-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Library for programming hybrid systems.
--   
--   Domain-specific language embedded in Haskell for programming hybrid
--   (mixed discrete-time and continuous-time) systems. Yampa is based on
--   the concepts of Functional Reactive Programming (FRP) and is
--   structured using arrow combinators.
@package Yampa
@version 0.10.7


-- | Standardized error-reporting for Yampa
module FRP.Yampa.Diagnostics
usrErr :: String -> String -> String -> a
intErr :: String -> String -> String -> a


-- | Hyperstrict evaluation.

-- | <i>Deprecated: Use DeepSeq instead</i>
module FRP.Yampa.Forceable
class Forceable a
force :: Forceable a => a -> a
instance FRP.Yampa.Forceable.Forceable GHC.Types.Int
instance FRP.Yampa.Forceable.Forceable GHC.Integer.Type.Integer
instance FRP.Yampa.Forceable.Forceable GHC.Types.Double
instance FRP.Yampa.Forceable.Forceable GHC.Types.Float
instance FRP.Yampa.Forceable.Forceable GHC.Types.Bool
instance FRP.Yampa.Forceable.Forceable ()
instance FRP.Yampa.Forceable.Forceable GHC.Types.Char
instance (FRP.Yampa.Forceable.Forceable a, FRP.Yampa.Forceable.Forceable b) => FRP.Yampa.Forceable.Forceable (a, b)
instance (FRP.Yampa.Forceable.Forceable a, FRP.Yampa.Forceable.Forceable b, FRP.Yampa.Forceable.Forceable c) => FRP.Yampa.Forceable.Forceable (a, b, c)
instance (FRP.Yampa.Forceable.Forceable a, FRP.Yampa.Forceable.Forceable b, FRP.Yampa.Forceable.Forceable c, FRP.Yampa.Forceable.Forceable d) => FRP.Yampa.Forceable.Forceable (a, b, c, d)
instance (FRP.Yampa.Forceable.Forceable a, FRP.Yampa.Forceable.Forceable b, FRP.Yampa.Forceable.Forceable c, FRP.Yampa.Forceable.Forceable d, FRP.Yampa.Forceable.Forceable e) => FRP.Yampa.Forceable.Forceable (a, b, c, d, e)
instance FRP.Yampa.Forceable.Forceable a => FRP.Yampa.Forceable.Forceable [a]
instance FRP.Yampa.Forceable.Forceable a => FRP.Yampa.Forceable.Forceable (GHC.Base.Maybe a)


-- | Definition of Yampa Event type.
--   
--   Yampa Events represent discrete time-signals, meaning those that do
--   not change continuously. Examples of event-carrying signals would be
--   mouse clicks (in between clicks it is assumed that there is no click),
--   some keyboard events, button presses on wiimotes or window-manager
--   events.
--   
--   The type <tt>Event</tt> is isomorphic to <tt>Maybe</tt> (<tt>Event a =
--   NoEvent | Event a</tt>) but, semantically, a <tt>Maybe</tt>-carrying
--   signal could change continuously, whereas an <tt>Event</tt>-carrying
--   signal should not. No mechanism in Yampa will check this or misbehave
--   if this assumption is violated.
--   
--   Events are essential for many other Yampa constructs, like switches
--   (see <tt>FRP.Yampa.Switches.switch</tt> for details).
module FRP.Yampa.Event

-- | 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).
data Event a
NoEvent :: Event a
Event :: a -> Event a

-- | Make the NoEvent constructor available. Useful e.g. for
--   initialization, ((--&gt;) &amp; friends), and it's easily available
--   anyway (e.g. mergeEvents []).
noEvent :: Event a

-- | Suppress any event in the first component of a pair.
noEventFst :: (Event a, b) -> (Event c, b)

-- | Suppress any event in the second component of a pair.
noEventSnd :: (a, Event b) -> (a, Event c)

-- | Eq instance (equivalent to derived instance)

-- | Ord instance (equivalent to derived instance)

-- | Functor instance (could be derived).

-- | Applicative instance (similar to <a>Maybe</a>).

-- | Monad instance

-- | Alternative instance

-- | Forceable instance

-- | NFData instance

-- | Convert a maybe value into a event (<a>Event</a> is isomorphic to
--   <a>Maybe</a>).
maybeToEvent :: Maybe a -> Event a

-- | An event-based version of the maybe function.
event :: a -> (b -> a) -> Event b -> a

-- | Extract the value from an event. Fails if there is no event.
fromEvent :: Event a -> a

-- | Tests whether the input represents an actual event.
isEvent :: Event a -> Bool

-- | Negation of <a>isEvent</a>.
isNoEvent :: Event a -> Bool

-- | Tags an (occurring) event with a value ("replacing" the old value).
--   
--   Applicative-based definition: tag = ($&gt;)
tag :: Event a -> b -> Event b
infixl 8 `tag`

-- | Tags an (occurring) event with a value ("replacing" the old value).
--   Same as <a>tag</a> with the arguments swapped.
--   
--   Applicative-based definition: tagWith = (&lt;$)
tagWith :: b -> Event a -> Event b

-- | Attaches an extra value to the value of an occurring event.
attach :: Event a -> b -> Event (a, b)
infixl 8 `attach`

-- | Left-biased event merge (always prefer left event, if present).
lMerge :: Event a -> Event a -> Event a
infixl 6 `lMerge`

-- | Right-biased event merge (always prefer right event, if present).
rMerge :: Event a -> Event a -> Event a
infixl 6 `rMerge`

-- | Unbiased event merge: simultaneous occurrence is an error.
merge :: Event a -> Event a -> Event a
infixl 6 `merge`

-- | Event merge parameterized by a conflict resolution function.
--   
--   Applicative-based definition: mergeBy f le re = (f <a>$</a> le
--   <a>*</a> re) <a>|</a> le <a>|</a> re
mergeBy :: (a -> a -> a) -> Event a -> Event a -> Event a

-- | 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, <a>mergeBy</a> = <a>mapMerge</a> <a>id</a> <a>id</a>
--   
--   Applicative-based definition: mapMerge lf rf lrf le re = (f <a>$</a>
--   le <a>*</a> re) <a>|</a> (lf <a>$</a> le) <a>|</a> (rf <a>$</a> re)
mapMerge :: (a -> c) -> (b -> c) -> (a -> b -> c) -> Event a -> Event b -> Event c

-- | Merge a list of events; foremost event has priority.
--   
--   Foldable-based definition: mergeEvents :: Foldable t =&gt; t (Event a)
--   -&gt; Event a mergeEvents = asum
mergeEvents :: [Event a] -> Event a

-- | Collect simultaneous event occurrences; no event if none.
--   
--   Traverable-based definition: catEvents :: Foldable t =&gt; t (Event a)
--   -&gt; Event (t a) carEvents e = if (null e) then NoEvent else
--   (sequenceA e)
catEvents :: [Event a] -> Event [a]

-- | Join (conjunction) of two events. Only produces an event if both
--   events exist.
--   
--   Applicative-based definition: joinE = liftA2 (,)
joinE :: Event a -> Event b -> Event (a, b)
infixl 7 `joinE`

-- | Split event carrying pairs into two events.
splitE :: Event (a, b) -> (Event a, Event b)

-- | Filter out events that don't satisfy some predicate.
filterE :: (a -> Bool) -> Event a -> Event a

-- | Combined event mapping and filtering. Note: since <a>Event</a> is a
--   <a>Functor</a>, see <a>fmap</a> for a simpler version of this function
--   with no filtering.
mapFilterE :: (a -> Maybe b) -> Event a -> Event b

