broccoli- Small library for interactive functional programs.

Safe HaskellNone




Small experimental library for interactive functional programs.

The following program reproduces the "time flows like a river" effect from Conal's Fran tutorial See also this video

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 Source

X a represents time signals with values of type a.

X a = Time -> a


data E a Source

E a represents events with values of type a.

E a = [(Time, a)]


Functor E 
Monoid (E a)

mempty = never, mappend = unionE

Event and signal combinators

never :: E a Source

An event that never happens.

unionE :: E a -> E a -> E a Source

All the occurrences from two events together. Same as <>.

(<>) :: Monoid m => m -> m -> m infixr 6

An infix synonym for mappend.


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

Same as unionE but on events that might have a different type.

voidE :: E a -> E () Source

Forget the values associated with the events.

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

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

snapshot_ :: E a -> X b -> E b Source

Like snapshot but ignores the original event's payload.

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.

trap :: a -> E a -> X a Source

A signal that remembers the most recent occurrence of an event.

justE :: E (Maybe a) -> E a Source

Filter out events with the value of Nothing.

maybeE :: (a -> Maybe b) -> E a -> E b Source

Filter out events using a Maybe function.

filterE :: (a -> Bool) -> E a -> E a Source

Filter out events using a Bool function.

multiplex :: [X a] -> X [a] Source

From many signals, one.

delayE :: DeltaT -> E a -> E a Source

Delay occurrences of an event.

delayX :: DeltaT -> X a -> X a Source

Shift a signal ahead in time.

dilate :: Double -> X a -> X a Source

Slow down a signal by a factor.

timeWarp :: (Time -> Time) -> X a -> X a Source

Time warp a signal.

timeWarp' Source


:: (Time -> Time) 
-> (Time -> Time)

inverse of warp

-> X a 
-> X a 

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

data Setup a Source

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

type Boot = () Source

The boot event occurs once at the beginning of a simulation.

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.


debugX :: Eq a => ((a, a) -> String) -> X a -> X a Source

Print out transitions in a signal, rasterizing if necessary. Only for debugging purposes.

debugE :: (a -> String) -> E a -> E a Source

Print out events as they occur. Only for debugging purposes.