我正在玩 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 还是新手,所以我可能从根本上误解了一些重要的事情(可能是这样。)