← All posts tagged code

Вот кстати по стеку вопрос. Когда фиксил тесты для fast-logger-а увидел забавную штуку.
Запускаю stack test . И для wai-logger он выдаёт замечательные ошибки про System.Posix . Выясняется что в cabal файле. используется.
if os(windows)
   Cpp-Options: -DWINDOWS

И почему-то при сборке тестов этот флаг либы не учитывается, добавление этого флага тестам ничего не даёт. 

А сами тесты сделаны с помощью doctest:
-- $setup
-- >>> :set -XOverloadedStrings
-- >>> import Network.Wai.Test

он ругается что нет такого модуля. Добавление его в зависимости stack и cabal ничего не даёт.

Собственно у меня 2 вопроса:
1. Фиксится встроенным в GHC mingw32_HOST_OS , но как всё таки stack заставить нормально обрабатывать Cpp-Options.
2. Полагаю что дело в путях, но всё равно какая-то хуйня.

Есть такой тип данных:
data Result = COk | CFail String

Т.е. что-то вроде Maybe но наоборот. И вот приходится мне комбинировать эти Result в стиле bind (>>=) .
Норот, может есть где-то готовый тип с инстансом Monad ?

Господа есть проблема с настройкой vpn-а. Есть сеть на роутере(debian-wheezy)(192.168.1.5) этой сети не поднимается openvpn тунель, а на компе который внутри сети понимается (192.168.1.3).
На роутере 4 интерфейса eth0, eth1, wlan0, br0.  eth0 и wlan0 объединены в br0, на него раздаётся dhcp. NAT делается одной коммандой. /sbin/iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE .
Внятной ошибки openvpn на 192.168.1.5 не пишет:
Mon Apr 20 22:25:42 2015 TCPv4_CLIENT link remote: [AF_INET]176.126.237.214:443
Mon Apr 20 22:25:42 2015 Connection reset, restarting [0]
Mon Apr 20 22:25:42 2015 SIGUSR1[soft,connection-reset] received, process restarting

Собственно вопрос куда копать?

Как-то так:
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 4 changes to 4 files
remote: 
remote:      .-. .-.
remote:     (   |   )
remote:   .-.:  |  ;,-.
remote:  (_ __`.|.'__ _)
remote:  (    .'|`.    )
remote:   `-'/  |  \`-'
remote:     (   !   )
remote:      `-' `-'\
remote:              \
remote:               )
remote: 
remote: Happy St. Patrick's Day!

Хочется все ошибки в процессе разбора документа собрать, а уже потом их выводить. По идее этот код должен подобное делать:
runX (errorMsgCollect >>> xunpickleDocument xpickle [] "foo.xml" >>> getErrorMessages)
но, сука, не делает. Я вот думаю толи я стрелки не так использую, толи вторы библиотеки...

Захотелось мне объединить 2 монадных транформера в один. В итоге я не могу написать дефолтную реализацию для MonadTransControl, которая нужна для MonadBaseControl.  Точнее я не могу нормально вписать тип в ^1 . По примеру из https://hackage.haskell.org/package/monad-control-0.3.3.0/docs/Control-Monad-Trans-Control.html#g:2

data WebAppState = WebAppState { _configChangeMutex :: MVar ()
                               , _plumbingState :: PlumbingState }
makeLenses ''WebAppState

newtype HandlerT m a = HandlerT { unHandlerT :: ReaderT WebAppState (LoggingT m) a}
    deriving (Monad, MonadReader WebAppState, Applicative, Functor, MonadLogger, MonadBase b )

instance MonadTrans HandlerT where lift = HandlerT . lift . lift

instance MonadTransControl HandlerT where
     newtype StT HandlerT a = StHandler {unStHandler :: StT (ReaderT WebAppState (LoggingT m)) a} -- ^1
     liftWith = defaultLiftWith HandlerT unHandlerT StHandler
     restoreT = defaultRestoreT HandlerT unStHandler