-- | Enable/disable event occurences based on an external condition.
gate :: Event a -> Bool -> Event a
infixl 8 `gate`
instance GHC.Show.Show a => GHC.Show.Show (FRP.Yampa.Event.Event a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (FRP.Yampa.Event.Event a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (FRP.Yampa.Event.Event a)
instance GHC.Base.Functor FRP.Yampa.Event.Event
instance GHC.Base.Applicative FRP.Yampa.Event.Event
instance GHC.Base.Monad FRP.Yampa.Event.Event
instance GHC.Base.Alternative FRP.Yampa.Event.Event
instance FRP.Yampa.Forceable.Forceable a => FRP.Yampa.Forceable.Forceable (FRP.Yampa.Event.Event a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (FRP.Yampa.Event.Event a)


-- | Defines basic signal functions, and elementary ways of altering them.
--   
--   This module defines very basic ways of creating and modifying signal
--   functions. In particular, it defines ways of creating constant output
--   producing SFs, and SFs that just pass the signal through unmodified.
--   
--   It also defines ways of altering the input and the output signal only
--   by inserting one value in the signal, or by transforming it.
module FRP.Yampa.Basic

-- | Identity: identity = arr id
--   
--   Using <a>identity</a> is preferred over lifting id, since the arrow
--   combinators know how to optimise certain networks based on the
--   transformations being applied.
identity :: SF a a

-- | Identity: constant b = arr (const b)
--   
--   Using <a>constant</a> is preferred over lifting const, since the arrow
--   combinators know how to optimise certain networks based on the
--   transformations being applied.
constant :: b -> SF a b

-- | Initialization operator (cf. Lustre/Lucid Synchrone).
--   
--   The output at time zero is the first argument, and from that point on
--   it behaves like the signal function passed as second argument.
(-->) :: b -> SF a b -> SF a b
infixr 0 -->

-- | Output pre-insert operator.
--   
--   Insert a sample in the output, and from that point on, behave like the
--   given sf.
(-:>) :: b -> SF a b -> SF a b
infixr 0 -:>

-- | Input initialization operator.
--   
--   The input at time zero is the first argument, and from that point on
--   it behaves like the signal function passed as second argument.
(>--) :: a -> SF a b -> SF a b
infixr 0 >--

-- | Transform initial output value.
--   
--   Applies a transformation <tt>f</tt> only to the first output value at
--   time zero.
(-=>) :: (b -> b) -> SF a b -> SF a b
infixr 0 -=>

-- | Transform initial input value.
--   
--   Applies a transformation <tt>f</tt> only to the first input value at
--   time zero.
(>=-) :: (a -> a) -> SF a b -> SF a b
infixr 0 >=-

-- | Override initial value of input signal.
initially :: a -> SF a a


-- | An interface giving access to some of the internal details of the
--   Yampa implementation.
--   
--   This interface is indended to be used when the need arises to break
--   abstraction barriers, e.g. for interfacing Yampa to the real world,
--   for debugging purposes, or the like. Be aware that the internal
--   details may change. Relying on this interface means that your code is
--   not insulated against such changes.
module FRP.Yampa.Internals

-- | 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).
data Event a
NoEvent :: Event a
Event :: a -> Event a


-- | Framework for record merging.
--   
--   Idea:
--   
--   MergeableRecord is intended to be a super class for classes providing
--   update operations on records. The ADT induced by such a set of
--   operations can be considered a "mergeable record", which can be merged
--   into larger mergeable records essentially by function composition.
--   Finalization turns a mergeable record into a record.
--   
--   Typical use:
--   
--   Given
--   
--   <pre>
--   data Foo = Foo {l1 :: T1, l2 :: T2}
--   </pre>
--   
--   one define a mergeable record type (MR Foo) by the following instance:
--   
--   <pre>
--   instance MergeableRecord Foo where
--       mrDefault = Foo {l1 = v1_dflt, l2 = v2_dflt}
--   </pre>
--   
--   Typically, one would also provide definitions for setting the fields,
--   possibly (but not necessarily) overloaded:
--   
--   <pre>
--   instance HasL1 Foo where
--       setL1 v = mrMake (foo -&gt; foo {l1 = v})
--   </pre>
--   
--   Now Foo records can be created as follows:
--   
--   <pre>
--   let foo1 = setL1 v1
--   ...
--   let foo2 = setL2 v2 ~+~ foo1
--   ...
--   let foo<a>N</a> = setL1 vN ~+~ foo<a>N-1</a>
--   let fooFinal = mrFinalize foo<a>N</a>
--   </pre>
module FRP.Yampa.MergeableRecord
class MergeableRecord a
mrDefault :: MergeableRecord a => a
data MR a
mrMake :: MergeableRecord a => (a -> a) -> MR a
(~+~) :: MergeableRecord a => MR a -> MR a -> MR a
mrMerge :: MergeableRecord a => MR a -> MR a -> MR a
mrFinalize :: MergeableRecord a => MR a -> a


-- | Collection of entities that really should be part of the Haskell 98
--   prelude or simply have no better home.
module FRP.Yampa.Miscellany

-- | <i>Deprecated: Use Control.Arrow.(&gt;&gt;&gt;) and
--   Control.Arrow.(&lt;&lt;&lt;).</i>
(#) :: (a -> b) -> (b -> c) -> (a -> c)
infixl 9 #
dup :: a -> (a, a)

-- | <i>Deprecated: mapFst is not used by Yampa and will be removed from
--   the next release</i>
mapFst :: (a -> b) -> [(a, c)] -> [(b, c)]

-- | <i>Deprecated: mapSnd is not used by Yampa and will be removed from
--   the next release</i>
mapSnd :: (a -> b) -> [(c, a)] -> [(c, b)]

-- | <i>Deprecated: Use the tuple package instead.</i>
sel3_1 :: (a, b, c) -> a

-- | <i>Deprecated: Use the tuple package instead.</i>
sel3_2 :: (a, b, c) -> b

-- | <i>Deprecated: Use the tuple package instead.</i>
sel3_3 :: (a, b, c) -> c

-- | <i>Deprecated: Use the tuple package instead.</i>
sel4_1 :: (a, b, c, d) -> a

-- | <i>Deprecated: Use the tuple package instead.</i>
sel4_2 :: (a, b, c, d) -> b

-- | <i>Deprecated: Use the tuple package instead.</i>
sel4_3 :: (a, b, c, d) -> c

-- | <i>Deprecated: Use the tuple package instead.</i>
sel4_4 :: (a, b, c, d) -> d

-- | <i>Deprecated: Use the tuple package instead.</i>
sel5_1 :: (a, b, c, d, e) -> a

-- | <i>Deprecated: Use the tuple package instead.</i>
sel5_2 :: (a, b, c, d, e) -> b

-- | <i>Deprecated: Use the tuple package instead.</i>
sel5_3 :: (a, b, c, d, e) -> c

-- | <i>Deprecated: Use the tuple package instead.</i>
sel5_4 :: (a, b, c, d, e) -> d

-- | <i>Deprecated: Use the tuple package instead.</i>
sel5_5 :: (a, b, c, d, e) -> e

-- | <i>Deprecated: These are not used by Yampa and will be removed.</i>
fDiv :: (RealFrac a) => a -> a -> Integer
infixl 7 `fDiv`

-- | <i>Deprecated: These are not used by Yampa and will be removed.</i>
fMod :: (RealFrac a) => a -> a -> a
infixl 7 `fMod`

-- | <i>Deprecated: These are not used by Yampa and will be removed.</i>
fDivMod :: (RealFrac a) => a -> a -> (Integer, a)
arr2 :: Arrow a => (b -> c -> d) -> a (b, c) d
arr3 :: Arrow a => (b -> c -> d -> e) -> a (b, c, d) e
arr4 :: Arrow a => (b -> c -> d -> e -> f) -> a (b, c, d, e) f
arr5 :: Arrow a => (b -> c -> d -> e -> f -> g) -> a (b, c, d, e, f) g
lift0 :: Arrow a => c -> a b c
lift1 :: Arrow a => (c -> d) -> (a b c -> a b d)
lift2 :: Arrow a => (c -> d -> e) -> (a b c -> a b d -> a b e)
lift3 :: Arrow a => (c -> d -> e -> f) -> (a b c -> a b d -> a b e -> a b f)
lift4 :: Arrow a => (c -> d -> e -> f -> g) -> (a b c -> a b d -> a b e -> a b f -> a b g)
lift5 :: Arrow a => (c -> d -> e -> f -> g -> h) -> (a b c -> a b d -> a b e -> a b f -> a b g -> a b h)


module FRP.Yampa.Random

-- | The class <a>RandomGen</a> provides a common interface to random
--   number generators.
class RandomGen g

-- | The <a>next</a> operation returns an <a>Int</a> that is uniformly
--   distributed in the range returned by <a>genRange</a> (including both
--   end points), and a new generator.
next :: RandomGen g => g -> (Int, g)

-- | The <a>genRange</a> operation yields the range of values returned by
--   the generator.
--   
--   It is required that:
--   
--   <ul>
--   <li>If <tt>(a,b) = <a>genRange</a> g</tt>, then <tt>a &lt;
--   b</tt>.</li>
--   <li><a>genRange</a> always returns a pair of defined <a>Int</a>s.</li>
--   </ul>
--   
--   The second condition ensures that <a>genRange</a> cannot examine its
--   argument, and hence the value it returns can be determined only by the
--   instance of <a>RandomGen</a>. That in turn allows an implementation to
--   make a single call to <a>genRange</a> to establish a generator's
--   range, without being concerned that the generator returned by (say)
--   <a>next</a> might have a different range to the generator passed to
--   <a>next</a>.
--   
--   The default definition spans the full range of <a>Int</a>.
genRange :: RandomGen g => g -> (Int, Int)

-- | The <a>split</a> operation allows one to obtain two distinct random
--   number generators. This is very useful in functional programs (for
--   example, when passing a random number generator down to recursive
--   calls), but very little work has been done on statistically robust
--   implementations of <a>split</a> ([<a>System.Random\#Burton</a>,
--   <a>System.Random\#Hellekalek</a>] are the only examples we know of).
split :: RandomGen g => g -> (g, g)

-- | With a source of random number supply in hand, the <a>Random</a> class
--   allows the programmer to extract random values of a variety of types.
--   
--   Minimal complete definition: <a>randomR</a> and <a>random</a>.
class Random a

-- | Takes a range <i>(lo,hi)</i> and a random number generator <i>g</i>,
--   and returns a random value uniformly distributed in the closed
--   interval <i>[lo,hi]</i>, together with a new generator. It is
--   unspecified what happens if <i>lo&gt;hi</i>. For continuous types
--   there is no requirement that the values <i>lo</i> and <i>hi</i> are
--   ever produced, but they may be, depending on the implementation and
--   the interval.
randomR :: (Random a, RandomGen g) => (a, a) -> g -> (a, g)

-- | The same as <a>randomR</a>, but using a default range determined by
--   the type:
--   
--   <ul>
--   <li>For bounded types (instances of <a>Bounded</a>, such as
--   <a>Char</a>), the range is normally the whole type.</li>
--   <li>For fractional types, the range is normally the semi-closed
--   interval <tt>[0,1)</tt>.</li>
--   <li>For <a>Integer</a>, the range is (arbitrarily) the range of
--   <a>Int</a>.</li>
--   </ul>
random :: (Random a, RandomGen g) => g -> (a, g)

-- | Plural variant of <a>randomR</a>, producing an infinite list of random
--   values instead of returning a new generator.
randomRs :: (Random a, RandomGen g) => (a, a) -> g -> [a]

-- | Plural variant of <a>random</a>, producing an infinite list of random
--   values instead of returning a new generator.
randoms :: (Random a, RandomGen g) => g -> [a]

-- | A variant of <a>randomR</a> that uses the global random number
--   generator (see <a>System.Random#globalrng</a>).
randomRIO :: Random a => (a, a) -> IO a

-- | A variant of <a>random</a> that uses the global random number
--   generator (see <a>System.Random#globalrng</a>).
randomIO :: Random a => IO a

-- | Noise (random signal) with default range for type in question; based
--   on "randoms".
noise :: (RandomGen g, Random b) => g -> SF a b

-- | Noise (random signal) with specified range; based on "randomRs".
noiseR :: (RandomGen g, Random b) => (b, b) -> g -> SF a b

-- | Stochastic event source with events occurring on average once every
--   t_avg seconds. However, no more than one event results from any one
--   sampling interval in the case of relatively sparse sampling, thus
--   avoiding an "event backlog" should sampling become more frequent at
--   some later point in time.
occasionally :: RandomGen g => g -> Time -> b -> SF a (Event b)


module FRP.Yampa.Scan
sscan :: (b -> a -> b) -> b -> SF a b
sscanPrim :: (c -> a -> Maybe (c, b)) -> c -> b -> SF a b


module FRP.Yampa.Delays

-- | Uninitialized delay operator.
pre :: SF a a

-- | Initialized delay operator.
iPre :: a -> SF a a

-- | Delay a signal by a fixed time <tt>t</tt>, using the second parameter
--   to fill in the initial <tt>t</tt> seconds.
delay :: Time -> a -> SF a a

-- | Lucid-Synchrone-like initialized delay (read "followed by").
fby :: b -> SF a b -> SF a b
infixr 0 `fby`


module FRP.Yampa.Hybrid

-- | Zero-order hold.
hold :: a -> SF (Event a) a

-- | Zero-order hold with delay.
--   
--   Identity: dHold a0 = hold a0 &gt;&gt;&gt; iPre a0).
dHold :: a -> SF (Event a) a

-- | Tracks input signal when available, holds last value when disappears.
--   
--   !!! DANGER!!! Event used inside arr! Probably OK because arr will not
--   be !!! optimized to arrE. But still. Maybe rewrite this using, say,
--   scan? !!! or switch? Switching (in hold) for every input sample does
--   not !!! seem like such a great idea anyway.
trackAndHold :: a -> SF (Maybe a) a
dTrackAndHold :: a -> SF (Maybe a) a

-- | Given an initial value in an accumulator, it returns a signal function
--   that processes an event carrying transformation functions. Every time
--   an <a>Event</a> is received, the function inside it is applied to the
--   accumulator, whose new value is outputted in an <a>Event</a>.
accum :: a -> SF (Event (a -> a)) (Event a)

-- | Zero-order hold accumulator (always produces the last outputted value
--   until an event arrives).
accumHold :: a -> SF (Event (a -> a)) a

-- | Zero-order hold accumulator with delayed initialization (always
--   produces the last outputted value until an event arrives, but the very
--   initial output is always the given accumulator).
dAccumHold :: a -> SF (Event (a -> a)) a

-- | Accumulator parameterized by the accumulation function.
accumBy :: (b -> a -> b) -> b -> SF (Event a) (Event b)

-- | Zero-order hold accumulator parameterized by the accumulation
--   function.
accumHoldBy :: (b -> a -> b) -> b -> SF (Event a) b

-- | Zero-order hold accumulator parameterized by the accumulation function
--   with delayed initialization (initial output sample is always the given
--   accumulator).
dAccumHoldBy :: (b -> a -> b) -> b -> SF (Event a) b

-- | Accumulator parameterized by the accumulator function with filtering,
--   possibly discarding some of the input events based on whether the
--   second component of the result of applying the accumulation function
--   is <a>Nothing</a> or <a>Just</a> x for some x.
accumFilter :: (c -> a -> (c, Maybe b)) -> c -> SF (Event a) (Event b)


module FRP.Yampa.Simulation

-- | Convenience function to run a signal function indefinitely, using a IO
--   actions to obtain new input and process the output.
--   
--   This function first runs the initialization action, which provides the
--   initial input for the signal transformer at time 0.
--   
--   Afterwards, an input sensing action is used to obtain new input (if
--   any) and the time since the last iteration. The argument to the input
--   sensing function indicates if it can block. If no new input is
--   received, it is assumed to be the same as in the last iteration.
--   
--   After applying the signal function to the input, the actuation IO
--   action is executed. The first argument indicates if the output has
--   changed, the second gives the actual output). Actuation functions may
--   choose to ignore the first argument altogether. This action should
--   return True if the reactimation must stop, and False if it should
--   continue.
--   
--   Note that this becomes the program's <i>main loop</i>, which makes
--   using this function incompatible with GLUT, Gtk and other graphics
--   libraries. It may also impose a sizeable constraint in larger projects
--   in which different subparts run at different time steps. If you need
--   to control the main loop yourself for these or other reasons, use
--   <a>reactInit</a> and <a>react</a>.
reactimate :: Monad m => m a -> (Bool -> m (DTime, Maybe a)) -> (Bool -> b -> m Bool) -> SF a b -> m ()

-- | A reference to reactimate's state, maintained across samples.
type ReactHandle a b = IORef (ReactState a b)

-- | Initialize a top-level reaction handle.
reactInit :: IO a -> (ReactHandle a b -> Bool -> b -> IO Bool) -> SF a b -> IO (ReactHandle a b)

-- | Process a single input sample.
react :: ReactHandle a b -> (DTime, Maybe a) -> IO Bool

-- | Given a signal function and a pair with an initial input sample for
--   the input signal, and a list of sampling times, possibly with new
--   input samples at those times, it produces a list of output samples.
--   
--   This is a simplified, purely-functional version of <a>reactimate</a>.
embed :: SF a b -> (a, [(DTime, Maybe a)]) -> [b]

-- | Synchronous embedding. The embedded signal function is run on the
--   supplied input and time stream at a given (but variable) ratio &gt;= 0
--   to the outer time flow. When the ratio is 0, the embedded signal
--   function is paused.
embedSynch :: SF a b -> (a, [(DTime, Maybe a)]) -> SF Double b

-- | Spaces a list of samples by a fixed time delta, avoiding unnecessary
--   samples when the input has not changed since the last sample.
deltaEncode :: Eq a => DTime -> [a] -> (a, [(DTime, Maybe a)])

-- | <a>deltaEncode</a> parameterized by the equality test.
deltaEncodeBy :: (a -> a -> Bool) -> DTime -> [a] -> (a, [(DTime, Maybe a)])


-- | 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:
--   
--   <pre>
--   switch :: SF a (b, Event c) -&gt; (c -&gt; SF a b) -&gt; SF a b
--   </pre>
--   
--   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.
module FRP.Yampa.Switches

-- | 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!
switch :: SF a (b, Event c) -> (c -> SF a b) -> SF a b

-- | 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!
dSwitch :: SF a (b, Event c) -> (c -> SF a b) -> SF a b

-- | Recurring switch.
--   
--   See <a>https://wiki.haskell.org/Yampa#Switches</a> for more
--   information on how this switch works.
rSwitch :: SF a b -> SF (a, Event (SF a b)) b

-- | Recurring switch with delayed observation.
--   
--   See <a>https://wiki.haskell.org/Yampa#Switches</a> for more
--   information on how this switch works.
drSwitch :: SF a b -> SF (a, Event (SF a b)) b

-- | <a>Call-with-current-continuation</a> switch.
--   
--   See <a>https://wiki.haskell.org/Yampa#Switches</a> for more
--   information on how this switch works.
kSwitch :: SF a b -> SF (a, b) (Event c) -> (SF a b -> c -> SF a b) -> SF a b

-- | <a>kSwitch</a> with delayed observation.
--   
--   See <a>https://wiki.haskell.org/Yampa#Switches</a> for more
--   information on how this switch works.
dkSwitch :: SF a b -> SF (a, b) (Event c) -> (SF a b -> c -> SF a b) -> SF a b

-- | Spatial parallel composition of a signal function collection. Given a
--   collection of signal functions, it returns a signal function that
--   <a>broadcast</a>s its input signal to every element of the collection,
--   to return a signal carrying a collection of outputs. See <a>par</a>.
--   
--   For more information on how parallel composition works, check
--   <a>http://haskell.cs.yale.edu/wp-content/uploads/2011/01/yampa-arcade.pdf</a>
parB :: Functor col => col (SF a b) -> SF a (col b)

-- | Parallel switch (dynamic collection of signal functions spatially
--   composed in parallel). See <a>pSwitch</a>.
--   
--   For more information on how parallel composition works, check
--   <a>http://haskell.cs.yale.edu/wp-content/uploads/2011/01/yampa-arcade.pdf</a>
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)

-- | Delayed parallel switch with broadcasting (dynamic collection of
--   signal functions spatially composed in parallel). See <a>dpSwitch</a>.
--   
--   For more information on how parallel composition works, check
--   <a>http://haskell.cs.yale.edu/wp-content/uploads/2011/01/yampa-arcade.pdf</a>
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)
rpSwitchB :: Functor col => col (SF a b) -> SF (a, Event (col (SF a b) -> col (SF a b))) (col b)
drpSwitchB :: Functor col => col (SF a b) -> SF (a, Event (col (SF a b) -> col (SF a b))) (col b)

-- | Spatial parallel composition of a signal function collection
--   parameterized on the routing function.
par :: Functor col => (forall sf. (a -> col sf -> col (b, sf))) -> col (SF b c) -> 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.
pSwitch :: Functor col => (forall sf. (a -> col sf -> col (b, sf))) -> col (SF b c) -> SF (a, col c) (Event d) -> (col (SF b c) -> d -> SF a (col c)) -> 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 <a>dpSwitch</a> 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.
dpSwitch :: Functor col => (forall sf. (a -> col sf -> col (b, sf))) -> col (SF b c) -> SF (a, col c) (Event d) -> (col (SF b c) -> d -> SF a (col c)) -> SF a (col c)
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)
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)
parZ :: [SF a b] -> SF [a] [b]
pSwitchZ :: [SF a b] -> SF ([a], [b]) (Event c) -> ([SF a b] -> c -> SF [a] [b]) -> SF [a] [b]
dpSwitchZ :: [SF a b] -> SF ([a], [b]) (Event c) -> ([SF a b] -> c -> SF [a] [b]) -> SF [a] [b]
rpSwitchZ :: [SF a b] -> SF ([a], Event ([SF a b] -> [SF a b])) [b]
drpSwitchZ :: [SF a b] -> SF ([a], Event ([SF a b] -> [SF a b])) [b]
parC :: SF a b -> SF [a] [b]


module FRP.Yampa.EventS

-- | Event source that never occurs.
never :: SF a (Event b)

-- | Event source with a single occurrence at time 0. The value of the
--   event is given by the function argument.
now :: b -> SF a (Event b)

-- | Event source with a single occurrence at or as soon after (local) time
--   <i>q</i> as possible.
after :: Time -> b -> SF a (Event b)

-- | Event source with repeated occurrences with interval q. Note: If the
--   interval is too short w.r.t. the sampling intervals, the result will
--   be that events occur at every sample. However, no more than one event
--   results from any sampling interval, thus avoiding an "event backlog"
--   should sampling become more frequent at some later point in time.
repeatedly :: Time -> b -> SF a (Event b)

-- | Event source with consecutive occurrences at the given intervals.
--   Should more than one event be scheduled to occur in any sampling
--   interval, only the first will in fact occur to avoid an event backlog.
afterEach :: [(Time, b)] -> SF a (Event b)

-- | Event source with consecutive occurrences at the given intervals.
--   Should more than one event be scheduled to occur in any sampling
--   interval, the output list will contain all events produced during that
--   interval.
afterEachCat :: [(Time, b)] -> SF a (Event [b])

-- | Delay for events. (Consider it a triggered after, hence <i>basic</i>.)
delayEvent :: Time -> SF (Event a) (Event a)

-- | Delay an event by a given delta and catenate events that occur so
--   closely so as to be <i>inseparable</i>.
delayEventCat :: Time -> SF (Event a) (Event [a])

-- | A rising edge detector. Useful for things like detecting key presses.
--   It is initialised as <i>up</i>, meaning that events occuring at time 0
--   will not be detected.
edge :: SF Bool (Event ())

-- | A rising edge detector that can be initialized as up (<a>True</a>,
--   meaning that events occurring at time 0 will not be detected) or down
--   (<a>False</a>, meaning that events ocurring at time 0 will be
--   detected).
iEdge :: Bool -> SF Bool (Event ())

-- | Like <a>edge</a>, but parameterized on the tag value.
edgeTag :: a -> SF Bool (Event a)

-- | Edge detector particularized for detecting transtitions on a
--   <a>Maybe</a> signal from <a>Nothing</a> to <a>Just</a>.
edgeJust :: SF (Maybe a) (Event a)

-- | Edge detector parameterized on the edge detection function and initial
--   state, i.e., the previous input sample. The first argument to the edge
--   detection function is the previous sample, the second the current one.
edgeBy :: (a -> a -> Maybe b) -> a -> SF a (Event b)

-- | Suppression of initial (at local time 0) event.
notYet :: SF (Event a) (Event a)

-- | Suppress all but the first event.
once :: SF (Event a) (Event a)

-- | Suppress all but the first n events.
takeEvents :: Int -> SF (Event a) (Event a)

-- | Suppress first n events.
dropEvents :: Int -> SF (Event a) (Event a)
snap :: SF a (Event a)
snapAfter :: Time -> SF a (Event a)
sample :: Time -> SF a (Event a)
recur :: SF a (Event b) -> SF a (Event b)
andThen :: SF a (Event b) -> SF a (Event b) -> SF a (Event b)
infixr 5 `andThen`

module FRP.Yampa.Conditional
provided :: (a -> Bool) -> SF a b -> SF a b -> SF a b

-- | Given a value in an accumulator (b), a predicate signal function
--   (sfC), and a second signal function (sf), pause will produce the
--   accumulator b if sfC input is True, and will transform the signal
--   using sf otherwise. It acts as a pause with an accumulator for the
--   moments when the transformation is paused.
pause :: b -> SF a Bool -> SF a b -> SF a b


-- | Vector space type relation and basic instances.
module FRP.Yampa.VectorSpace
class (Eq a, Floating a) => VectorSpace v a | v -> a
zeroVector :: VectorSpace v a => v
(*^) :: VectorSpace v a => a -> v -> v
(^/) :: VectorSpace v a => v -> a -> v
negateVector :: VectorSpace v a => v -> v
(^+^) :: VectorSpace v a => v -> v -> v
(^-^) :: VectorSpace v a => v -> v -> v
dot :: VectorSpace v a => v -> v -> a
norm :: VectorSpace v a => v -> a
normalize :: VectorSpace v a => v -> v
instance FRP.Yampa.VectorSpace.VectorSpace GHC.Types.Float GHC.Types.Float
instance FRP.Yampa.VectorSpace.VectorSpace GHC.Types.Double GHC.Types.Double
instance (GHC.Classes.Eq a, GHC.Float.Floating a) => FRP.Yampa.VectorSpace.VectorSpace (a, a) a
instance (GHC.Classes.Eq a, GHC.Float.Floating a) => FRP.Yampa.VectorSpace.VectorSpace (a, a, a) a
instance (GHC.Classes.Eq a, GHC.Float.Floating a) => FRP.Yampa.VectorSpace.VectorSpace (a, a, a, a) a
instance (GHC.Classes.Eq a, GHC.Float.Floating a) => FRP.Yampa.VectorSpace.VectorSpace (a, a, a, a, a) a


-- | 3D vector abstraction (R^3).
module FRP.Yampa.Vector3
data Vector3 a
vector3 :: RealFloat a => a -> a -> a -> Vector3 a
vector3X :: RealFloat a => Vector3 a -> a
vector3Y :: RealFloat a => Vector3 a -> a
vector3Z :: RealFloat a => Vector3 a -> a
vector3XYZ :: RealFloat a => Vector3 a -> (a, a, a)
vector3Spherical :: RealFloat a => a -> a -> a -> Vector3 a
vector3Rho :: RealFloat a => Vector3 a -> a
vector3Theta :: RealFloat a => Vector3 a -> a
vector3Phi :: RealFloat a => Vector3 a -> a
vector3RhoThetaPhi :: RealFloat a => Vector3 a -> (a, a, a)
vector3Rotate :: RealFloat a => a -> a -> Vector3 a -> Vector3 a
instance GHC.Classes.Eq a => GHC.Classes.Eq (FRP.Yampa.Vector3.Vector3 a)
instance GHC.Show.Show a => GHC.Show.Show (FRP.Yampa.Vector3.Vector3 a)
instance GHC.Float.RealFloat a => FRP.Yampa.VectorSpace.VectorSpace (FRP.Yampa.Vector3.Vector3 a) a
instance GHC.Float.RealFloat a => FRP.Yampa.Forceable.Forceable (FRP.Yampa.Vector3.Vector3 a)


-- | 2D vector abstraction (R^2).
module FRP.Yampa.Vector2
data Vector2 a
vector2 :: RealFloat a => a -> a -> Vector2 a
vector2X :: RealFloat a => Vector2 a -> a
vector2Y :: RealFloat a => Vector2 a -> a
vector2XY :: RealFloat a => Vector2 a -> (a, a)
vector2Polar :: RealFloat a => a -> a -> Vector2 a
vector2Rho :: RealFloat a => Vector2 a -> a
vector2Theta :: RealFloat a => Vector2 a -> a
vector2RhoTheta :: RealFloat a => Vector2 a -> (a, a)
vector2Rotate :: RealFloat a => a -> Vector2 a -> Vector2 a
instance GHC.Classes.Eq a => GHC.Classes.Eq (FRP.Yampa.Vector2.Vector2 a)
instance GHC.Show.Show a => GHC.Show.Show (FRP.Yampa.Vector2.Vector2 a)
instance GHC.Float.RealFloat a => FRP.Yampa.VectorSpace.VectorSpace (FRP.Yampa.Vector2.Vector2 a) a
instance GHC.Float.RealFloat a => FRP.Yampa.Forceable.Forceable (FRP.Yampa.Vector2.Vector2 a)


module FRP.Yampa.Integration

-- | Integration using the rectangle rule.
integral :: VectorSpace a s => SF a a

-- | "Immediate" integration (using the function's value at the current
--   time)
imIntegral :: VectorSpace a s => a -> SF a a
impulseIntegral :: VectorSpace a k => SF (a, Event a) a
count :: Integral b => SF (Event a) (Event b)

-- | A very crude version of a derivative. It simply divides the value
--   difference by the time difference. Use at your own risk.
derivative :: VectorSpace a s => SF a a
iterFrom :: (a -> a -> DTime -> b -> b) -> b -> SF a b


module FRP.Yampa.Time

-- | Outputs the time passed since the signal function instance was
--   started.
localTime :: SF a Time

-- | Alternative name for localTime.
time :: SF a Time


-- | Well-initialised loops
module FRP.Yampa.Loop

-- | Loop with an initial value for the signal being fed back.
loopPre :: c -> SF (a, c) (b, c) -> SF a b

-- | Loop by integrating the second value in the pair and feeding the
--   result back. Because the integral at time 0 is zero, this is always
--   well defined.
loopIntegral :: VectorSpace c s => SF (a, c) (b, c) -> SF a b


-- | Affine space type relation.
module FRP.Yampa.AffineSpace
class (Floating a, VectorSpace v a) => AffineSpace p v a | p -> v, v -> a
origin :: AffineSpace p v a => p
(.+^) :: AffineSpace p v a => p -> v -> p
(.-^) :: AffineSpace p v a => p -> v -> p
(.-.) :: AffineSpace p v a => p -> p -> v
distance :: AffineSpace p v a => p -> p -> a


-- | 3D point abstraction (R^3).
module FRP.Yampa.Point3
data Point3 a
Point3 :: !a -> !a -> !a -> Point3 a
point3X :: RealFloat a => Point3 a -> a
point3Y :: RealFloat a => Point3 a -> a
point3Z :: RealFloat a => Point3 a -> a
instance GHC.Classes.Eq a => GHC.Classes.Eq (FRP.Yampa.Point3.Point3 a)
instance GHC.Show.Show a => GHC.Show.Show (FRP.Yampa.Point3.Point3 a)
instance GHC.Float.RealFloat a => FRP.Yampa.AffineSpace.AffineSpace (FRP.Yampa.Point3.Point3 a) (FRP.Yampa.Vector3.Vector3 a) a
instance GHC.Float.RealFloat a => FRP.Yampa.Forceable.Forceable (FRP.Yampa.Point3.Point3 a)


-- | 2D point abstraction (R^2).
module FRP.Yampa.Point2
data Point2 a
Point2 :: !a -> !a -> Point2 a
point2X :: RealFloat a => Point2 a -> a
point2Y :: RealFloat a => Point2 a -> a
instance GHC.Classes.Eq a => GHC.Classes.Eq (FRP.Yampa.Point2.Point2 a)
instance GHC.Show.Show a => GHC.Show.Show (FRP.Yampa.Point2.Point2 a)
instance GHC.Float.RealFloat a => FRP.Yampa.AffineSpace.AffineSpace (FRP.Yampa.Point2.Point2 a) (FRP.Yampa.Vector2.Vector2 a) a
instance GHC.Float.RealFloat a => FRP.Yampa.Forceable.Forceable (FRP.Yampa.Point2.Point2 a)


-- | Basic geometrical abstractions.
module FRP.Yampa.Geometry


-- | Domain-specific language embedded in Haskell for programming hybrid
--   (mixed discrete-time and continuous-time) systems. Yampa is based on
--   the concepts of Functional Reactive Programming (FRP) and is
--   structured using arrow combinators.
--   
--   You can find examples, tutorials and documentation on Yampa here:
--   
--   <a>https://wiki.haskell.org/Yampa</a>
--   
--   <a>https://github.com/ivanperez-keera/Yampa/tree/master/examples</a>
--   
--   Structuring a hybrid system in Yampa is done based on two main
--   concepts:
--   
--   <ul>
--   <li>Signal Functions: <a>SF</a>. Yampa is based on the concept of
--   Signal Functions, which are functions from a typed input signal to a
--   typed output signal. Conceptually, signals are functions from Time to
--   Value, where time are the real numbers and, computationally, a very
--   dense approximation (Double) is used.</li>
--   <li>Events: <a>Event</a>. Values that may or may not occur (and would
--   probably occur rarely). It is often used for incoming network
--   messages, mouse clicks, etc. Events are used as values carried by
--   signals.</li>
--   </ul>
--   
--   A complete Yampa system is defined as one Signal Function from some
--   type <tt>a</tt> to a type <tt>b</tt>. The execution of this signal
--   transformer with specific input can be accomplished by means of two
--   functions: <a>reactimate</a> (which needs an initialization action, an
--   input sensing action and an actuation/consumer action and executes
--   until explicitly stopped), and <a>react</a> (which executes only one
--   cycle).
--   
--   This will be the last version of Yampa to include mergeable records,
--   point2 and point3, vector2 and vector3, and other auxiliary
--   definitions. The internals have now changed. Also, please let us know
--   if you see any problems with the new project structure.
--   
--   Main Yampa modules:
--   
--   <ul>
--   <li><a>FRP.Yampa</a> -- This exports all FRP-related functions</li>
--   <li><a>FRP.Yampa.Task</a></li>
--   </ul>
--   
--   Minimal Complete FRP Definition:
--   
--   <ul>
--   <li><a>FRP.Yampa.Core</a></li>
--   </ul>
--   
--   Different FRP aspects:
--   
--   <ul>
--   <li><a>FRP.Yampa.Basic</a></li>
--   <li><a>FRP.Yampa.Conditional</a></li>
--   <li><a>FRP.Yampa.Delays</a></li>
--   <li><a>FRP.Yampa.Event</a></li>
--   <li><a>FRP.Yampa.EventS</a> -- Event consuming/producing SFs. To be
--   renamed.</li>
--   <li><a>FRP.Yampa.Hybrid</a> -- Hybrid (discrete/continuous) SFs</li>
--   <li><a>FRP.Yampa.Integration</a></li>
--   <li><a>FRP.Yampa.Loop</a></li>
--   <li><a>FRP.Yampa.Random</a></li>
--   <li><a>FRP.Yampa.Scan</a></li>
--   <li><a>FRP.Yampa.Switches</a></li>
--   <li><a>FRP.Yampa.Time</a></li>
--   <li><a>FRP.Yampa.Simulation</a> -- Reactimation/evaluation</li>
--   </ul>
--   
--   Internals:
--   
--   <ul>
--   <li><a>FRP.Yampa.InternalCore</a> -- Module not exposed.</li>
--   </ul>
--   
--   Geometry:
--   
--   <ul>
--   <li><a>FRP.Yampa.Geometry</a></li>
--   <li><a>FRP.Yampa.AffineSpace</a></li>
--   <li><a>FRP.Yampa.VectorSpace</a></li>
--   <li><a>FRP.Yampa.Point2</a></li>
--   <li><a>FRP.Yampa.Point3</a></li>
--   <li><a>FRP.Yampa.Vector2</a></li>
--   <li><a>FRP.Yampa.Vector3</a></li>
--   </ul>
--   
--   Old legacy code:
--   
--   <ul>
--   <li><a>FRP.Yampa.Diagnostics</a></li>
--   <li><a>FRP.Yampa.Forceable</a></li>
--   <li><a>FRP.Yampa.Internals</a> -- No longer in use</li>
--   <li><a>FRP.Yampa.MergeableRecord</a></li>
--   <li><a>FRP.Yampa.Miscellany</a></li>
--   <li><a>FRP.Yampa.Utilities</a></li>
--   </ul>
module FRP.Yampa

-- | The class <a>RandomGen</a> provides a common interface to random
--   number generators.
class RandomGen g

-- | The <a>next</a> operation returns an <a>Int</a> that is uniformly
--   distributed in the range returned by <a>genRange</a> (including both
--   end points), and a new generator.
next :: RandomGen g => g -> (Int, g)

-- | The <a>genRange</a> operation yields the range of values returned by
--   the generator.
--   
--   It is required that:
--   
--   <ul>
--   <li>If <tt>(a,b) = <a>genRange</a> g</tt>, then <tt>a &lt;
--   b</tt>.</li>
--   <li><a>genRange</a> always returns a pair of defined <a>Int</a>s.</li>
--   </ul>
--   
--   The second condition ensures that <a>genRange</a> cannot examine its
--   argument, and hence the value it returns can be determined only by the
--   instance of <a>RandomGen</a>. That in turn allows an implementation to
--   make a single call to <a>genRange</a> to establish a generator's
--   range, without being concerned that the generator returned by (say)
--   <a>next</a> might have a different range to the generator passed to
--   <a>next</a>.
--   
--   The default definition spans the full range of <a>Int</a>.
genRange :: RandomGen g => g -> (Int, Int)

-- | The <a>split</a> operation allows one to obtain two distinct random
--   number generators. This is very useful in functional programs (for
--   example, when passing a random number generator down to recursive
--   calls), but very little work has been done on statistically robust
--   implementations of <a>split</a> ([<a>System.Random\#Burton</a>,
--   <a>System.Random\#Hellekalek</a>] are the only examples we know of).
split :: RandomGen g => g -> (g, g)

-- | With a source of random number supply in hand, the <a>Random</a> class
--   allows the programmer to extract random values of a variety of types.
--   
--   Minimal complete definition: <a>randomR</a> and <a>random</a>.
class Random a

-- | Takes a range <i>(lo,hi)</i> and a random number generator <i>g</i>,
--   and returns a random value uniformly distributed in the closed
--   interval <i>[lo,hi]</i>, together with a new generator. It is
--   unspecified what happens if <i>lo&gt;hi</i>. For continuous types
--   there is no requirement that the values <i>lo</i> and <i>hi</i> are
--   ever produced, but they may be, depending on the implementation and
--   the interval.
randomR :: (Random a, RandomGen g) => (a, a) -> g -> (a, g)

-- | The same as <a>randomR</a>, but using a default range determined by
--   the type:
--   
--   <ul>
--   <li>For bounded types (instances of <a>Bounded</a>, such as
--   <a>Char</a>), the range is normally the whole type.</li>
--   <li>For fractional types, the range is normally the semi-closed
--   interval <tt>[0,1)</tt>.</li>
--   <li>For <a>Integer</a>, the range is (arbitrarily) the range of
--   <a>Int</a>.</li>
--   </ul>
random :: (Random a, RandomGen g) => g -> (a, g)

-- | Plural variant of <a>randomR</a>, producing an infinite list of random
--   values instead of returning a new generator.
randomRs :: (Random a, RandomGen g) => (a, a) -> g -> [a]

-- | Plural variant of <a>random</a>, producing an infinite list of random
--   values instead of returning a new generator.
randoms :: (Random a, RandomGen g) => g -> [a]

-- | A variant of <a>randomR</a> that uses the global random number
--   generator (see <a>System.Random#globalrng</a>).
randomRIO :: Random a => (a, a) -> IO a

-- | A variant of <a>random</a> that uses the global random number
--   generator (see <a>System.Random#globalrng</a>).
randomIO :: Random a => IO a

-- | Time is used both for time intervals (duration), and time w.r.t. some
--   agreed reference point in time.
type Time = Double

-- | DTime is the time type for lengths of sample intervals. Conceptually,
--   DTime = R+ = { x in R | x &gt; 0 }. Don't assume Time and DTime have
--   the same representation.
type DTime = Double

-- | Signal function that transforms a signal carrying values of some type
--   <tt>a</tt> into a signal carrying values of some type <tt>b</tt>. You
--   can think of it as (Signal a -&gt; Signal b). A signal is,
--   conceptually, a function from <a>Time</a> to value.
data SF a b

-- | 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).
data Event a
NoEvent :: Event a
Event :: a -> Event a

-- | Lifts a pure function into a signal function (applied pointwise).
arrPrim :: (a -> b) -> SF a b

-- | Lifts a pure function into a signal function applied to events
--   (applied pointwise).
arrEPrim :: (Event a -> b) -> SF (Event a) b

-- | Identity: identity = arr id
--   
--   Using <a>identity</a> is preferred over lifting id, since the arrow
--   combinators know how to optimise certain networks based on the
--   transformations being applied.
identity :: SF a a

-- | Identity: constant b = arr (const b)
--   
--   Using <a>constant</a> is preferred over lifting const, since the arrow
--   combinators know how to optimise certain networks based on the
--   transformations being applied.
constant :: b -> SF a b

-- | Outputs the time passed since the signal function instance was
--   started.
localTime :: SF a Time

-- | Alternative name for localTime.
time :: SF a Time

-- | Initialization operator (cf. Lustre/Lucid Synchrone).
--   
--   The output at time zero is the first argument, and from that point on
--   it behaves like the signal function passed as second argument.
(-->) :: b -> SF a b -> SF a b
infixr 0 -->

-- | Output pre-insert operator.
--   
--   Insert a sample in the output, and from that point on, behave like the
--   given sf.
(-:>) :: b -> SF a b -> SF a b
infixr 0 -:>

-- | Input initialization operator.
--   
--   The input at time zero is the first argument, and from that point on
--   it behaves like the signal function passed as second argument.
(>--) :: a -> SF a b -> SF a b
infixr 0 >--

-- | Transform initial output value.
--   
--   Applies a transformation <tt>f</tt> only to the first output value at
--   time zero.
(-=>) :: (b -> b) -> SF a b -> SF a b
infixr 0 -=>

-- | Transform initial input value.
--   
--   Applies a transformation <tt>f</tt> only to the first input value at
--   time zero.
(>=-) :: (a -> a) -> SF a b -> SF a b
infixr 0 >=-

-- | Override initial value of input signal.
initially :: a -> SF a a
sscan :: (b -> a -> b) -> b -> SF a b
sscanPrim :: (c -> a -> Maybe (c, b)) -> c -> b -> SF a b

-- | Event source that never occurs.
never :: SF a (Event b)

-- | Event source with a single occurrence at time 0. The value of the
--   event is given by the function argument.
now :: b -> SF a (Event b)

-- | Event source with a single occurrence at or as soon after (local) time
--   <i>q</i> as possible.
after :: Time -> b -> SF a (Event b)

-- | Event source with repeated occurrences with interval q. Note: If the
--   interval is too short w.r.t. the sampling intervals, the result will
--   be that events occur at every sample. However, no more than one event
--   results from any sampling interval, thus avoiding an "event backlog"
--   should sampling become more frequent at some later point in time.
repeatedly :: Time -> b -> SF a (Event b)

-- | Event source with consecutive occurrences at the given intervals.
--   Should more than one event be scheduled to occur in any sampling
--   interval, only the first will in fact occur to avoid an event backlog.
afterEach :: [(Time, b)] -> SF a (Event b)

-- | Event source with consecutive occurrences at the given intervals.
--   Should more than one event be scheduled to occur in any sampling
--   interval, the output list will contain all events produced during that
--   interval.
afterEachCat :: [(Time, b)] -> SF a (Event [b])

-- | Delay for events. (Consider it a triggered after, hence <i>basic</i>.)
delayEvent :: Time -> SF (Event a) (Event a)

-- | Delay an event by a given delta and catenate events that occur so
--   closely so as to be <i>inseparable</i>.
delayEventCat :: Time -> SF (Event a) (Event [a])

-- | A rising edge detector. Useful for things like detecting key presses.
--   It is initialised as <i>up</i>, meaning that events occuring at time 0
--   will not be detected.
edge :: SF Bool (Event ())

-- | A rising edge detector that can be initialized as up (<a>True</a>,
--   meaning that events occurring at time 0 will not be detected) or down
--   (<a>False</a>, meaning that events ocurring at time 0 will be
--   detected).
iEdge :: Bool -> SF Bool (Event ())

-- | Like <a>edge</a>, but parameterized on the tag value.
edgeTag :: a -> SF Bool (Event a)

-- | Edge detector particularized for detecting transtitions on a
--   <a>Maybe</a> signal from <a>Nothing</a> to <a>Just</a>.
edgeJust :: SF (Maybe a) (Event a)

-- | Edge detector parameterized on the edge detection function and initial
--   state, i.e., the previous input sample. The first argument to the edge
--   detection function is the previous sample, the second the current one.
edgeBy :: (a -> a -> Maybe b) -> a -> SF a (Event b)

-- | Convert a maybe value into a event (<a>Event</a> is isomorphic to
--   <a>Maybe</a>).
maybeToEvent :: Maybe a -> Event a

-- | Suppression of initial (at local time 0) event.
notYet :: SF (Event a) (Event a)

-- | Suppress all but the first event.
once :: SF (Event a) (Event a)

-- | Suppress all but the first n events.
takeEvents :: Int -> SF (Event a) (Event a)

-- | Suppress first n events.
dropEvents :: Int -> SF (Event a) (Event a)

-- | Make the NoEvent constructor available. Useful e.g. for
--   initialization, ((--&gt;) &amp; friends), and it's easily available
--   anyway (e.g. mergeEvents []).
noEvent :: Event a

-- | Suppress any event in the first component of a pair.
noEventFst :: (Event a, b) -> (Event c, b)

-- | Suppress any event in the second component of a pair.
noEventSnd :: (a, Event b) -> (a, Event c)

-- | An event-based version of the maybe function.
event :: a -> (b -> a) -> Event b -> a

-- | Extract the value from an event. Fails if there is no event.
fromEvent :: Event a -> a

-- | Tests whether the input represents an actual event.
isEvent :: Event a -> Bool

-- | Negation of <a>isEvent</a>.
isNoEvent :: Event a -> Bool

-- | Tags an (occurring) event with a value ("replacing" the old value).
--   
--   Applicative-based definition: tag = ($&gt;)
tag :: Event a -> b -> Event b
infixl 8 `tag`

-- | Tags an (occurring) event with a value ("replacing" the old value).
--   Same as <a>tag</a> with the arguments swapped.
--   
--   Applicative-based definition: tagWith = (&lt;$)
tagWith :: b -> Event a -> Event b

-- | Attaches an extra value to the value of an occurring event.
attach :: Event a -> b -> Event (a, b)
infixl 8 `attach`

-- | Left-biased event merge (always prefer left event, if present).
lMerge :: Event a -> Event a -> Event a
infixl 6 `lMerge`

-- | Right-biased event merge (always prefer right event, if present).
rMerge :: Event a -> Event a -> Event a
infixl 6 `rMerge`

-- | Unbiased event merge: simultaneous occurrence is an error.
merge :: Event a -> Event a -> Event a
infixl 6 `merge`

-- | Event merge parameterized by a conflict resolution function.
--   
--   Applicative-based definition: mergeBy f le re = (f <a>$</a> le
--   <a>*</a> re) <a>|</a> le <a>|</a> re
mergeBy :: (a -> a -> a) -> Event a -> Event a -> Event a

-- | 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, <a>mergeBy</a> = <a>mapMerge</a> <a>id</a> <a>id</a>
--   
--   Applicative-based definition: mapMerge lf rf lrf le re = (f <a>$</a>
--   le <a>*</a> re) <a>|</a> (lf <a>$</a> le) <a>|</a> (rf <a>$</a> re)
mapMerge :: (a -> c) -> (b -> c) -> (a -> b -> c) -> Event a -> Event b -> Event c

-- | Merge a list of events; foremost event has priority.
--   
--   Foldable-based definition: mergeEvents :: Foldable t =&gt; t (Event a)
--   -&gt; Event a mergeEvents = asum
mergeEvents :: [Event a] -> Event a

-- | Collect simultaneous event occurrences; no event if none.
--   
--   Traverable-based definition: catEvents :: Foldable t =&gt; t (Event a)
--   -&gt; Event (t a) carEvents e = if (null e) then NoEvent else
--   (sequenceA e)
catEvents :: [Event a] -> Event [a]

-- | Join (conjunction) of two events. Only produces an event if both
--   events exist.
--   
--   Applicative-based definition: joinE = liftA2 (,)
joinE :: Event a -> Event b -> Event (a, b)
infixl 7 `joinE`

-- | Split event carrying pairs into two events.
splitE :: Event (a, b) -> (Event a, Event b)

-- | Filter out events that don't satisfy some predicate.
filterE :: (a -> Bool) -> Event a -> Event a

-- | Combined event mapping and filtering. Note: since <a>Event</a> is a
--   <a>Functor</a>, see <a>fmap</a> for a simpler version of this function
--   with no filtering.
mapFilterE :: (a -> Maybe b) -> Event a -> Event b

-- | Enable/disable event occurences based on an external condition.
gate :: Event a -> Bool -> Event a
infixl 8 `gate`

-- | 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!
switch :: SF a (b, Event c) -> (c -> SF a b) -> SF a b

-- | 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!
dSwitch :: SF a (b, Event c) -> (c -> SF a b) -> SF a b

-- | Recurring switch.
--   
--   See <a>https://wiki.haskell.org/Yampa#Switches</a> for more
--   information on how this switch works.
rSwitch :: SF a b -> SF (a, Event (SF a b)) b

-- | Recurring switch with delayed observation.
--   
--   See <a>https://wiki.haskell.org/Yampa#Switches</a> for more
--   information on how this switch works.
drSwitch :: SF a b -> SF (a, Event (SF a b)) b

-- | <a>Call-with-current-continuation</a> switch.
--   
--   See <a>https://wiki.haskell.org/Yampa#Switches</a> for more
--   information on how this switch works.
kSwitch :: SF a b -> SF (a, b) (Event c) -> (SF a b -> c -> SF a b) -> SF a b

-- | <a>kSwitch</a> with delayed observation.
--   
--   See <a>https://wiki.haskell.org/Yampa#Switches</a> for more
--   information on how this switch works.
dkSwitch :: SF a b -> SF (a, b) (Event c) -> (SF a b -> c -> SF a b) -> SF a b

-- | Spatial parallel composition of a signal function collection. Given a
--   collection of signal functions, it returns a signal function that
--   <a>broadcast</a>s its input signal to every element of the collection,
--   to return a signal carrying a collection of outputs. See <a>par</a>.
--   
--   For more information on how parallel composition works, check
--   <a>http://haskell.cs.yale.edu/wp-content/uploads/2011/01/yampa-arcade.pdf</a>
parB :: Functor col => col (SF a b) -> SF a (col b)

-- | Parallel switch (dynamic collection of signal functions spatially
--   composed in parallel). See <a>pSwitch</a>.
--   
--   For more information on how parallel composition works, check
--   <a>http://haskell.cs.yale.edu/wp-content/uploads/2011/01/yampa-arcade.pdf</a>
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)

-- | Delayed parallel switch with broadcasting (dynamic collection of
--   signal functions spatially composed in parallel). See <a>dpSwitch</a>.
--   
--   For more information on how parallel composition works, check
--   <a>http://haskell.cs.yale.edu/wp-content/uploads/2011/01/yampa-arcade.pdf</a>
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)
rpSwitchB :: Functor col => col (SF a b) -> SF (a, Event (col (SF a b) -> col (SF a b))) (col b)
drpSwitchB :: Functor col => col (SF a b) -> SF (a, Event (col (SF a b) -> col (SF a b))) (col b)

-- | Spatial parallel composition of a signal function collection
--   parameterized on the routing function.
par :: Functor col => (forall sf. (a -> col sf -> col (b, sf))) -> col (SF b c) -> 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.
pSwitch :: Functor col => (forall sf. (a -> col sf -> col (b, sf))) -> col (SF b c) -> SF (a, col c) (Event d) -> (col (SF b c) -> d -> SF a (col c)) -> 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 <a>dpSwitch</a> 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.
dpSwitch :: Functor col => (forall sf. (a -> col sf -> col (b, sf))) -> col (SF b c) -> SF (a, col c) (Event d) -> (col (SF b c) -> d -> SF a (col c)) -> SF a (col c)
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)
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)

