RS232+enumerator+attoparsec
iterParseDeviceMsg :: Monad m => Enumeratee ByteString DeviceMsg m b iterParseDeviceMsg = sequence $ iterParser $ parseDeviceMsg
читает последовательность строк из источника, выдает на выходе последовательность DeviceMsg.
sequence взят из Data.Enumerator, где написано:
-- | Feeds outer input elements into the provided iteratee until it yields -- an inner input, passes that to the inner iteratee, and then loops. sequence :: Monad m => Iteratee ao m ai -> Enumeratee ao ai m b
Что характерно, я не очень понимаю, что я делаю, кроме того, что превратил Iteratee(сток для данных) в Enumeratee(фильтр-конвертор для потока данных).
В итоге использование выглядит таким образом:
processWeather1:: MonadIO m => SerialPort -> m () processWeather1 serial = do E.run_ $ enumSerial serial E.$= iterParseDeviceMsg E.$$ printObjI
Идея примерно в следующем: данные читаются из потока небольшими кусками и скармливаются парсеру, который выдает на выходе последовательность уже разобранных данных. И предположительно, это все должно работать в постоянной памяти.
Можно было бы сделать вообще влоб, но с Iteratees более мозгозасушивающе, заодно можно копипастить идеи из http://www.yesodweb.com
Сейчас вот еще к этой хрени нужно прикрутить rrdtool для складывания считанных значений в него и какой-нибудь сервис попроще, чтобы отдавать текущие показания датчиков.
no subject
no subject
Без примеров использования понять достаточно сложно.
no subject
кстати, тоже некоторое время не совсем понимал, что делал, а тупо, "в лоб", портировал на камло. Потом-то понял. Но понимание странное -- например, если объяснять sequence хоть сколько-нибудь подробнее, чем в комментарии к нему, то получится слишком много текста. Может быть, это потому, что сами идеи не слишком простые лежат под низом, или не слишком простая их комбинация.
no subject
no subject
no subject
no subject
no subject
no subject