Safe Haskell | None |
---|---|

Language | Haskell2010 |

Small experimental library for interactive functional programs.

The following program reproduces the "time flows like a river" effect from Conal's Fran tutorial http://conal.net/fran/tutorial.htm. See also this video https://www.youtube.com/watch?v=_M6_doag0z0.

timeFlows :: String -> X R2 -> X [(Char, R2)] timeFlows message mouse = multiplex (zipWith f message [0..]) where f c i = delayX i (fmap (c,) mouse)

Using a recursive program it is possible to simulate a stateful object such as this stack.

data Stack a = Push a | Pop stack :: E (Stack a) -> E a stack cmd = out where out = justE (fmap fst result) state = trap [] (fmap snd result) arg = snapshot cmd state result = fmap f arg f (Push x) xs = (Nothing, x:xs) f Pop [] = (Nothing, []) f Pop (x:xs) = (Just x, xs)

- data X a
- data E a
- never :: E a
- unionE :: E a -> E a -> E a
- (<>) :: Monoid m => m -> m -> m
- (-|-) :: E a -> E b -> E (Either a b)
- voidE :: E a -> E ()
- snapshot :: E a -> X b -> E (a, b)
- snapshot_ :: E a -> X b -> E b
- accum :: s -> (a -> s -> s) -> E a -> X s
- edge :: (a -> a -> Maybe b) -> X a -> E b
- trap :: a -> E a -> X a
- justE :: E (Maybe a) -> E a
- maybeE :: (a -> Maybe b) -> E a -> E b
- filterE :: (a -> Bool) -> E a -> E a
- multiplex :: [X a] -> X [a]
- delayE :: DeltaT -> E a -> E a
- delayX :: DeltaT -> X a -> X a
- dilate :: Double -> X a -> X a
- timeWarp :: (Time -> Time) -> X a -> X a
- timeWarp' :: (Time -> Time) -> (Time -> Time) -> X a -> X a
- delayE' :: E (a, DeltaT) -> E a
- rasterize :: X a -> X a
- data Setup a
- type Time = Double
- type DeltaT = Double
- type Boot = ()
- runProgram :: (E Boot -> X Time -> Setup (E ())) -> IO ()
- newX :: a -> Setup (X a, a -> IO ())
- newE :: Setup (E a, a -> IO ())
- input :: IO () -> Setup ()
- output :: (Time -> a -> IO ()) -> E a -> Setup ()
- debugX :: Eq a => ((a, a) -> String) -> X a -> X a
- debugE :: (a -> String) -> E a -> E a

# Documentation

`X a`

represents time signals with values of type `a`

.

X a = Time -> a

`E a`

represents events with values of type `a`

.

E a = [(Time, a)]

# Event and signal combinators

(-|-) :: E a -> E b -> E (Either a b) Source

Same as `unionE`

but on events that might have a different type.

snapshot :: E a -> X b -> E (a, b) Source

An event which gets the value of a signal when another event occurs.

accum :: s -> (a -> s -> s) -> E a -> X s Source

Sum over events using an initial state and a state transition function.

edge :: (a -> a -> Maybe b) -> X a -> E b Source

An event that occurs on "edges" detected in a signal. The signal will be rasterized if necessary for this to make sense.

Like `timeWarp`

but works with events. The inverse of the warp function
must exist and be provided.

delayE' :: E (a, DeltaT) -> E a Source

Like `delayE`

but the amount of delay is determined on a per-event basis.

rasterize :: X a -> X a Source

Rasterize a signal. If there are several edge tests on a continuous signal then it's better to explicitly rasterize before.

# Setup IO interface

A monad for hooking up inputs and outputs to a program.

runProgram :: (E Boot -> X Time -> Setup (E ())) -> IO () Source

Runs a program defined by the setup computation. The simulation ends if the returned event occurs. The provided time signal is in units of seconds with zero at the beginning of the simulation.

newX :: a -> Setup (X a, a -> IO ()) Source

Creates a new input signal with an initial value. Use `input`

to feed
data to the signal during the simulation.

newE :: Setup (E a, a -> IO ()) Source

Creates a new input event and a command to trigger it. Use `input`

to
to provide external stimulus during the simulation.

input :: IO () -> Setup () Source

A thread to generate source signals and events will be started when setup is complete.

output :: (Time -> a -> IO ()) -> E a -> Setup () Source

Setup a thread to react to events. The callback will be provided with the time of the event which is measured in seconds since the start of the simulation.