我在 Stack Overflow 上查看了许多问题的答案,试图找到解决我在使用 Reactive Banana 库时遇到的问题的方法。所有的答案都使用了一些我不太理解的“mapAccum”魔法。查看 API 文档,我发现“accumE
和 accumB
的有效组合”。这不是很有帮助。
看来这个函数可以用来比较 Behavior
的值在两个连续的事件时,这是我想做的。但我不清楚如何使这项工作。mapAccum
到底是怎么回事?工作?
最佳答案
请注意
mapAccum :: acc -> Event t (acc -> (x, acc)) -> (Event t x, Behavior t acc)
所以它需要一个初始值
:: acc
累积,以及产生一个函数的事件在生成输出值的同时更新累积值
::x
. (通常你会通过 <$>
部分应用一些功能来制作这样的事件。)结果,您将获得一个触发您的
x
的新事件。每当它们出现时的值和包含的行为您当前的累积值。
使用
mapAccum
如果你有一个事件并且你想做出一个相关的行为和事件。例如,在您的问题域中来自 your other question ,假设您有一个事件
eTime :: Event t Int
发射不规律,你想计算eDeltaTime :: Event t Int
对于差异和bTimeAgain :: Behaviour t Int
当前使用的时间:type Time = Int
type DeltaTime = Time
getDelta :: Time -> Time -> (DeltaTime,Time)
getDelta new old = (new-old,new)
我可以写
getDelta new = \old -> (new-old,new)
使下一步更清晰:deltaMaker :: Event t (Time -> (DeltaTime,Time))
deltaMaker = getDelta <$> eTime
(eDeltaT,bTimeAgain) = mapAccum 0 $ deltaMaker
在这种情况下,
bTimeAgain
将是与 eTime
中的事件具有相同值的行为.有时候是这样的因为我的
getDelta
函数通过new
从 eTime
直通不变到acc
值(value)。(如果我想要
bTimeAgain
自己,我会使用 stepper :: a -> Event t a -> Behaviour t a
。)如果我不需要
bTimeAgain
,我可以写(eDeltaT,_) = mapAccum 0 $ deltaMaker
.
关于haskell - Reactive Banana 的 mapAccum 函数是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12327424/