Safe Haskell | None |
---|---|
Language | Haskell98 |
- data Signal a
- newSignal :: a -> Updater (Signal a)
- newSignalIO :: a -> IO (Signal a)
- writeSignal :: Signal a -> a -> Updater ()
- readSignal :: Signal a -> Updater a
- data Updater a
- runUpdater :: Updater a -> IO a
- getEvent :: Signal a -> Updater a
- onCommit :: IO () -> Updater ()
- onCleanup :: Updater () -> Updater ()
- stop :: Updater a
- modifySignal :: Signal a -> (a -> a) -> Updater ()
- getBehavior :: Signal a -> Updater a
- local :: Updater a -> Updater ()
- liftSTM :: STM a -> Updater a
- putLine :: String -> Updater ()
- runGlobalUpdater :: Updater a -> IO ()
Signals
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 :: a -> Updater (Signal a) Source
Creates a new signal. You can use this signal in any context you want and share it freely between any number of different Updater monads.
newSignalIO :: a -> IO (Signal a) Source
writeSignal :: Signal a -> a -> Updater () Source
Writes the value to the variable inside the signal and schedules the listeners to run. The listeners will run in the same stm action and with the value you gave. However, they do not run immediately. So you are guaranteed that writeSignal will not have any immediate sideffects other then writing the one single variable.
readSignal :: Signal a -> Updater a Source
Gets the current value.
Updater Monad
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
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.
Helpers
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
modifySignal :: Signal a -> (a -> a) -> Updater () Source
simple combination of readSignal and writeSignal
getBehavior :: Signal a -> Updater a Source
Similar to getEvent
except that it also fires an event immediately,
with the value of the current state.
getBehavior signal = liftSTM (readSignal signal) <|> getEvent signal
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)
runGlobalUpdater :: Updater a -> IO () Source
this is just a convenience for use in ghci and in the test cases. It will just run the updater it is given in it's own thread.