-- | Zero-order hold.
hold :: a -> SF (Event a) a

-- | Zero-order hold with delay.
--   
--   Identity: dHold a0 = hold a0 &gt;&gt;&gt; iPre a0).
dHold :: a -> SF (Event a) a

-- | Tracks input signal when available, holds last value when disappears.
--   
--   !!! DANGER!!! Event used inside arr! Probably OK because arr will not
--   be !!! optimized to arrE. But still. Maybe rewrite this using, say,
--   scan? !!! or switch? Switching (in hold) for every input sample does
--   not !!! seem like such a great idea anyway.
trackAndHold :: a -> SF (Maybe a) a

-- | Given an initial value in an accumulator, it returns a signal function
--   that processes an event carrying transformation functions. Every time
--   an <a>Event</a> is received, the function inside it is applied to the
--   accumulator, whose new value is outputted in an <a>Event</a>.
accum :: a -> SF (Event (a -> a)) (Event a)

-- | Zero-order hold accumulator (always produces the last outputted value
--   until an event arrives).
accumHold :: a -> SF (Event (a -> a)) a

-- | Zero-order hold accumulator with delayed initialization (always
--   produces the last outputted value until an event arrives, but the very
--   initial output is always the given accumulator).
dAccumHold :: a -> SF (Event (a -> a)) a

