Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reactive Banana: State monad or not?

I have an interface (WX) which is based on Reactive Banana. Now I have different questions about how to really manage the status:

  1. Should I consider the state as the Behaviors that I define in the code?

  2. If the state depends on external "events" too, not only related to the GUI would be better considering IORef?

  3. Or Can I use State Monad? All the examples I saw till now define the network in IO environment. Have any sense stack State Monad and how? With Moment?

like image 875
Randomize Avatar asked Sep 01 '15 16:09

Randomize


1 Answers

Should I consider the state as the Behaviors that I define in the code?

For most scenarios you will indeed want to use Behaviors for state. In a GUI application you will often want to update your state in response to interface events. In addition, and crucially, the state must remain existing between occurrences of the events, and State doesn't allow that. More specifically, the standard way to react to an event occurrence doing something other than updating a Behavior is through the reactimate function:

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

The action to be performed is of type IO (). While it is possible to use runStateT to run a StateT s IO computation using reactimate, the computation will be self-contained, and you won't have the state it used available to be passed elsewhere. This problem does not arise when using Events to update Behaviors through the reactive-banana FRP interface: the Behaviors remain there until you need to use them again.

If the state depends on external "events" too, not only related to the GUI would be better considering IORef?

Not necessarily. In many cases you can use the tools in Reactive.Banana.Frameworks such as fromAddHandler and newEvent to create Events that are fired when external I/O actions happen. That way you can integrate such actions to your event network. One typical example would be a timer: reactive-banana has no built-in notion of time, but you can introduce a tick event that is fired through an I/O action that happens at regular intervals.

That said, in some cases you might still want to use...

  • ... IORefs (or other sorts of mutable variables, such as MVars), if you have to use a library with an interface that, for whatever reason, restricts your ability to freely react to events using Behaviors and reactimate. A while ago there was a very nice question about such a scenario involving hArduino. The two answers there show different, yet similar in spirit, ways to have an useful event network in unfavourable circumstances.

  • ... StateT if you have some stateful algorithm that is self-contained and whose results won't be used elsewhere in your event network, so that you can run it with runStateT and stick it in a reactimate call. Silly example: an IO () action in reactimate along these lines:

    displayMessageBox . show =<< evalStateT someStateComputation initialState
    
like image 71
duplode Avatar answered Nov 11 '22 00:11

duplode