`valueB` 是如何工作的?它总是 returns 相同的值?

How does `valueB` work? It always returns the same value?

考虑以下代码:

module Main where

import Control.Event.Handler
import Reactive.Banana
import Reactive.Banana.Frameworks

main :: IO ()
main = do
  (addHandler, fire) <- newAddHandler
  compile (network addHandler) >>= actuate
  fire "fire one"
  fire "fire two"

network :: AddHandler String -> MomentIO ()
network addHandler = do
  fireEvent <- fromAddHandler addHandler
  behavior <- stepper "initial stepper value" fireEvent
  behaviorValue <- valueB behavior
  reactimate $ putStrLn . (\v -> "fire input: " ++ show v) <$> fireEvent
  reactimate $ print behaviorValue <$ fireEvent

这个程序的输出是:

fire input: "fire one"
"initial stepper value"
fire input: "fire two"
"initial stepper value"

我使用 valueB 正确吗?如果不是,我做错了什么? valueB 的用途是什么?我应该在什么时候使用它?

根据文档,valueB 获取给定行为的当前值。它在某些 MonadMoment 中有效。在这种情况下,此 "moment" 是创建网络的时间。出于这个原因,你总是得到相同的价值。您只在开始时要求一次价值。

您不能直接对行为的变化做出反应,因为它们并没有真正通知它们的变化(它们是连续的信号)。

如果您想查看 valueB 的实际效果。我认为 execute 功能是您所需要的。

execute (valueB <$> stepper "initial stepper value" fireEvent)

这当然是一个非常人为的例子,但它应该做你想做的。

此外,我没有专门使用 ReactiveBanana 的经验,但大多数 FRP 框架的工作方式相似。

记住 Moment(和 MomentIO)monad 表示在特定时刻发生的计算会有所帮助。组合器 valueB 只是 returns 那个时刻行为的值。在你的情况下,那是在最开始。

如果想在不同的时间对一个Behavior的值进行采样,可以使用<@><@运算符,和<$>和[=17非常相似=].例如,将最后一行替换为

reactimate $ print <$> behavior <@ fireEvent

将在事件触发的每个时刻打印行为的值。

更高级的用法是将 valueBexecute 一起使用。