`valueB`如何运作?它总是返回相同的值?

时间:2016-06-19 00:20:45

标签: haskell reactive-programming frp reactive-banana

请考虑以下代码:

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的目的是什么?我何时应该使用它?

2 个答案:

答案 0 :(得分:2)

有助于记住Moment(和MomentIO)monad表示在特定时刻发生的计算。组合器valueB只返回当时行为的值。在你的情况下,这是在一开始。

如果您想在不同时间对行为的值进行抽样,可以使用与<@><@非常相似的<$><$运算符。例如,用

替换最后一行
reactimate $ print <$> behavior <@ fireEvent

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

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

答案 1 :(得分:1)

根据文档,valueB获取给定行为的当前值。它适用于某些MonadMoment。在这种情况下,这个“时刻”是网络创建的时间。因此,您始终可以获得相同的值。您只需要在开始时询问一次该值。

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

如果您想查看valueB的实际操作。我认为execute函数就是您所需要的。

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

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

另外,我没有专门针对ReactiveBanana的经验,但大多数FRP框架的工作方式都相似。