instance MonadBaseControl b m => MonadBaseControl b (HandlerT m) where
    newtype StM (HandlerT m) a = StMHandlerT {unStMHandlerT :: ComposeSt HandlerT m a}
    liftBaseWith = defaultLiftBaseWith StMHandlerT
    restoreM     = defaultRestoreM   unStMHandlerT

Собственно вопрос: как это сделать?

Есть у меня необходимость принимать по UDP пакеты. Выглядит сейчас это - так:
CNU.sourceSocket sock 4096  $= CL.map CNU.msgData
                                    =$= conduitDecode 
                                    =$= CL.map (uncurry EMessage)
                                    $$  CRQ.sinkRollingQueue  q

Принимается пакет, потом десериализуется, а затем суётся в очередь.
Собственно, если данные превышают размер пакета они собираются из нескольких пакетов при этом sender из UDP-шного пакета игнорируется. Тут остаётся актуальным вопрос переупорядочивания UDP-ишных пакетов, т.е. если я засуну в сокет больше 4096 с одной стороны, то на приёмнике могу получить что-то вклинившееся между этими 2-мя пакетами или это просто влияет на размер буфера? 
Сейчас появилась необходимость скомбинировать адресс/порт отправителя  с десериализованным сообщением, учитывая что сообщение может быть разбито на несколько пакетов... Хочется для этого како-то zipConduit использовать, но что-то не очень понимаю как. Собственно помогите с примером.

Вопрос будет тупой. Есть у меня тип Event

data Event = EEv1 {host :: String, node :: String}
                       | EEv2 {host :: String, node :: String}
                       | EEv3 {fromHost :: String, toHost:: String, node :: String}

Собственно вопрос: многие поля одинаковые. Может есть какие-то более правильные способы такое делать?

Например у меня есть некий кондуит, который получает по UDP пакеты, преобразует их в нужный мне ADT и пихает в очередь. Выглядит запуск примерно так:

void $ forkIO $ sourceSocket sock 4096 =$= ... =$= sinkRollingQueue

И вот пришло нам битое сообщение из-за него вылетает эксепшн, но я не хочу прибивать весь процесс к чертям из-за такой мелочи. Собственно первое что приходит на ум — это отловить эксепшн с пом onException, вывести в лог сообщение об ошибке и снова запустить кондуит, как-то так:

getMsg =  sourceSocket sock 4096 =$= ... =$= sinkRollingQueue

void $ forkIO $ getMsg `onException` (\e -> print e >> getMsg) 

Собственно вопрос - это обычно так и делается или я что-то упускаю?

