2

I'm looking for the function in reactive-banana that will choose from which event stream to emit next depending on the incoming value of another event stream or signal (Behaviour ?). In the library for scala, reactive-web this is done with:

 flatMap[U](f: T => EventStream[U]): EventStream[U] 

thanks !

miguel.negrao
  • 949
  • 5
  • 13

2 Answers2

5

This is dynamic event switching. Unfortunately, in that formulation, it has many problems, and so is not included in reactive-banana. However, a variant of dynamic event switching will be added soon. For now, you'll have to do without it.

In particular, flatMap is Scala's name for the monadic bind function; a Monad instance for behaviours is problematic because it provides the dynamic event switching functionality that leads to the time leak explained in the article I linked.

ehird
  • 40,602
  • 3
  • 180
  • 182
  • Thanks for the links, I think is exactly what I needed. I will read them carefully. – miguel.negrao Apr 07 '12 at 11:47
  • Btw, although EventSource has a bind method it does not have a pure method, so it can't be a Monad or even an Applicative. Signal, on the other hand has a pure function so it could be Monad and Applicative, but I never checked if it complies with the properties of Monad. In reactive-banana Behavior is not a Monad, I wonder what is missing. – miguel.negrao Apr 07 '12 at 12:22
  • 2
    Well, nothing's missing, as such; it's deliberately omitted because it causes time leaks and is semantically problematic; it has the "wrong type" in a sense (the right type is given in the second post I linked to). – ehird Apr 07 '12 at 12:30
2

As an addendum to ehird's answer, I want to mention that it's often possible to avoid dynamic event switching, namely when the relevant behaviors/events are in scope at compile-time. Dynamic event switching is only needed when you compute a new behavior/event on the fly, not when you switch between behaviors/events that are already in scope.

In particular, have a look at the TwoCounters.hs example on the examples page to see how this can be done.

Heinrich Apfelmus
  • 11,034
  • 1
  • 39
  • 67
  • In the TwoCounters.hs example both counters are updated whenever the buttons up or down are pressed, it's just that the value of one of the counters will not change. I can think of many situations where this is not wanted, since emitting something could be the visible effect in itself (i.e. play a musical note). Would there be a way to change this example such that only one of the counters receives a new event when you press the up or down buttons ? – miguel.negrao Apr 08 '12 at 11:03
  • Note that the semantics of `Behavior` is different from what you expect. It does not come with any notion of "this value was updated". (There is the `changes` function, but it's only an approximation.) You have to use an `Event` if you care about "emitting" values, like playing a musical note. In the case of the counter, you can filter out the button presses from the inactive counters after they were changed. – Heinrich Apfelmus Apr 09 '12 at 07:23