我正在尝试使用 netwire 包尝试了解 FRP,我有一个简单的问题。
从以下简单的电线开始,我能够每 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 的新手,所以我可能从根本上误解了它的一些重要内容(可能是这种情况。)