(Автор реактивный-банан говорит.)
В целом, ваш код выглядит хорошо для меня.На самом деле я не понимаю, почему вы используете реактивный банан, но у вас будут свои причины.Тем не менее, если вы ищете что-то вроде Node.js, помните, что легковесные потоки Haskell лишают необходимости использовать архитектуру, основанную на событиях.
Добавление: По сути, функциональное реактивное программированиеполезно, когда у вас есть множество различных входов, состояний и выходов, которые должны работать вместе с правильным выбором времени (например, GUI, анимация, аудио).Напротив, это излишне, когда вы имеете дело со многими по существу независимыми событиями;лучше всего с ними справляются обычные функции и случайное состояние.
Относительно отдельных вопросов:
«Я особенно приветствую любые комментарии относительно того, является ли это« хорошим »«Использование аккумулятора, (я не уверен, что эта функция будет проходить весь поток событий каждый раз, хотя я предполагаю, что нет).»
Выглядит хорошо для меня.Как вы уже догадались, функция accumE
действительно работает в реальном времени;он будет хранить только текущее накопленное значение.
Судя по вашему предположению, вы, похоже, думаете, что всякий раз, когда приходит новое событие, оно будет проходить через сеть, как светлячок.Хотя это происходит внутри, это не , как вы должны думать о функционально-реактивном программировании.Скорее, правильная картина такова: результатом fromAddHandler
является полный список входных событий , поскольку они будут происходить .Другими словами, вы должны думать, что recvd
содержит упорядоченный список каждого события в будущем.(Конечно, в интересах вашего собственного здравомыслия, вы не должны пытаться смотреть на них до того, как наступит их время. ;-)) Функция accumE
просто преобразовывает один список в другой, проходя его один раз.
Мне нужно будет прояснить этот способ мышления в документации.
"Также мне хотелось бы знать, как можно было бы извлекать сообщения из нескольких сокетов - на данный моментУ меня есть цикл обработки событий внутри навсегда. Как конкретный пример этого, как бы я добавить второй сокет (пара REQ / REP на языке zeromq) для запроса к текущему состоянию внутреннего счетчика IdMap? "
Если функция receive
не блокируется, вы можете просто вызвать ее дважды на разных сокетах
linkSocketHandler s1 s2 runner1 runner2 = forever $ do
receive s1 [] >>= runner1 . fromString . C.unpack
receive s2 [] >>= runner2 . fromString . C.unpack
Если она блокирует, вам нужно будет использовать потоки, см. Также раздел Обработка нескольких потоков TCP в книге Real World Haskell.(Не стесняйтесь задавать новый вопрос по этому вопросу, поскольку он выходит за рамки этого.)