Yampa-0.10.5: Library for programming hybrid systems.

Copyright(c) Antony Courtney and Henrik Nilsson, Yale University, 2003
LicenseBSD-style (see the LICENSE file in the distribution)
Maintainernilsson@cs.yale.edu
Stabilityprovisional
Portabilityportable
Safe HaskellSafe
LanguageHaskell98

FRP.Yampa.Event

Description

Definition of Yampa Event type.

Note on naming conventions used in this module.

Names here might have to be rethought. It's really a bit messy. In general, the aim has been short and convenient names (like tag, attach, lMerge) and thus we have tried to stay away from suffixing/ prefixing conventions. E.g. Event as a common suffix would be very verbose.

However, part of the names come from a desire to stay close to similar functions for the Maybe type. e.g. event, fromEvent, isEvent. In many cases, this use of Event can could understood to refer to the constructor Event, not to the type name Event. Thus this use of event should not be seen as a suffixing-with-type-name convention. But that is obviously not easy to see, and, more over, interpreting Event as the name of the type might make equally good or better sense. E.g. fromEvent can also be seen as a function taking an event signal, which is a partial function on time, to a normal signal. The latter is then undefined when the source event function is undefined.

In other cases, it has been necessary to somehow stay out of the way of names used by the prelude or other commonly imported modules/modules which could be expected to be used heavily in Yampa code. In those cases a suffix E have been added. Examples are filterE (exists in Prelude) and joinE (exists in Monad). Maybe the suffix isn't necessary in the last case.

Some functions (actually only one currently, mapFilterE) have got an E suffix just because they're closely related (by name or semantics) to one which already has an E suffix. Another candidate would be splitE to complement joinE. But events carrying pairs could obviously have other sources than a joinE, so currently it is called split.

2003-05-19: Actually, have now changed to splitE to avoid a clash with the method split in the class RandomGen.

2003-05-19: What about gate? Stands out compared to e.g. filterE.

Currently the E suffix is considered an exception. Maybe we should use completely different names to avoid the E suffix. If the functions are not used that often, Event might be approriate. Alternatively the suffix E should be adopted globaly (except if the name already contains event in some form?).

Arguably, having both a type Event and a constructor Event is confusing since there are more than one constructor. But the name Event for the constructor is quite apt. It's really the type name that is wrong. But no one has found a better name, and changing it would be a really major undertaking. Yes, the constructor Event is not exported, but we still need to talk conceptually about them. On the other hand, if we consider Event-signals as partial functions on time, maybe it isn't so confusing: they just don't have a value between events, so NoEvent does not really exist conceptually.

ToDo: - Either: reveal NoEvent and Event or: introcuce 'event = Event', call what's now event fromEvent, and call what's now called fromEvent something else, like unsafeFromEvent??? Better, dump it! After all, using current names, 'fromEvent = event undefined'!

Synopsis

Documentation

data Event a

A single possible event occurrence, that is, a value that may or may not occur. Events are used to represent values that are not produced continuously, such as mouse clicks (only produced when the mouse is clicked, as opposed to mouse positions, which are always defined).

Constructors

NoEvent 
Event a 

Instances

Monad Event

Monad instance

Functor Event

Functor instance (could be derived).

Applicative Event

Applicative instance (similar to Maybe).

Alternative Event

Alternative instance

Eq a => Eq (Event a)

Eq instance (equivalent to derived instance)

Ord a => Ord (Event a)

Ord instance (equivalent to derived instance)

Show a => Show (Event a) 
NFData a => NFData (Event a)

NFData instance

Forceable a => Forceable (Event a)

Forceable instance

noEvent :: Event a

Make the NoEvent constructor available. Useful e.g. for initialization, ((-->) & friends), and it's easily available anyway (e.g. mergeEvents []).

noEventFst :: (Event a, b) -> (Event c, b)

Suppress any event in the first component of a pair.

noEventSnd :: (a, Event b) -> (a, Event c)

Suppress any event in the second component of a pair.

maybeToEvent :: Maybe a -> Event a

Convert a maybe value into a event (Event is isomorphic to Maybe).

event :: a -> (b -> a) -> Event b -> a

An event-based version of the maybe function.

fromEvent :: Event a -> a

Extract the value from an event. Fails if there is no event.

isEvent :: Event a -> Bool

Tests whether the input represents an actual event.

isNoEvent :: Event a -> Bool

Negation of isEvent.

tag :: Event a -> b -> Event b infixl 8

Tags an (occurring) event with a value ("replacing" the old value).

Applicative-based definition: tag = ($>)

tagWith :: b -> Event a -> Event b

Tags an (occurring) event with a value ("replacing" the old value). Same as tag with the arguments swapped.

Applicative-based definition: tagWith = (<$)

attach :: Event a -> b -> Event (a, b) infixl 8

Attaches an extra value to the value of an occurring event.

lMerge :: Event a -> Event a -> Event a infixl 6

Left-biased event merge (always prefer left event, if present).

rMerge :: Event a -> Event a -> Event a infixl 6

Right-biased event merge (always prefer right event, if present).

merge :: Event a -> Event a -> Event a infixl 6

Unbiased event merge: simultaneous occurrence is an error.

mergeBy :: (a -> a -> a) -> Event a -> Event a -> Event a

Event merge parameterized by a conflict resolution function.

Applicative-based definition: mergeBy f re le = (f $ re * le) | re | le

mapMerge :: (a -> c) -> (b -> c) -> (a -> b -> c) -> Event a -> Event b -> Event c

A generic event merge-map utility that maps event occurrences, merging the results. The first three arguments are mapping functions, the third of which will only be used when both events are present. Therefore, mergeBy = mapMerge id id

mergeEvents :: [Event a] -> Event a

Merge a list of events; foremost event has priority.

catEvents :: [Event a] -> Event [a]

Collect simultaneous event occurrences; no event if none.

joinE :: Event a -> Event b -> Event (a, b) infixl 7

Join (conjunction) of two events. Only produces an event if both events exist.

splitE :: Event (a, b) -> (Event a, Event b)

Split event carrying pairs into two events.

filterE :: (a -> Bool) -> Event a -> Event a

Filter out events that don't satisfy some predicate.

mapFilterE :: (a -> Maybe b) -> Event a -> Event b

Combined event mapping and filtering. Note: since Event is a Functor, see fmap for a simpler version of this function with no filtering.

gate :: Event a -> Bool -> Event a infixl 8

Enable/disable event occurences based on an external condition.