-- | Accumulator parameterized by the accumulation function.
accumBy :: (b -> a -> b) -> b -> SF (Event a) (Event b)

-- | Zero-order hold accumulator parameterized by the accumulation
--   function.
accumHoldBy :: (b -> a -> b) -> b -> SF (Event a) b

-- | Zero-order hold accumulator parameterized by the accumulation function
--   with delayed initialization (initial output sample is always the given
--   accumulator).
dAccumHoldBy :: (b -> a -> b) -> b -> SF (Event a) b

-- | Accumulator parameterized by the accumulator function with filtering,
--   possibly discarding some of the input events based on whether the
--   second component of the result of applying the accumulation function
--   is <a>Nothing</a> or <a>Just</a> x for some x.
accumFilter :: (c -> a -> (c, Maybe b)) -> c -> SF (Event a) (Event b)

-- | Uninitialized delay operator.
pre :: SF a a

-- | Initialized delay operator.
iPre :: a -> SF a a

-- | Delay a signal by a fixed time <tt>t</tt>, using the second parameter
--   to fill in the initial <tt>t</tt> seconds.
delay :: Time -> a -> SF a a

-- | Given a value in an accumulator (b), a predicate signal function
--   (sfC), and a second signal function (sf), pause will produce the
--   accumulator b if sfC input is True, and will transform the signal
--   using sf otherwise. It acts as a pause with an accumulator for the
--   moments when the transformation is paused.
pause :: b -> SF a Bool -> SF a b -> SF a b

