metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2011-11-01 08:57 pm

Haskell, гротесковое

Енумераторы-итератии наконец заработали так, как я себе это представлял.
Ошибок было две:
Ключевая: надо было IO action лифтить внутрь iteratee и там всю работу и выполнять. А не внутри IO дергать енумератор с итератее-парсером и доставая результат:

неправильно, теряет куски буферов :
processWeather3 :: SerialPort -> IO () 
processWeather3 serial = loop
     where loop = do a <- E.run_ $ enumSerial serial E.$$ P.iterParseLine
                     BS.putStrLn a
                     loop

правильно:
iterWeather5 = loop
     where loop = do a <- P.iterParseLine
                     liftIO $ BS.putStrLn a
                     loop

processWeather5 :: SerialPort -> IO () 
processWeather5 serial = E.run_ $ enumSerial serial E.$$ iterWeather5

Вторая ошибка: в протоколе одного девайса после строки данных идет \r\n. в протоколе другого только \r. Строки разделены пустыми строками как бог на душу положит.
Я пишу парсер на attoparsec таким образом:
do skipWhile isSpace_w8 --пропускаем whitespace 
   data <- ReadData     --читаем строку данных
   skipWhile isSpace_w8 --пропускаем whitespace (т.е. - перенос строки)
   return data
Так вот, skipWhile, что характерно - будет ждать данных пока не придет хоть что-нибудь, отличающееся от предиката. Если девайс не гонит данные непрерывным потоком - то это повисает до истечения таймаута.
Таймауты, впрочем, вообще не обрабатываются - пакет serialport на них возвращает пустые строки. Дойдут руки - буду разбираться как это исправлять, кроссплатформенным образом.
И да, я вспомнил, зачем же я это все делал: меня задрало не иметь под руками прототипа софта, который можно единообразно запустить как винде, так и на линуксе и который бы работал с висящими на ком-порту девайсами согласно разнообразных от фонаря придуманных протоколов.

[identity profile] skif-by.livejournal.com 2011-11-02 06:11 am (UTC)(link)
Что характерно, все численные модели прогноза погоды до сих пор на fortran :) Ну с некоторой обвязкой на цэ, максимум.