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

127 views Asked by At

Consider the following code:

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

The output from this program is:

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

Am I using valueB correctly? If not, what am I doing wrong? What is the purpose of valueB and when should I use it?

2

There are 2 answers

2
Heinrich Apfelmus On BEST ANSWER

It helps to keep in mind that the Moment (and MomentIO) monad expresses a computation that happens at a particular moment in time. The combinator valueB simply returns the value of the Behavior at that moment. In your case, that is at the very beginning.

If you want to sample the value of a Behavior at different times, you can use the <@> and <@ operators, which are very similar to <$> and <$. For instance, replacing the last line with

reactimate $ print <$> behavior <@ fireEvent

will print the value of the Behavior at each moment when the event fires.

A more advanced use would be to use valueB with execute.

0
Martin Kolinek On

According to documentation, valueB obtains the current value of a given behavior. It works in some MonadMoment. In this case this "moment" is the time the network is created. For this reason you always get the same value. You are asking for the value only once, at the beginning.

You can't directly react to changes in Behaviors since they don't really notify about their changes (they are continuous signals).

If you want to see valueB in action. I think the execute function is what you need.

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

This is of course a very contrived example, but it should do what you want.

Also, I don't have experience with ReactiveBanana specifically, but most of the FRP frameworks work similarly.