-- | Loop with an initial value for the signal being fed back.
loopPre :: c -> SF (a, c) (b, c) -> SF a b

-- | Loop by integrating the second value in the pair and feeding the
--   result back. Because the integral at time 0 is zero, this is always
--   well defined.
loopIntegral :: VectorSpace c s => SF (a, c) (b, c) -> SF a b

-- | Integration using the rectangle rule.
integral :: VectorSpace a s => SF a a

-- | "Immediate" integration (using the function's value at the current
--   time)
imIntegral :: VectorSpace a s => a -> SF a a
impulseIntegral :: VectorSpace a k => SF (a, Event a) a
count :: Integral b => SF (Event a) (Event b)

-- | A very crude version of a derivative. It simply divides the value
--   difference by the time difference. Use at your own risk.
derivative :: VectorSpace a s => SF a a
iterFrom :: (a -> a -> DTime -> b -> b) -> b -> SF a b

-- | Noise (random signal) with default range for type in question; based
--   on "randoms".
noise :: (RandomGen g, Random b) => g -> SF a b

-- | Noise (random signal) with specified range; based on "randomRs".
noiseR :: (RandomGen g, Random b) => (b, b) -> g -> SF a b

-- | Stochastic event source with events occurring on average once every
--   t_avg seconds. However, no more than one event results from any one
--   sampling interval in the case of relatively sparse sampling, thus
--   avoiding an "event backlog" should sampling become more frequent at
--   some later point in time.
occasionally :: RandomGen g => g -> Time -> b -> SF a (Event b)

