Я играю с пакетом netwire, пытаясь почувствовать FRP, и у меня есть быстрый вопрос.Haskell Netwire: провода проводов
Начиная со следующими простыми проводами, я могу испускать событие каждые 5 секунд (приблизительно)
myWire :: (Monad m, HasTime t s) => Wire s() m a Float
myWire = timeF
myWire' :: (Monad m, HasTime t s) => Wire s() m a Int
myWire' = fmap round myWire
myEvent :: (Monad m, HasTime t s) => Wire s() m a (Event Int)
myEvent = periodic 5 . myWire'
Это очень красиво и прямо вперед, но то, что я хочу делать дальше сопоставьте каждый событие, произведенное на проводе, после чего я могу посмотреть обновление. У меня есть агрегатная функция, как следующее:
eventList :: (Monad m, HasTime t s)
=> Wire s() m a (Event [Wire s() m a Int])
eventList = accumE go [] . myEvent
where go soFar x = f x : soFar
f x = for 10 . pure x --> pure 0
Я тогда ввести новый провод, который будет тормозить, пока eventList
начинается не запуская события, например так:
myList :: (Monad m, HasTime t s) => Wire s() m a [Wire s() m a Int]
myList = asSoonAs . eventList
Так я пошел от событий провод, содержащий список проводов. Наконец, я ввожу провод к шагу каждый из этих проводов и составить список результатов:
myNums :: (Monad m, HasTime t s) => Wire s() m [Wire s() m a Int] [Int]
myNums = mkGen $ \dt wires -> do
stepped <- mapM (\w -> stepWire w dt $ Right undefined) wires
let alive = [ (r, w) | (Right r, w) <- stepped ]
return (Right (map fst alive), myNums)
myNumList :: (Monad m, HasTime t s) => Wire s() m a [Int]
myNumList = myNums . myList
И, наконец, у меня основная программа, чтобы проверить все это:
main = testWire clockSession_ myNumList
Что ожидать чтобы увидеть это растущий список, где каждый элемент в списке покажет время его создания в течение 10 секунд, после чего элемент покажет нуль. Вместо этого я получаю растущий список статических значений. Например, то, что я ожидаю увидеть после нескольких этапов, -
[0]
[5, 0]
[10, 5, 0]
[15, 10, 0, 0]
и так далее. То, что я на самом деле вижу, это
[0]
[5, 0]
[10, 5, 0]
[15, 10, 5, 0]
Итак, я знаю, что моя функция аккумулятора работает: каждое созданное событие преобразуется в провод. Но я не вижу, что эти провода излучают разные значения с течением времени. Мое заявление for 10 . pure x --> pure 0
должно переключать их на излучение 0 по истечении времени.
Я еще новичок в FRP, так что я может быть в корне недоразумения что-то важное об этом (вероятно, так.)
Я не думаю, что это возможно с netwire или любой из других современных библиотек FRP. Эти библиотеки прилагают совместные усилия, чтобы избежать утечки времени и пространства, избегая предоставления экземпляра «Монады» или чего-либо подобного. Это означает, что вообще невозможно включить «Wire ... (Wire ... a)» в «Wire a». – Cirdec