Ответ 1
(Автор reactive-banana.)
В целом, ваш код выглядит хорошо для меня. Я действительно не понимаю, почему вы используете реактивный банан в первую очередь, но у вас будут причины. Тем не менее, если вы ищете что-то вроде Node.js, помните, что haskell leightweight threads не нужно использовать для использования архитектуры, основанной на событиях.
Приложение. В принципе, функциональное реактивное программирование полезно, когда у вас есть множество различных входов, состояний и вывода, которые должны работать вместе с правильным временем (подумайте о графиках, анимации, аудио). Напротив, он переполняется, когда вы имеете дело со многими существенно независимыми событиями; они лучше всего обрабатываются обычными функциями и случайным состоянием.
Относительно индивидуальных вопросов:
"Я особенно приветствую любые комментарии относительно того, является ли это" хорошим "использованием accumE (я не понимаю, что эта функция будет обрабатывать весь поток событий каждый раз, хотя я предполагаю, что нет)".
Выглядит хорошо. Как вы уже догадались, функция accumE
действительно в режиме реального времени; он сохранит только текущее накопленное значение.
Судя по вашей догадке, вы, кажется, думаете, что всякий раз, когда приходит новое событие, он будет путешествовать по сети, как светлячок. Хотя это происходит внутри страны, вы не должны думать о функциональном реактивном программировании. Скорее, правильная картина такова: результат fromAddHandler
- это полный список входных событий по мере их возникновения. Другими словами, вы должны думать, что recvd
содержит упорядоченный список каждого события из будущего. (Конечно, в интересах вашего собственного здравомыслия, вы не должны пытаться смотреть на них до того, как их время наступит.;-)) Функция accumE
просто преобразует один список в другой, пройдя его один раз.
Мне нужно будет сделать этот способ мышления более ясным в документации.
"Также я хотел бы знать, как можно было бы тянуть сообщения из нескольких сокетов - в тот момент, когда я нахожусь в цикле событий внутри вечно. В качестве конкретного примера этого, как бы добавить второй сокет (REQ/REP в zeromq parlance), чтобы запросить текущее состояние внутреннего счетчика 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. (Не стесняйтесь задавать новый вопрос по этому вопросу, поскольку он выходит за рамки этого.)