-- | Convenience function to run a signal function indefinitely, using a IO
--   actions to obtain new input and process the output.
--   
--   This function first runs the initialization action, which provides the
--   initial input for the signal transformer at time 0.
--   
--   Afterwards, an input sensing action is used to obtain new input (if
--   any) and the time since the last iteration. The argument to the input
--   sensing function indicates if it can block. If no new input is
--   received, it is assumed to be the same as in the last iteration.
--   
--   After applying the signal function to the input, the actuation IO
--   action is executed. The first argument indicates if the output has
--   changed, the second gives the actual output). Actuation functions may
--   choose to ignore the first argument altogether. This action should
--   return True if the reactimation must stop, and False if it should
--   continue.
--   
--   Note that this becomes the program's <i>main loop</i>, which makes
--   using this function incompatible with GLUT, Gtk and other graphics
--   libraries. It may also impose a sizeable constraint in larger projects
--   in which different subparts run at different time steps. If you need
--   to control the main loop yourself for these or other reasons, use
--   <a>reactInit</a> and <a>react</a>.
reactimate :: Monad m => m a -> (Bool -> m (DTime, Maybe a)) -> (Bool -> b -> m Bool) -> SF a b -> m ()

-- | A reference to reactimate's state, maintained across samples.
type ReactHandle a b = IORef (ReactState a b)

