Elerea (Eventless Reactivity) is a simplistic FRP implementation that parts with the concept of events, and uses a continuous latching construct instead. The user sees the functionality through an applicative interface, which is used to build up a network of interconnected mutable references. The network is executed iteratively, where each superstep consists of two phases: sampling-aging and finalisation. As an example, the following code is a possible way to define an approximation of our beloved trig functions:
sine = integral 0 cosine cosine = integral 1 (-sine)
Note that integral
is not a primitive, it can be defined by the user
as a transfer function. A possible implementation that can be used on
any Fractional
signal looks like this:
integral x0 s = transfer x0 (\dt x x0 -> x0+x*realToFrac dt) s
Head to FRP.Elerea.Internal for the implementation details.
- type Time = Double
- type DTime = Double
- type Sink a = a -> IO ()
- data Signal a
- superstep :: Signal a -> DTime -> IO a
- time :: Signal Time
- stateless :: (Time -> a) -> Signal a
- stateful :: a -> (DTime -> a -> a) -> Signal a
- transfer :: a -> (DTime -> t -> a -> a) -> Signal t -> Signal a
- latcher :: Signal a -> Signal Bool -> Signal (Signal a) -> Signal a
- external :: a -> IO (Signal a, Sink a)
Documentation
A signal is represented as a transactional structural node.
Functor Signal | |
Applicative Signal | The |
Eq (Signal a) | The equality test checks whether to signals are physically the same. |
Fractional t => Fractional (Signal t) | |
Num t => Num (Signal t) | |
Show (Signal a) | The |
:: Signal a | the top-level signal |
-> DTime | the amount of time to advance |
-> IO a | the value of the signal before the update |
Advancing the whole network that the given signal depends on by
the amount of time given in the second argument. Note that the shared
time
signal is also advanced, so this function should only be used
for sampling the top level.
A pure stateful signal.
:: a | initial state |
-> (DTime -> t -> a -> a) | state updater function |
-> Signal t | input signal |
-> Signal a |
A stateful transfer function. The current input can only affect the next output, i.e. there is an implicit delay.
:: Signal a |
|
-> Signal Bool |
|
-> Signal (Signal a) |
|
-> Signal a |
Reactive signal that starts out as s
and can change its
behaviour to the one supplied in ss
whenever e
is true. The change
can only be observed in the next instant.