есть функция вида
foo :: Int -> Int -> m (bool)
в другой монадической функции (монада та же)
bar :: Int -> m (Maybe bool)
bar p2 = do
    (p1::(Maybe Int)) <- getInt
    case p1 of
        (Just p1') -> fmap Just $ foo p1' p2
        Nothing   -> return Nothing

И тут я вижу что case можно по идее заменить на что-то вроде fmap, но туплю и никак не могу понять что я не так делаю.

Забавный прикол 
Этот хендлер отправляет приложение в SegFault

getFileMetaR  fileId = do
    File {..} <- runDB $ get404 fileId
    returnJson $ object ["id" .= fileId, "mime-type" .= fileMimetype, "ttl" .= fileTtl]

а этот нет
getFileMetaR  fileId = do
    File {..} <- fromJust404 $ runDB $ get fileId
    returnJson $ object ["id" .= fileId, "mime-type" .= fileMimetype, "ttl" .= fileTtl]

Где 
fromJust404 ::MonadHandler m => m (Maybe a) -> m a
fromJust404 l = l >>= maybe notFound return

а get404 http://hackage.haskell.org/packages/archive/yesod-persistent/1.2.0/doc/html/src/Yesod-Persist.html#get404

Что-то я посмотрел на http://www.haskell.org/haskellwiki/Failure и как-то не совсем понял как получится такое:
Consider a program to download a web page and parse it:

1. Network.URI.parseURI returns (Maybe URI).
2. Network.HTTP.simpleHTTP returns (IO (Result Request)), which is basically a broken version of (IO (Either ConnError Request)).
3. Parsec returns (Either ParseError a)

So there's no hope that I can write anything like:

  do uri <- parseURI uriStr
     doc <- evenSimplerHTTP uri
     parsed <- parse grammar uriStr doc

Там же всё равно какие-то fromJust или fromEither придётся использовать.

Есть некая функция поведение, которой может изменяться булевым флагом. Флаг этот выставляется исключительно в компаил тайм. Собственно хочется сделать так, чтоб в рантайме этой проверки не было. Придумалось 2 варианта:
void* foo<bool b>(void* )
{
//...
if(b) do();
//...
}

и 2й со специализацией do для случая true (функция) и false (пустая функция)

Так вот, второй вариант точно не будет содержать условного перехода в сгенерённом компилером выводе, но он более сложный и раздрыстаный; первый же проще но не известно в общем случае соптимизирует ли компилятор в константу.
Может кто знает как такая оптимизация называется правильно на ангельском или выполняется ли она gcc/MSVC?

вот есть у меня необходимость брать timestamp и преобразовывать его в ByteString 

Вот код:

import qualified Data.ByteString.Char8 as C 

ts <- liftIO $ (C.pack . show . fst . properFraction) <$> getPOSIXTime

Есть один неприятный ворнинг, его причину я понимаю. Знаю как побороть с промежуточным let и заданием типа, можно это как-то сделать без промежуточного let?
 
Handler/AsipApi.hs|37 col 43 warning| Defaulting the following constraint(s) to type `Integer'
||            (Integral b0)
||              arising from a use of `properFraction'
||              at /home/yuriy-shelyag/sandboxes/axxoncloud/Handler/AsipApi.hs:37:43-56
||            (Show b0)
||              arising from a use of `show'
||              at /home/yuriy-shelyag/sandboxes/axxoncloud/Handler/AsipApi.hs:37:30-33

Пока писал пришла идея:

ts <- liftIO $ (C.pack . show . (fst :: (Int,a) ->Int). properFraction ) <$> getPOSIXTime

Есть ли способ красивее?

Вот нужна мне функция [Text] -> Bool
Хочется что-то вроде такого:
isRequestRedirected pieces | ["live":"media":_] <- pieces = True
                           | ["archive":"media":"rendered-info":_] <- pieces = False
                           | ["archive":"media":_] <- pieces = True
                           | otherwise = False

Т.е. понятно что тут можно это все склеить и обойтись isPrefixOf, однако интересны и другие варианты.

Жуйк, есть вопрос:
вот есть некая функция что возвращает завернутое в монаду Maybe a . Я уверен, что там всегда Just a. Как наиболее красиво убрать этот Maybe? Мне ничего лучше 
do
    mUID <- liftM fromJust getUserId 
    ...

Господа, а можно как-то на POSIX make изобразить такую конструкцию:

dir/%.o:
   cd dir && make %*.o

Т.е. часть *.c файлов для собрки лежит в поддиректории и для того чтоб их сбилдить надо вызвать make foo.o в этой поддиректории. На GNU make я это изобразил, а вот на POSIX как-то херово :(

Я вот что-то никак не вкурю как мне из UTF8 получить на выходе String читаемо выводимый. Просто Text.XML.Light ByteString с utf-8, а когда выводишь значение атрибута плюётся кодами вместо кирилицы.
Как это победить?

Prelude Codec.Binary.UTF8.String> encodeString "херня"
"\209\133\208\181\209\128\208\189\209\143"
Prelude Codec.Binary.UTF8.String> decodeString $ encodeString "херня"
"\1093\1077\1088\1085\1103"

typedef std::map<int,int> Map;
std::mem_fun_t<void,Map> f = std::mem_fun(&Map::clear); //не собирается - пишет не может инициялизировать
//...
std::mem_fun_t<void,Map> f = std::mem_fun<void,Map>(&Map::clear); //собирается

А не собирается он, потому что компилятор выводит тип не std::map <..> , а базовый для него std::_Tree . Ахуеть.
Проблема итак без костылей не решалась, теперь костыли еще и кривые