-- | Initialize a top-level reaction handle.
reactInit :: IO a -> (ReactHandle a b -> Bool -> b -> IO Bool) -> SF a b -> IO (ReactHandle a b)

-- | Process a single input sample.
react :: ReactHandle a b -> (DTime, Maybe a) -> IO Bool

-- | Given a signal function and a pair with an initial input sample for
--   the input signal, and a list of sampling times, possibly with new
--   input samples at those times, it produces a list of output samples.
--   
--   This is a simplified, purely-functional version of <a>reactimate</a>.
embed :: SF a b -> (a, [(DTime, Maybe a)]) -> [b]

-- | Synchronous embedding. The embedded signal function is run on the
--   supplied input and time stream at a given (but variable) ratio &gt;= 0
--   to the outer time flow. When the ratio is 0, the embedded signal
--   function is paused.
embedSynch :: SF a b -> (a, [(DTime, Maybe a)]) -> SF Double b

-- | Spaces a list of samples by a fixed time delta, avoiding unnecessary
--   samples when the input has not changed since the last sample.
deltaEncode :: Eq a => DTime -> [a] -> (a, [(DTime, Maybe a)])

-- | <a>deltaEncode</a> parameterized by the equality test.
deltaEncodeBy :: (a -> a -> Bool) -> DTime -> [a] -> (a, [(DTime, Maybe a)])

