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

  • 是否应将状态视为代码中定义的Behavior
  • 如果状态也依赖于外部“事件”,那么考虑IORef不仅与GUI相关会更好吗?
  • 还是可以使用State Monad?到目前为止,我看到的所有示例都在IO环境中定义了网络。有任何意义的堆栈State Monad以及如何?用Moment吗?
  • 最佳答案



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

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

    要执行的操作的类型为IO ()。尽管可以使用runStateT通过StateT s IO运行reactimate计算,但是该计算将是独立的,并且您将无法获得将其用于其他地方的状态。当使用Event s通过 react 性香蕉FRP接口(interface)更新Behavior时,不会出现此问题:Behavior保留在那里,直到您需要再次使用它们为止。



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

    也就是说,在某些情况下,您可能仍要使用...
  • ... MVar s(或其他类型的可变变量,例如Behavior s),如果您必须使用带有接口(interface)的库,无论出于何种原因,该接口(interface)都会限制您使用reactimatehArduino自由响应事件的能力。前一段时间有a very nice question about such a scenario involving StateT 。那里的两个答案显示了在不利情况下拥有有用的事件网络的不同但又相似的方式。
  • ... runStateT,如果您有一些独立的有状态算法,并且其结果不会在事件网络的其他地方使用,那么您可以使用reactimate运行它并将其粘贴在IO ()调用中。愚蠢的例子:在reactimate中的ojit_code Action 如下:
    displayMessageBox . show =<< evalStateT someStateComputation initialState
    
  • 关于haskell - 活性香蕉: State monad or not?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32336189/

    10-08 22:58