reactive-banana- Small but solid library for functional reactive programming (FRP).





Build event networks using existing event-based frameworks and run them.


data PushIO Source

The type index PushIO represents the efficient push-driven implementation described here. It implements the same FRP interface as the model implementation represented by Model.

interpret :: Typeable a => (Event PushIO a -> Event PushIO b) -> [a] -> IO [[b]]Source

Simple way to run an event graph. Very useful for testing.

Building event networks with input and output

After having read all about Events and Behaviors, you want to hook them up to an existing event-based framework, like wxHaskell or Gtk2Hs. How do you do that?

This Reactive.Banana.Implementation module allows you to obtain input events from external sources and it allows you perform output in reaction to events.

In constrast, the functions from Reactive.Banana.Model allow you to express the output events in terms of the input events. This expression is called an event graph.

An event network is an event graph together with inputs and outputs. To build an event network, describe the inputs, outputs and event graph in the NetworkDescription monad and use the compile function to obtain an event network from that.

To run an event network, use the run function. The network will register its input event handlers and start producing output.

A typical setup looks like this:

 main = do
   -- initialize your GUI framework
   window <- newWindow

   -- build the event network
   network <- compile $ do
       -- input: obtain  Event  from functions that register event handlers
       emouse    <- fromAddHandler (registerMouseEvent window)
       ekeyboard <- fromAddHandler (registerKeyEvent window)
       -- express event graph
           behavior1 = accumB ...
           event15 = union event13 event14
       -- output: animate some event occurences
       reactimate $ fmap print event15
       reactimate $ fmap drawCircle eventCircle

   -- register handlers and start producing outputs
   run network

In short, you use fromAddHandler to obtain input events. The library uses this to register event handlers with your event-based framework.

To animate output events, use the reactimate function.

data NetworkDescription a Source

Monad for describing event networks.

The NetworkDescription monad is an instance of MonadIO, so IO is allowed inside.

Note: It is forbidden to smuggle values of types Event or Behavior outside the NetworkDescription monad. This shouldn't be possible by default, but you might get clever and use IORef to circumvent this. Don't do that, it won't work and also has a 99,98% chance of destroying the earth by summoning time-traveling zygohistomorphisms.

compile :: NetworkDescription () -> IO EventNetworkSource

Compile a NetworkDescription into an EventNetwork that you can run, pause and so on.

type AddHandler a = (a -> IO ()) -> IO (IO ())Source

A value of type AddHandler a is just a facility for registering callback functions, also known as event handlers.

The type is a bit mysterious, it works like this:

 do unregisterMyHandler <- addHandler myHandler

The argument is an event handler that will be registered. The return value is an action that unregisters this very event handler again.

fromAddHandler :: Typeable a => AddHandler a -> NetworkDescription (Event PushIO a)Source

Input, obtain an Event from an AddHandler.

When the event network is run, this will register a callback function such that an event will occur whenever the callback function is called.

reactimate :: Event PushIO (IO ()) -> NetworkDescription ()Source

Output. Execute the IO action whenever the event occurs.

liftIO :: MonadIO m => forall a. IO a -> m a

Lift a computation from the IO monad.

Running event networks

data EventNetwork Source

Data type that represents a compiled event network. It may be paused or already running.

run :: EventNetwork -> IO ()Source

Run an event network. The inputs will register their event handlers, so that the networks starts to produce outputs in response to input events.

pause :: EventNetwork -> IO ()Source

Pause an event network. Immediately stop producing output and unregister all event handlers for inputs. Hence, the network stops responding to input events, but it's state will be preserved.

You can resume the network with run.

Note: You can stop a network even while it is processing events, i.e. you can use pause as an argument to reactimate. The network will not stop immediately though, only after the current event has been processed completely.


newAddHandler :: IO (AddHandler a, a -> IO ())Source

Build a facility to register and unregister event handlers.

This function is only useful if you want to hook up this library to a poorly designed event-based framework, or roll your own.