-- | <i>Deprecated: Use Control.Arrow.(&gt;&gt;&gt;) and
--   Control.Arrow.(&lt;&lt;&lt;).</i>
(#) :: (a -> b) -> (b -> c) -> (a -> c)
infixl 9 #
dup :: a -> (a, a)


-- | Task abstraction on top of signal transformers.
module FRP.Yampa.Task
data Task a b c
mkTask :: SF a (b, Event c) -> Task a b c
runTask :: Task a b c -> SF a (Either b c)
runTask_ :: Task a b c -> SF a b
taskToSF :: Task a b c -> SF a (b, Event c)
constT :: b -> Task a b c
sleepT :: Time -> b -> Task a b ()
snapT :: Task a b a
timeOut :: Task a b c -> Time -> Task a b (Maybe c)
infixl 0 `timeOut`
abortWhen :: Task a b c -> SF a (Event d) -> Task a b (Either c d)
infixl 0 `abortWhen`
repeatUntil :: Monad m => m a -> (a -> Bool) -> m a
infixl 0 `repeatUntil`
for :: Monad m => a -> (a -> a) -> (a -> Bool) -> m b -> m ()
forAll :: Monad m => [a] -> (a -> m b) -> m ()
forEver :: Monad m => m a -> m b
instance GHC.Base.Functor (FRP.Yampa.Task.Task a b)
instance GHC.Base.Applicative (FRP.Yampa.Task.Task a b)
instance GHC.Base.Monad (FRP.Yampa.Task.Task a b)

module FRP.Yampa.Core

-- | Signal function that transforms a signal carrying values of some type
--   <tt>a</tt> into a signal carrying values of some type <tt>b</tt>. You
--   can think of it as (Signal a -&gt; Signal b). A signal is,
--   conceptually, a function from <a>Time</a> to value.
data SF a b

-- | Initialized delay operator.
iPre :: a -> SF a a

-- | Lift a function to an arrow.
arr :: Arrow a => forall b c. () => (b -> c) -> a b c

-- | Left-to-right composition
(>>>) :: Category k cat => cat a b -> cat b c -> cat a c
infixr 1 >>>

-- | Send the first component of the input through the argument arrow, and
--   copy the rest unchanged to the output.
first :: Arrow a => forall b c d. () => a b c -> a (b, d) (c, d)
loop :: ArrowLoop a => forall b d c. () => a (b, d) (c, d) -> a b c

-- | Integration using the rectangle rule.
integral :: VectorSpace a s => SF a 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).
data Event a
NoEvent :: Event a
Event :: a -> Event a

-- | 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!
switch :: SF a (b, Event c) -> (c -> SF a b) -> SF a b

-- | Time is used both for time intervals (duration), and time w.r.t. some
--   agreed reference point in time.
type Time = Double

-- | Alternative name for localTime.
time :: SF a Time


-- | Derived utility definitions.
--   
--   ToDo:
--   
--   <ul>
--   <li>Possibly add impulse :: VectorSpace a k =&gt; a -&gt; Event a But
--   to do that, we need access to Event, which we currently do not
--   have.</li>
--   <li>The general arrow utilities should be moved to a module
--   FRP.Yampa.Utilities.</li>
--   <li>I'm not sure structuring the Yampa "core" according to what is
--   core functionality and what's not is all that useful. There are many
--   cases where we want to implement combinators that fairly easily could
--   be implemented in terms of others as primitives simply because we
--   expect that that implementation is going to be much more efficient,
--   and that the combinators are used sufficiently often to warrant doing
--   this. E.g. <a>switch</a> should be a primitive, even though it could
--   be derived from <tt>pSwitch</tt>.</li>
--   <li>Reconsider <a>recur</a>. If an event source has an immediate
--   occurrence, we'll get into a loop. For example: recur now. Maybe
--   suppress initial occurrences? Initial occurrences are rather pointless
--   in this case anyway.</li>
--   </ul>
module FRP.Yampa.Utilities

-- | Window sampling
--   
--   First argument is the window length wl, second is the sampling
--   interval t. The output list should contain (min (truncate (T/t) wl))
--   samples, where T is the time the signal function has been running.
--   This requires some care in case of sparse sampling. In case of sparse
--   sampling, the current input value is assumed to have been present at
--   all points where sampling was missed.
sampleWindow :: Int -> Time -> SF a (Event [a])
