Yampa-0.10.7: Library for programming hybrid systems.

Copyright (c) Antony Courtney and Henrik Nilsson Yale University 2003 BSD-style (see the LICENSE file in the distribution) ivan.perez@keera.co.uk provisional non-portable (GHC extensions) None Haskell98

FRP.Yampa.Switches

Description

Switches allow you to change the signal function being applied.

The basic idea of switching is fromed by combining a subordinate signal function and a signal function continuation parameterised over some initial data.

For example, the most basic switch has the following signature:

switch :: SF a (b, Event c) -> (c -> SF a b) -> SF a b

which indicates that it has two parameters: a signal function that produces an output and indicates, with an event, when it is time to switch, and a signal function that starts with the residual data left by the first SF in the event and continues onwards.

Note that switching occurs, at most, once. If you want something to switch repeatedly, you need to loop. However, some switches are immediate (meaning that the second SF is started at the time of switching). If you use the same SF that originally provoked the switch, you are very likely to fall into an infinite loop.

Synopsis

# Switching

## Basic switchers

switch :: SF a (b, Event c) -> (c -> SF a b) -> SF a b Source #

Basic switch.

By default, the first signal function is applied.

Whenever the second value in the pair actually is an event, the value carried by the event is used to obtain a new signal function to be applied *at that time and at future times*.

Until that happens, the first value in the pair is produced in the output signal.

Important note: at the time of switching, the second signal function is applied immediately. If that second SF can also switch at time zero, then a double (nested) switch might take place. If the second SF refers to the first one, the switch might take place infinitely many times and never be resolved.

Remember: The continuation is evaluated strictly at the time of switching!

dSwitch :: SF a (b, Event c) -> (c -> SF a b) -> SF a b Source #

Switch with delayed observation.

By default, the first signal function is applied.

Whenever the second value in the pair actually is an event, the value carried by the event is used to obtain a new signal function to be applied *at future times*.

Until that happens, the first value in the pair is produced in the output signal.

Important note: at the time of switching, the second signal function is used immediately, but the current input is fed by it (even though the actual output signal value at time 0 is discarded).

If that second SF can also switch at time zero, then a double (nested) -- switch might take place. If the second SF refers to the first one, the switch might take place infinitely many times and never be resolved.

Remember: The continuation is evaluated strictly at the time of switching!

rSwitch :: SF a b -> SF (a, Event (SF a b)) b Source #

Recurring switch.

drSwitch :: SF a b -> SF (a, Event (SF a b)) b Source #

Recurring switch with delayed observation.

kSwitch :: SF a b -> SF (a, b) (Event c) -> (SF a b -> c -> SF a b) -> SF a b Source #

dkSwitch :: SF a b -> SF (a, b) (Event c) -> (SF a b -> c -> SF a b) -> SF a b Source #

kSwitch with delayed observation.

## Parallel composition and switching

### Parallel composition and switching over collections with broadcasting

parB :: Functor col => col (SF a b) -> SF a (col b) Source #

Spatial parallel composition of a signal function collection. Given a collection of signal functions, it returns a signal function that broadcasts its input signal to every element of the collection, to return a signal carrying a collection of outputs. See par.

pSwitchB :: Functor col => col (SF a b) -> SF (a, col b) (Event c) -> (col (SF a b) -> c -> SF a (col b)) -> SF a (col b) Source #

Parallel switch (dynamic collection of signal functions spatially composed in parallel). See pSwitch.

dpSwitchB :: Functor col => col (SF a b) -> SF (a, col b) (Event c) -> (col (SF a b) -> c -> SF a (col b)) -> SF a (col b) Source #

Delayed parallel switch with broadcasting (dynamic collection of signal functions spatially composed in parallel). See dpSwitch.

rpSwitchB :: Functor col => col (SF a b) -> SF (a, Event (col (SF a b) -> col (SF a b))) (col b) Source #

drpSwitchB :: Functor col => col (SF a b) -> SF (a, Event (col (SF a b) -> col (SF a b))) (col b) Source #

### Parallel composition and switching over collections with general routing

Arguments

 :: Functor col => (forall sf. a -> col sf -> col (b, sf)) Determines the input to each signal function in the collection. IMPORTANT! The routing function MUST preserve the structure of the signal function collection. -> col (SF b c) Signal function collection. -> SF a (col c)

Spatial parallel composition of a signal function collection parameterized on the routing function.

Arguments

 :: Functor col => (forall sf. a -> col sf -> col (b, sf)) Routing function: determines the input to each signal function in the collection. IMPORTANT! The routing function has an obligation to preserve the structure of the signal function collection. -> col (SF b c) Signal function collection. -> SF (a, col c) (Event d) Signal function generating the switching event. -> (col (SF b c) -> d -> SF a (col c)) Continuation to be invoked once event occurs. -> SF a (col c)

Parallel switch parameterized on the routing function. This is the most general switch from which all other (non-delayed) switches in principle can be derived. The signal function collection is spatially composed in parallel and run until the event signal function has an occurrence. Once the switching event occurs, all signal function are "frozen" and their continuations are passed to the continuation function, along with the event value.

Arguments

 :: Functor col => (forall sf. a -> col sf -> col (b, sf)) Routing function. Its purpose is to pair up each running signal function in the collection maintained by dpSwitch with the input it is going to see at each point in time. All the routing function can do is specify how the input is distributed. -> col (SF b c) Initial collection of signal functions. -> SF (a, col c) (Event d) Signal function that observes the external input signal and the output signals from the collection in order to produce a switching event. -> (col (SF b c) -> d -> SF a (col c)) The fourth argument is a function that is invoked when the switching event occurs, yielding a new signal function to switch into based on the collection of signal functions previously running and the value carried by the switching event. This allows the collection to be updated and then switched back in, typically by employing dpSwitch again. -> SF a (col c)

Parallel switch with delayed observation parameterized on the routing function.

The collection argument to the function invoked on the switching event is of particular interest: it captures the continuations of the signal functions running in the collection maintained by dpSwitch at the time of the switching event, thus making it possible to preserve their state across a switch. Since the continuations are plain, ordinary signal functions, they can be resumed, discarded, stored, or combined with other signal functions.

rpSwitch :: Functor col => (forall sf. a -> col sf -> col (b, sf)) -> col (SF b c) -> SF (a, Event (col (SF b c) -> col (SF b c))) (col c) Source #

drpSwitch :: Functor col => (forall sf. a -> col sf -> col (b, sf)) -> col (SF b c) -> SF (a, Event (col (SF b c) -> col (SF b c))) (col c) Source #

parZ :: [SF a b] -> SF [a] [b] Source #

pSwitchZ :: [SF a b] -> SF ([a], [b]) (Event c) -> ([SF a b] -> c -> SF [a] [b]) -> SF [a] [b] Source #

dpSwitchZ :: [SF a b] -> SF ([a], [b]) (Event c) -> ([SF a b] -> c -> SF [a] [b]) -> SF [a] [b] Source #

rpSwitchZ :: [SF a b] -> SF ([a], Event ([SF a b] -> [SF a b])) [b] Source #

drpSwitchZ :: [SF a b] -> SF ([a], Event ([SF a b] -> [SF a b])) [b] Source #

parC :: SF a b -> SF [a] [b] Source #