haskell - react 香蕉 : State monad or not?

标签 haskell reactive-banana

我有一个基于 Reactive Banana 的界面 (WX)。 现在我对如何真正管理状态有不同的问题:

  1. 我应该将状态视为我在代码中定义的行为吗?

  2. 如果状态也依赖于外部“事件”,那么不仅仅与 GUI 相关,考虑 IORef 会更好吗?

  3. 或者我可以使用 State Monad 吗?到目前为止我看到的所有例子都是在 IO 环境中定义网络的。对堆栈 State Monad 有任何意义吗?与时刻

最佳答案

Should I consider the state as the Behaviors that I define in the code?

对于大多数场景,您确实需要使用Behavior 来表示状态。在 GUI 应用程序中,您经常需要更新状态以响应界面事件。此外,最重要的是,状态必须在事件发生之间保持存在,而 State 不允许这样做。更具体地说,对事件发生使用react而不是更新 Behavior 的标准方法是通过 reactimate 函数:

reactimate :: Frameworks t => Event t (IO ()) -> Moment t ()

要执行的操作的类型为IO ()。虽然可以使用 runStateT 来使用 reactimate 运行 StateT s IO 计算,但该计算将是独立的,并且您不会它所使用的状态不能传递到其他地方。当使用Event通过reactive-banana FRP接口(interface)更新Behavior时,不会出现这个问题:Behavior会保留在那里,直到您需要为止再次使用它们。

If the state depends on external "events" too, not only related to the GUI would be better considering IORef?

不一定。在许多情况下,您可以使用 Reactive.Banana.Frameworks 中的工具。例如 fromAddHandlernewEvent 来创建在外部 I/O 操作发生时触发的 Event。这样您就可以将此类操作集成到您的事件网络中。一个典型的例子是 a timer :reactive-banana 没有内置的时间概念,但您可以引入通过定期发生的 I/O 操作触发的刻度事件。

也就是说,在某些情况下您可能仍然想使用...

  • ... IORef(或其他类型的可变变量,例如 MVar),如果您必须使用具有以下接口(interface)的库:无论出于何种原因,都会限制您使用行为和重新响应来自由响应事件的能力。前段时间有a very nice question about such a scenario involving hArduino 。这两个答案展示了在不利情况下建立有用的事件网络的不同但本质上相似的方法。

  • ... StateT 如果您有一些独立的有状态算法,并且其结果不会在事件网络中的其他地方使用,以便您可以使用 runStateT 并将其放入 reactimate 调用中。愚蠢的示例:reactimate 中的 IO () 操作如下:

    displayMessageBox . show =<< evalStateT someStateComputation initialState
    

关于haskell - react 香蕉 : State monad or not?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32336189/

相关文章:

haskell - FRP - 事件流和信号 - 仅使用信号会丢失什么?

haskell - 在重新启动内执行 MonadIO 操作

Haskell:从具有一百万个值的列表构建 IntMap 时,我应该得到 "Stack space overflow"吗?

haskell - 如何重载haskell中的幂函数(^)?

haskell - 遍历多态结构并仅在少数情况下执行转换

haskell - 将 monad 限制为类型类

haskell - 如何在reactive-banana中使行为包含其他行为

haskell - FRP框架和IO

haskell - "dummies", IO+Maybe 的最简单的非平凡 monad 转换器示例