haskell - Reactive Banana 的 mapAccum 函数是如何工作的?

标签 haskell reactive-banana

我在 Stack Overflow 上查看了许多问题的答案,试图找到解决我在使用 Reactive Banana 库时遇到的问题的方法。所有的答案都使用了一些我不太理解的“mapAccum”魔法。查看 API 文档,我发现“accumEaccumB 的有效组合”。这不是很有帮助。

看来这个函数可以用来比较 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函数通过neweTime 直通不变到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/

相关文章:

haskell - 实践中的错误catchError

haskell - 为什么 cabal 不能保留同一个包的多个版本?

多线程和 gtk2hs

haskell - 使用 Reactive Banana 做一些基本的微积分

haskell - 安装reactive-banana-wx

delphi - 如何在 Parsec 中定义多种类型的注释 block

haskell - 使用模板 Haskell 时键入同义词 "not in scope"

haskell - 如何在 Haskell 中将函数映射到向量的特定范围

haskell - 是否可以? : Behavior t [Behavior t a] -> Behavior t [a]