Updater-0.1: Monadic FRP library based on stm

Safe HaskellNone





data Signal a Source

Signal is the portable Signal they can be exchanged between any parts of your program. Internally, they are just a variable and a list of change hooks.

newSignal :: Updater (a -> Updater (), Signal a) Source

Creates a new signal and gives you a way to update it. It is important to note that because the signal and the update function are separate, you can easily have readonly, writeonly permissions.

getValue :: Signal a -> Updater (Maybe a) Source

Gets the current value. Return Nothing if the signal is uninitialized.

Updater Monad

data Updater a Source

This monad works very similar to a continuation monad on top of stm. You can do any basic stm computation you want simply using liftSTM. However, if you use getEvent everything after that call will be executed everytime the Signal given to getEvent is changed.

You can also use the Alternative instance to make a union of events.

You can also use the Applicative instance to run two things 'parallel'. Parallel meaning that events on one side will not cause the other side to be reevaluated completely.

runUpdater :: Updater a -> IO a Source

This will evaluate the Updater Monad. It will block until the first run reaches the end. After that, it will return the result and free everything. To prevent signals from reaching the end use stop or getEvent with some exit signal.

getEvent :: Signal a -> Updater a Source

Runs everything below it everytime its input signal is updated.

onCommit :: IO () -> Updater () Source

IO actions given here will be executed once a signal update has been completed. They keep the order in which they are inserted.

onCleanup :: Updater () -> Updater () Source

doesn't really work yet


stop :: Updater a Source

Just a synonym for empty from Alternative. It basically prevents signals from ever progressing beyond this point. You can use this to make a filter for instance

when (condition) stop

getBehavior :: Signal a -> Updater a Source

Similar to getEvent except that it also fires an event immediately, if the input signal is already initialized. It can be created using getEvent and Alternative

local :: Updater a -> Updater () Source

Returns immediately after registering the given computation. However, events from inside will not spread outside, except for the initial one.

It is implemented like this

local computation = return () <|> (computation >> stop)

putLine :: String -> Updater () Source

Just for some quick debugging

putLine = onCommit . putStrLn