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


-- | A minimalistic FRP library
--   
--   Elerea (Eventless reactivity) is a tiny discrete time FRP
--   implementation without the notion of event-based switching and
--   sampling, with first-class signals (time-varying values). Reactivity
--   is provided through various higher-order constructs that also allow
--   the user to work with arbitrary time-varying structures containing
--   live signals. Signals have precise and simple denotational semantics.
--   
--   Stateful signals can be safely generated at any time through a monadic
--   interface, while stateless combinators can be used in a purely
--   applicative style. Elerea signals can be defined recursively, and
--   external input is trivial to attach. The library comes in two major
--   variants:
--   
--   <ul>
--   <li>Simple: signals are plain discrete streams isomorphic to functions
--   over natural numbers;</li>
--   <li>Param: adds a globally accessible input signal for
--   convenience;</li>
--   </ul>
--   
--   This is a minimal library that defines only some basic primitives, and
--   you are advised to install <tt>elerea-examples</tt> as well to get an
--   idea how to build non-trivial systems with it. The examples are
--   separated in order to minimise the dependencies of the core library.
--   The <tt>dow</tt> package contains a full game built on top of the
--   simple variant.
--   
--   The basic idea of the implementation is described in the WFLP 2010
--   paper <i>Efficient and Compositional Higher-Order Streams</i>
--   (<a>http://sgate.emt.bme.hu/documents/patai/publications/PataiWFLP2010.pdf</a>).
--   
--   Additional contributions: Takano Akio, Mitsutoshi Aoe
@package elerea
@version 2.9.0


-- | Elerea (Eventless reactivity) is a tiny discrete time FRP
--   implementation without the notion of event-based switching and
--   sampling, with first-class signals (time-varying values). Reactivity
--   is provided through various higher-order constructs that also allow
--   the user to work with arbitrary time-varying structures containing
--   live signals. Signals have precise and simple denotational semantics.
--   
--   Stateful signals can be safely generated at any time through a monadic
--   interface, while stateless combinators can be used in a purely
--   applicative style. Elerea signals can be defined recursively, and
--   external input is trivial to attach. The library comes in two major
--   variants, one of which you need to import:
--   
--   <ul>
--   <li><a>FRP.Elerea.Simple</a>: signals are plain discrete streams
--   isomorphic to functions over natural numbers;</li>
--   <li><a>FRP.Elerea.Param</a>: adds a globally accessible input signal
--   for convenience;</li>
--   </ul>
--   
--   Elerea is a minimal library that defines only some basic primitives,
--   and you are advised to install <tt>elerea-examples</tt> as well to get
--   an idea how to build non-trivial systems with it. The examples are
--   separated in order to minimise the dependencies of the core library.
--   The <tt>dow</tt> package contains a full game built on top of the
--   simple variant.
--   
--   The basic idea of the implementation is described in the WFLP 2010
--   paper <i>Efficient and Compositional Higher-Order Streams</i>
--   (<a>http://sgate.emt.bme.hu/documents/patai/publications/PataiWFLP2010.pdf</a>).
--   
--   In short, the basic idea is to define completely dynamic data-flow
--   networks through a pure combinator-style monadic interface. The
--   network can be turned into an I/O action that samples it sequentially
--   by the <tt>start</tt> function. Under the hood, the network is
--   represented by mutable variables whose interconnections are
--   encapsulated in closures, and consistency is ensured by a two-phase
--   update process (essentially double buffering). The library keeps track
--   of the variables through weak pointers, so all of the live variables
--   can be updated (this is necessary to ensure referential transparency),
--   and unused ones can be garbage collected.
module FRP.Elerea


-- | This module provides leak-free and referentially transparent
--   higher-order discrete signals. Unlike in <a>FRP.Elerea.Simple</a>, the
--   sampling action has an extra argument that will be globally
--   distributed to every node and can be used to update the state. For
--   instance, it can hold the time step between the two samplings, but it
--   could also encode all the external input to the system.
module FRP.Elerea.Param

-- | A signal represents a value changing over time. It can be thought of
--   as a function of type <tt>Nat -&gt; a</tt>, where the argument is the
--   sampling time, and the <a>Monad</a> instance agrees with the intuition
--   (bind corresponds to extracting the current sample). Signals and the
--   values they carry are denoted the following way in the documentation:
--   
--   <pre>
--   s = &lt;&lt;s0 s1 s2 ...&gt;&gt;
--   </pre>
--   
--   This says that <tt>s</tt> is a signal that reads <tt>s0</tt> during
--   the first sampling, <tt>s1</tt> during the second and so on. You can
--   also think of <tt>s</tt> as the following function:
--   
--   <pre>
--   s t_sample = [s0,s1,s2,...] !! t_sample
--   </pre>
--   
--   Signals are constrained to be sampled sequentially, there is no random
--   access. The only way to observe their output is through <a>start</a>.
data Signal a

-- | A signal generator is the only source of stateful signals. It can be
--   thought of as a function of type <tt>Nat -&gt; Signal p -&gt; a</tt>,
--   where the result is an arbitrary data structure that can potentially
--   contain new signals, the first argument is the creation time of these
--   new signals, and the second is a globally accessible input signal. It
--   exposes the <a>MonadFix</a> interface, which makes it possible to
--   define signals in terms of each other. Unlike the simple variant, the
--   denotation of signal generators differs from that of signals. We will
--   use the following notation for generators:
--   
--   <pre>
--   g = &lt;|g0 g1 g2 ...|&gt;
--   </pre>
--   
--   Just like signals, generators behave as functions of time, but they
--   can also refer to the input signal:
--   
--   <pre>
--   g t_start s_input = [g0,g1,g2,...] !! t_start
--   </pre>
--   
--   The conceptual difference between the two notions is that signals are
--   passed a sampling time, while generators expect a start time that will
--   be the creation time of all the freshly generated signals in the
--   resulting structure.
data SignalGen p a

-- | Embedding a signal into an <a>IO</a> environment. Repeated calls to
--   the computation returned cause the whole network to be updated, and
--   the current sample of the top-level signal is produced as a result.
--   The computation accepts a global parameter that will be distributed to
--   all signals. For instance, this can be the time step, if we want to
--   model continuous-time signals. This is the only way to extract a
--   signal generator outside the network, and it is equivalent to passing
--   zero to the function representing the generator.
--   
--   Example:
--   
--   <pre>
--   do
--       smp &lt;- start (stateful 10 (+))
--       res &lt;- forM [5,3,2,9,4] smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [10,15,18,20,29]
--   </pre>
start :: SignalGen p (Signal a) -> IO (p -> IO a)

-- | A signal that can be directly fed through the sink function returned.
--   This can be used to attach the network to the outer world. The signal
--   always yields the value last written to the sink at the start of the
--   superstep. In other words, if the sink is written less frequently than
--   the network sampled, the output remains the same during several
--   samples. If values are pushed in the sink more frequently, only the
--   last one before sampling is visible on the output.
external :: a -> IO (SignalGen p (Signal a), a -> IO ())

-- | An event-like signal that can be fed through the sink function
--   returned. The signal carries a list of values fed in since the last
--   sampling, i.e. it is constantly [] if the sink is never invoked. The
--   order of elements is reversed, so the last value passed to the sink is
--   the head of the list.
externalMulti :: IO (SignalGen p (Signal [a]), a -> IO ())

-- | A signal that can be directly fed through the sink function returned.
--   This can be used to attach the network to the outer world. Note that
--   this is optional, as all the input of the network can be fed in
--   through the global parameter, although that is not really convenient
--   for many signals.
--   
--   As for why this construct is unsafe, consult the explanation for the
--   equivalent in <a>FRP.Elerea.Simple</a>.
unsafeExternal :: a -> IO (Signal a, a -> IO ())

-- | The <a>delay</a> combinator is the elementary building block for
--   adding state to the signal network by constructing delayed versions of
--   a signal that emit a given value at creation time and the previous
--   output of the signal afterwards (<tt>--</tt> is undefined):
--   
--   <pre>
--   delay x0 s = &lt;| &lt;&lt;x0 s0 s1 s2 s3 ...&gt;&gt;
--                   &lt;&lt;-- x0 s1 s2 s3 ...&gt;&gt;
--                   &lt;&lt;-- -- x0 s2 s3 ...&gt;&gt;
--                   &lt;&lt;-- -- -- x0 s3 ...&gt;&gt;
--                   ...
--                |&gt;
--   </pre>
--   
--   It can be thought of as the following function (which should also make
--   it clear why the return value is <a>SignalGen</a>):
--   
--   <pre>
--   delay x0 s t_start s_input t_sample
--     | t_start == t_sample = x0
--     | t_start &lt; t_sample  = s (t_sample-1)
--     | otherwise           = error \"Premature sample!\"
--   </pre>
--   
--   The way signal generators are extracted by <a>generator</a> ensures
--   that the error can never happen. It is also clear that the behaviour
--   of <a>delay</a> is not affected in any way by the global input.
--   
--   Example (requires the <tt>DoRec</tt> extension):
--   
--   <pre>
--   do
--       smp &lt;- start $ do
--           rec let fib'' = liftA2 (+) fib' fib
--               fib' &lt;- delay 1 fib''
--               fib &lt;- delay 1 fib'
--           return fib
--       res &lt;- replicateM 7 (smp undefined)
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [1,1,2,3,5,8,13]
--   </pre>
delay :: a -> Signal a -> SignalGen p (Signal a)

-- | A formal conversion from signals to signal generators, which
--   effectively allows for retrieving the current value of a previously
--   created signal within a generator. This includes both signals defined
--   in an external scope as well as those created earlier in the same
--   generator. It can be modelled by the following function:
--   
--   <pre>
--   snapshot s t_start s_input = s t_start
--   </pre>
snapshot :: Signal a -> SignalGen p a

-- | A reactive signal that takes the value to output from a signal
--   generator carried by its input with the sampling time provided as the
--   start time for the generated structure. It is possible to create new
--   signals in the monad, which is the key to defining dynamic data-flow
--   networks.
--   
--   <pre>
--   generator &lt;&lt; &lt;|x00 x01 x02 ...|&gt;
--                &lt;|x10 x11 x12 ...|&gt;
--                &lt;|x20 x21 x22 ...|&gt;
--                ...
--             &gt;&gt; = &lt;| &lt;&lt;x00 x11 x22 ...&gt;&gt;
--                     &lt;&lt;x00 x11 x22 ...&gt;&gt;
--                     &lt;&lt;x00 x11 x22 ...&gt;&gt;
--                     ...
--                  |&gt;
--   </pre>
--   
--   It can be thought of as the following function:
--   
--   <pre>
--   generator g t_start s_input t_sample = g t_sample t_sample s_input
--   </pre>
--   
--   It has to live in the <a>SignalGen</a> monad, because it needs to
--   maintain an internal state to be able to cache the current sample for
--   efficiency reasons. However, this state is not carried between
--   samples, therefore start time doesn't matter and can be ignored. Also,
--   even though it does not make use of the global input itself, part of
--   its job is to distribute it among the newly generated signals.
--   
--   Refer to the longer example at the bottom of <a>FRP.Elerea.Simple</a>
--   to see how it can be used.
generator :: Signal (SignalGen p a) -> SignalGen p (Signal a)

-- | Memoising combinator. It can be used to cache results of applicative
--   combinators in case they are used in several places. It is
--   observationally equivalent to <a>return</a> in the <a>SignalGen</a>
--   monad.
--   
--   <pre>
--   memo s = &lt;|s s s s ...|&gt;
--   </pre>
--   
--   For instance, if <tt>s = f &lt;$&gt; s'</tt>, then <tt>f</tt> will be
--   recalculated once for each sampling of <tt>s</tt>. This can be avoided
--   by writing <tt>s &lt;- memo (f &lt;$&gt; s')</tt> instead. However,
--   <a>memo</a> incurs a small overhead, therefore it should not be used
--   blindly.
--   
--   All the functions defined in this module return memoised signals. Just
--   like <a>delay</a>, it is independent of the global input.
memo :: Signal a -> SignalGen p (Signal a)

-- | A signal that is true exactly once: the first time the input signal is
--   true. Afterwards, it is constantly false, and it holds no reference to
--   the input signal. For instance (assuming the rest of the input is
--   constantly <tt>False</tt>):
--   
--   <pre>
--   till &lt;&lt;False False True True False True ...&gt;&gt; =
--       &lt;| &lt;&lt;False False True  False False False False False False False ...&gt;&gt;
--          &lt;&lt; ---  False True  False False False False False False False ...&gt;&gt;
--          &lt;&lt; ---   ---  True  False False False False False False False ...&gt;&gt;
--          &lt;&lt; ---   ---   ---  True  False False False False False False ...&gt;&gt;
--          &lt;&lt; ---   ---   ---   ---  False True  False False False False ...&gt;&gt;
--          &lt;&lt; ---   ---   ---   ---   ---  True  False False False False ...&gt;&gt;
--          &lt;&lt; ---   ---   ---   ---   ---   ---  False False False False ...&gt;&gt;
--          ...
--       |&gt;
--   </pre>
--   
--   It is observationally equivalent to the following expression (which
--   would hold onto <tt>s</tt> forever):
--   
--   <pre>
--   till s = do
--       step &lt;- transfer False (const (||)) s
--       dstep &lt;- delay False step
--       memo (liftA2 (/=) step dstep)
--   </pre>
--   
--   Example:
--   
--   <pre>
--   do
--       smp &lt;- start $ do
--           accum &lt;- stateful 0 (+)
--           tick &lt;- till ((&gt;=10) &lt;$&gt; accum)
--           return $ liftA2 (,) accum tick
--       res &lt;- forM [4,1,3,5,2,8,6] smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [(0,False),(4,False),(5,False),(8,False),(13,True),(15,False),(23,False)]
--   </pre>
till :: Signal Bool -> SignalGen p (Signal Bool)

-- | The common input signal that is fed through the function returned by
--   <a>start</a>, unless we are in an <a>embed</a>ded generator. It is
--   equivalent to the following function:
--   
--   <pre>
--   input t_start s_input = s_input
--   </pre>
--   
--   Example:
--   
--   <pre>
--   do
--       smp &lt;- start $ do
--           sig &lt;- input
--           return (sig*2)
--       res &lt;- forM [4,1,3,5,2,8,6] smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [8,2,6,10,4,16,12]
--   </pre>
input :: SignalGen p (Signal p)

-- | Embed a generator with an overridden input signal. It is equivalent to
--   the following function:
--   
--   <pre>
--   embed s g t_start s_input = g t_start s
--   </pre>
--   
--   Example:
--   
--   <pre>
--   do
--       smp &lt;- start $ do
--           sig &lt;- input
--           embed (sig*2) $ do
--               sig &lt;- input
--               return (sig+1)
--       res &lt;- forM [4,1,3,5,2,8,6] smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [9,3,7,11,5,17,13]
--   </pre>
embed :: Signal p' -> SignalGen p' a -> SignalGen p a

-- | A direct stateful transformation of the input. The initial state is
--   the first output, and every following output is calculated from the
--   previous one and the value of the global parameter (which might have
--   been overridden by <a>embed</a>).
--   
--   Example:
--   
--   <pre>
--   do
--       smp &lt;- start (stateful "" (:))
--       res &lt;- forM "olleh~" smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   ["","o","lo","llo","ello","hello"]
--   </pre>
stateful :: a -> (p -> a -> a) -> SignalGen p (Signal a)

-- | A stateful transfer function. The current input affects the current
--   output, i.e. the initial state given in the first argument is
--   considered to appear before the first output, and can never be
--   observed. Every output is derived from the current value of the input
--   signal, the global parameter (which might have been overridden by
--   <a>embed</a>) and the previous output. It is equivalent to the
--   following expression:
--   
--   Example (assuming a delta time is passed to the sampling function in
--   each step):
--   
--   <pre>
--   integral x0 s = transfer x0 (\dt v x -&gt; x+dt*v)
--   </pre>
--   
--   Example for using the above:
--   
--   <pre>
--   do
--       smp &lt;- start (integral 3 (pure 2))
--       res &lt;- replicateM 7 (smp 0.1)
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [3.2,3.4,3.6,3.8,4.0,4.2,4.4]
--   </pre>
transfer :: a -> (p -> t -> a -> a) -> Signal t -> SignalGen p (Signal a)

-- | A variation of <a>transfer</a> with two input signals.
transfer2 :: a -> (p -> t1 -> t2 -> a -> a) -> Signal t1 -> Signal t2 -> SignalGen p (Signal a)

-- | A variation of <a>transfer</a> with three input signals.
transfer3 :: a -> (p -> t1 -> t2 -> t3 -> a -> a) -> Signal t1 -> Signal t2 -> Signal t3 -> SignalGen p (Signal a)

-- | A variation of <a>transfer</a> with four input signals.
transfer4 :: a -> (p -> t1 -> t2 -> t3 -> t4 -> a -> a) -> Signal t1 -> Signal t2 -> Signal t3 -> Signal t4 -> SignalGen p (Signal a)

-- | An IO action executed in the <a>SignalGen</a> monad. Can be used as
--   <a>liftIO</a>.
execute :: IO a -> SignalGen p a

-- | A signal that executes a given IO action once at every sampling.
--   
--   In essence, this combinator provides cooperative multitasking
--   capabilities, and its primary purpose is to assist library writers in
--   wrapping effectful APIs as conceptually pure signals. If there are
--   several effectful signals in the system, their order of execution is
--   undefined and should not be relied on.
--   
--   Example:
--   
--   <pre>
--   do
--       act &lt;- start $ do
--           ref &lt;- execute $ newIORef 0
--           let accum n = do
--                   x &lt;- readIORef ref
--                   putStrLn $ "Accumulator: " ++ show x
--                   writeIORef ref $! x+n
--                   return ()
--           effectful1 accum =&lt;&lt; input
--       forM_ [4,9,2,1,5] act
--   </pre>
--   
--   Output:
--   
--   <pre>
--   Accumulator: 0
--   Accumulator: 4
--   Accumulator: 13
--   Accumulator: 15
--   Accumulator: 16
--   </pre>
--   
--   Another example (requires mersenne-random):
--   
--   <pre>
--   do
--       smp &lt;- start $ effectful randomIO :: IO (IO Double)
--       res &lt;- replicateM 5 smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [0.12067753390401374,0.8658877349182655,0.7159264443196786,0.1756941896012891,0.9513646060896676]
--   </pre>
effectful :: IO a -> SignalGen p (Signal a)

-- | A signal that executes a parametric IO action once at every sampling.
--   The parameter is supplied by another signal at every sampling step.
effectful1 :: (t -> IO a) -> Signal t -> SignalGen p (Signal a)

-- | Like <a>effectful1</a>, but with two parameter signals.
effectful2 :: (t1 -> t2 -> IO a) -> Signal t1 -> Signal t2 -> SignalGen p (Signal a)

-- | Like <a>effectful1</a>, but with three parameter signals.
effectful3 :: (t1 -> t2 -> t3 -> IO a) -> Signal t1 -> Signal t2 -> Signal t3 -> SignalGen p (Signal a)

-- | Like <a>effectful1</a>, but with four parameter signals.
effectful4 :: (t1 -> t2 -> t3 -> t4 -> IO a) -> Signal t1 -> Signal t2 -> Signal t3 -> Signal t4 -> SignalGen p (Signal a)
instance GHC.Base.Monad FRP.Elerea.Param.Signal
instance GHC.Base.Applicative FRP.Elerea.Param.Signal
instance GHC.Base.Functor FRP.Elerea.Param.Signal
instance GHC.Base.Functor (FRP.Elerea.Param.SignalGen p)
instance GHC.Base.Applicative (FRP.Elerea.Param.SignalGen p)
instance GHC.Base.Monad (FRP.Elerea.Param.SignalGen p)
instance Control.Monad.Fix.MonadFix (FRP.Elerea.Param.SignalGen p)
instance Control.Monad.IO.Class.MonadIO (FRP.Elerea.Param.SignalGen p)
instance Control.Monad.Base.MonadBase (FRP.Elerea.Param.SignalGen p) (FRP.Elerea.Param.SignalGen p)
instance GHC.Show.Show (FRP.Elerea.Param.Signal a)
instance GHC.Classes.Eq (FRP.Elerea.Param.Signal a)
instance GHC.Classes.Ord t => GHC.Classes.Ord (FRP.Elerea.Param.Signal t)
instance GHC.Enum.Enum t => GHC.Enum.Enum (FRP.Elerea.Param.Signal t)
instance GHC.Enum.Bounded t => GHC.Enum.Bounded (FRP.Elerea.Param.Signal t)
instance GHC.Num.Num t => GHC.Num.Num (FRP.Elerea.Param.Signal t)
instance GHC.Real.Real t => GHC.Real.Real (FRP.Elerea.Param.Signal t)
instance GHC.Real.Integral t => GHC.Real.Integral (FRP.Elerea.Param.Signal t)
instance GHC.Real.Fractional t => GHC.Real.Fractional (FRP.Elerea.Param.Signal t)
instance GHC.Float.Floating t => GHC.Float.Floating (FRP.Elerea.Param.Signal t)


-- | This module provides leak-free and referentially transparent
--   higher-order discrete signals.
module FRP.Elerea.Simple

-- | A signal represents a value changing over time. It can be thought of
--   as a function of type <tt>Nat -&gt; a</tt>, where the argument is the
--   sampling time, and the <a>Monad</a> instance agrees with the intuition
--   (bind corresponds to extracting the current sample). Signals and the
--   values they carry are denoted the following way in the documentation:
--   
--   <pre>
--   s = &lt;&lt;s0 s1 s2 ...&gt;&gt;
--   </pre>
--   
--   This says that <tt>s</tt> is a signal that reads <tt>s0</tt> during
--   the first sampling, <tt>s1</tt> during the second and so on. You can
--   also think of <tt>s</tt> as the following function:
--   
--   <pre>
--   s t_sample = [s0,s1,s2,...] !! t_sample
--   </pre>
--   
--   Signals are constrained to be sampled sequentially, there is no random
--   access. The only way to observe their output is through <a>start</a>.
data Signal a

-- | A signal generator is the only source of stateful signals. It can be
--   thought of as a function of type <tt>Nat -&gt; a</tt>, where the
--   result is an arbitrary data structure that can potentially contain new
--   signals, and the argument is the creation time of these new signals.
--   It exposes the <a>MonadFix</a> interface, which makes it possible to
--   define signals in terms of each other. The denotation of signal
--   generators happens to be the same as that of signals, but this partly
--   accidental (it does not hold in the other variants), so we will use a
--   separate notation for generators:
--   
--   <pre>
--   g = &lt;|g0 g1 g2 ...|&gt;
--   </pre>
--   
--   Just like signals, generators behave as functions of time:
--   
--   <pre>
--   g t_start = [g0,g1,g2,...] !! t_start
--   </pre>
--   
--   The conceptual difference between the two notions is that signals are
--   passed a sampling time, while generators expect a start time that will
--   be the creation time of all the freshly generated signals in the
--   resulting structure.
data SignalGen a

-- | Embedding a signal into an <a>IO</a> environment. Repeated calls to
--   the computation returned cause the whole network to be updated, and
--   the current sample of the top-level signal is produced as a result.
--   This is the only way to extract a signal generator outside the
--   network, and it is equivalent to passing zero to the function
--   representing the generator. In general:
--   
--   <pre>
--   replicateM n =&lt;&lt; start &lt;|&lt;&lt;x0 x1 x2 x3 ...&gt;&gt; ...|&gt; == take n [x0,x1,x2,x3,...]
--   </pre>
--   
--   Example:
--   
--   <pre>
--   do
--       smp &lt;- start (stateful 3 (+2))
--       res &lt;- replicateM 5 smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [3,5,7,9,11]
--   </pre>
start :: SignalGen (Signal a) -> IO (IO a)

-- | A signal that can be directly fed through the sink function returned.
--   This can be used to attach the network to the outer world. The signal
--   always yields the value last written to the sink at the start of the
--   superstep. In other words, if the sink is written less frequently than
--   the network sampled, the output remains the same during several
--   samples. If values are pushed in the sink more frequently, only the
--   last one before sampling is visible on the output.
--   
--   Example:
--   
--   <pre>
--   do
--       (gen,snk) &lt;- external 4
--       smp &lt;- start gen
--       r1 &lt;- smp
--       r2 &lt;- smp
--       snk 7
--       r3 &lt;- smp
--       snk 9
--       snk 2
--       r4 &lt;- smp
--       print [r1,r2,r3,r4]
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [4,4,7,2]
--   </pre>
external :: a -> IO (SignalGen (Signal a), a -> IO ())

-- | An event-like signal that can be fed through the sink function
--   returned. The signal carries a list of values fed in since the last
--   sampling, i.e. it is constantly <tt>[]</tt> if the sink is never
--   invoked. The order of elements is reversed, so the last value passed
--   to the sink is the head of the list.
--   
--   Example:
--   
--   <pre>
--   do
--       (gen,snk) &lt;- externalMulti
--       smp &lt;- start gen
--       r1 &lt;- smp
--       snk 7
--       r2 &lt;- smp
--       r3 &lt;- smp
--       snk 9
--       snk 2
--       r4 &lt;- smp
--       print [r1,r2,r3,r4]
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [[],[7],[],[2,9]]
--   </pre>
externalMulti :: IO (SignalGen (Signal [a]), a -> IO ())

-- | A signal that can be directly fed through the sink function returned.
--   This can be used to attach the network to the outer world. The signal
--   always yields the value last written to the sink. In other words, if
--   the sink is written less frequently than the network sampled, the
--   output remains the same during several samples. If values are pushed
--   in the sink more frequently, only the last one before sampling is
--   visible on the output.
--   
--   Example:
--   
--   <pre>
--   do
--       (sig,snk) &lt;- unsafeExternal 4
--       smp &lt;- start (return sig)
--       r1 &lt;- smp
--       r2 &lt;- smp
--       snk 7
--       r3 &lt;- smp
--       snk 9
--       snk 2
--       r4 &lt;- smp
--       print [r1,r2,r3,r4]
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [4,4,7,2]
--   </pre>
--   
--   There are two reasons why this construct is deemed unsafe. Firstly, if
--   the sink is used from another thread several times during the sampling
--   process, the observed value of the signal might be inconsistent within
--   a superstep. More interestingly, this unmanaged channel can interact
--   with <a>snapshot</a> in strange ways. See
--   <a>https://github.com/cobbpg/elerea/issues/9</a> for some examples.
--   
--   Note: this function used to be called <tt>external</tt> up until
--   version 2.8.0.
unsafeExternal :: a -> IO (Signal a, a -> IO ())

-- | The <a>delay</a> combinator is the elementary building block for
--   adding state to the signal network by constructing delayed versions of
--   a signal that emit a given value at creation time and the previous
--   output of the signal afterwards (<tt>--</tt> is undefined):
--   
--   <pre>
--   delay x0 s = &lt;| &lt;&lt;x0 s0 s1 s2 s3 ...&gt;&gt;
--                   &lt;&lt;-- x0 s1 s2 s3 ...&gt;&gt;
--                   &lt;&lt;-- -- x0 s2 s3 ...&gt;&gt;
--                   &lt;&lt;-- -- -- x0 s3 ...&gt;&gt;
--                   ...
--                |&gt;
--   </pre>
--   
--   It can be thought of as the following function (which should also make
--   it clear why the return value is <a>SignalGen</a>):
--   
--   <pre>
--   delay x0 s t_start t_sample
--     | t_start == t_sample = x0
--     | t_start &lt; t_sample  = s (t_sample-1)
--     | otherwise           = error \"Premature sample!\"
--   </pre>
--   
--   The way signal generators are extracted by <a>generator</a> ensures
--   that the error can never happen.
--   
--   Example (requires the <tt>DoRec</tt> extension):
--   
--   <pre>
--   do
--       smp &lt;- start $ do
--           rec let fib'' = liftA2 (+) fib' fib
--               fib' &lt;- delay 1 fib''
--               fib &lt;- delay 1 fib'
--           return fib
--       res &lt;- replicateM 7 smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [1,1,2,3,5,8,13]
--   </pre>
delay :: a -> Signal a -> SignalGen (Signal a)

-- | A formal conversion from signals to signal generators, which
--   effectively allows for retrieving the current value of a previously
--   created signal within a generator. This includes both signals defined
--   in an external scope as well as those created earlier in the same
--   generator. In the model, it corresponds to the identity function.
snapshot :: Signal a -> SignalGen a

-- | A reactive signal that takes the value to output from a signal
--   generator carried by its input with the sampling time provided as the
--   start time for the generated structure. It is possible to create new
--   signals in the monad, which is the key to defining dynamic data-flow
--   networks.
--   
--   <pre>
--   generator &lt;&lt; &lt;|x00 x01 x02 ...|&gt;
--                &lt;|x10 x11 x12 ...|&gt;
--                &lt;|x20 x21 x22 ...|&gt;
--                ...
--             &gt;&gt; = &lt;| &lt;&lt;x00 x11 x22 ...&gt;&gt;
--                     &lt;&lt;x00 x11 x22 ...&gt;&gt;
--                     &lt;&lt;x00 x11 x22 ...&gt;&gt;
--                     ...
--                  |&gt;
--   </pre>
--   
--   It can be thought of as the following function:
--   
--   <pre>
--   generator g t_start t_sample = g t_sample t_sample
--   </pre>
--   
--   It has to live in the <a>SignalGen</a> monad, because it needs to
--   maintain an internal state to be able to cache the current sample for
--   efficiency reasons. However, this state is not carried between
--   samples, therefore start time doesn't matter and can be ignored.
--   
--   Refer to the longer example at the bottom to see how it can be used.
generator :: Signal (SignalGen a) -> SignalGen (Signal a)

-- | Memoising combinator. It can be used to cache results of applicative
--   combinators in case they are used in several places. It is
--   observationally equivalent to <a>return</a> in the <a>SignalGen</a>
--   monad.
--   
--   <pre>
--   memo s = &lt;|s s s s ...|&gt;
--   </pre>
--   
--   For instance, if <tt>s = f &lt;$&gt; s'</tt>, then <tt>f</tt> will be
--   recalculated once for each sampling of <tt>s</tt>. This can be avoided
--   by writing <tt>s &lt;- memo (f &lt;$&gt; s')</tt> instead. However,
--   <a>memo</a> incurs a small overhead, therefore it should not be used
--   blindly.
--   
--   All the functions defined in this module return memoised signals.
memo :: Signal a -> SignalGen (Signal a)

-- | A signal that is true exactly once: the first time the input signal is
--   true. Afterwards, it is constantly false, and it holds no reference to
--   the input signal. For instance (assuming the rest of the input is
--   constantly <tt>False</tt>):
--   
--   <pre>
--   till &lt;&lt;False False True True False True ...&gt;&gt; =
--       &lt;| &lt;&lt;False False True  False False False False False False False ...&gt;&gt;
--          &lt;&lt; ---  False True  False False False False False False False ...&gt;&gt;
--          &lt;&lt; ---   ---  True  False False False False False False False ...&gt;&gt;
--          &lt;&lt; ---   ---   ---  True  False False False False False False ...&gt;&gt;
--          &lt;&lt; ---   ---   ---   ---  False True  False False False False ...&gt;&gt;
--          &lt;&lt; ---   ---   ---   ---   ---  True  False False False False ...&gt;&gt;
--          &lt;&lt; ---   ---   ---   ---   ---   ---  False False False False ...&gt;&gt;
--          ...
--       |&gt;
--   </pre>
--   
--   It is observationally equivalent to the following expression (which
--   would hold onto <tt>s</tt> forever):
--   
--   <pre>
--   till s = do
--       step &lt;- transfer False (||) s
--       dstep &lt;- delay False step
--       memo (liftA2 (/=) step dstep)
--   </pre>
--   
--   Example:
--   
--   <pre>
--   do
--       smp &lt;- start $ do
--           cnt &lt;- stateful 0 (+1)
--           tick &lt;- till ((&gt;=3) &lt;$&gt; cnt)
--           return $ liftA2 (,) cnt tick
--       res &lt;- replicateM 6 smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [(0,False),(1,False),(2,False),(3,True),(4,False),(5,False)]
--   </pre>
till :: Signal Bool -> SignalGen (Signal Bool)

-- | A pure stateful signal. The initial state is the first output, and
--   every subsequent state is derived from the preceding one by applying a
--   pure transformation.
--   
--   Example:
--   
--   <pre>
--   do
--       smp &lt;- start (stateful "x" ('x':))
--       res &lt;- replicateM 5 smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   ["x","xx","xxx","xxxx","xxxxx"]
--   </pre>
stateful :: a -> (a -> a) -> SignalGen (Signal a)

-- | A stateful transfer function. The current input affects the current
--   output, i.e. the initial state given in the first argument is
--   considered to appear before the first output, and can never be
--   observed, and subsequent states are determined by combining the
--   preceding state with the current output of the input signal using the
--   function supplied.
--   
--   Example:
--   
--   <pre>
--   do
--       smp &lt;- start $ do
--           cnt &lt;- stateful 1 (+1)
--           transfer 10 (+) cnt
--       res &lt;- replicateM 5 smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [11,13,16,20,25]
--   </pre>
transfer :: a -> (t -> a -> a) -> Signal t -> SignalGen (Signal a)

-- | A variation of <a>transfer</a> with two input signals.
transfer2 :: a -> (t1 -> t2 -> a -> a) -> Signal t1 -> Signal t2 -> SignalGen (Signal a)

-- | A variation of <a>transfer</a> with three input signals.
transfer3 :: a -> (t1 -> t2 -> t3 -> a -> a) -> Signal t1 -> Signal t2 -> Signal t3 -> SignalGen (Signal a)

-- | A variation of <a>transfer</a> with four input signals.
transfer4 :: a -> (t1 -> t2 -> t3 -> t4 -> a -> a) -> Signal t1 -> Signal t2 -> Signal t3 -> Signal t4 -> SignalGen (Signal a)

-- | An IO action executed in the <a>SignalGen</a> monad. Can be used as
--   <a>liftIO</a>.
execute :: IO a -> SignalGen a

-- | A signal that executes a given IO action once at every sampling.
--   
--   In essence, this combinator provides cooperative multitasking
--   capabilities, and its primary purpose is to assist library writers in
--   wrapping effectful APIs as conceptually pure signals. If there are
--   several effectful signals in the system, their order of execution is
--   undefined and should not be relied on.
--   
--   Example:
--   
--   <pre>
--   do
--       smp &lt;- start $ do
--           ref &lt;- execute $ newIORef 0
--           effectful $ do
--               x &lt;- readIORef ref
--               putStrLn $ "Count: " ++ show x
--               writeIORef ref $! x+1
--               return ()
--       replicateM_ 5 smp
--   </pre>
--   
--   Output:
--   
--   <pre>
--   Count: 0
--   Count: 1
--   Count: 2
--   Count: 3
--   Count: 4
--   </pre>
--   
--   Another example (requires mersenne-random):
--   
--   <pre>
--   do
--       smp &lt;- start $ effectful randomIO :: IO (IO Double)
--       res &lt;- replicateM 5 smp
--       print res
--   </pre>
--   
--   Output:
--   
--   <pre>
--   [0.12067753390401374,0.8658877349182655,0.7159264443196786,0.1756941896012891,0.9513646060896676]
--   </pre>
effectful :: IO a -> SignalGen (Signal a)

-- | A signal that executes a parametric IO action once at every sampling.
--   The parameter is supplied by another signal at every sampling step.
effectful1 :: (t -> IO a) -> Signal t -> SignalGen (Signal a)

-- | Like <a>effectful1</a>, but with two parameter signals.
effectful2 :: (t1 -> t2 -> IO a) -> Signal t1 -> Signal t2 -> SignalGen (Signal a)

-- | Like <a>effectful1</a>, but with three parameter signals.
effectful3 :: (t1 -> t2 -> t3 -> IO a) -> Signal t1 -> Signal t2 -> Signal t3 -> SignalGen (Signal a)

-- | Like <a>effectful1</a>, but with four parameter signals.
effectful4 :: (t1 -> t2 -> t3 -> t4 -> IO a) -> Signal t1 -> Signal t2 -> Signal t3 -> Signal t4 -> SignalGen (Signal a)
instance GHC.Base.Monad FRP.Elerea.Simple.Signal
instance GHC.Base.Applicative FRP.Elerea.Simple.Signal
instance GHC.Base.Functor FRP.Elerea.Simple.Signal
instance GHC.Base.Functor FRP.Elerea.Simple.SignalGen
instance GHC.Base.Applicative FRP.Elerea.Simple.SignalGen
instance GHC.Base.Monad FRP.Elerea.Simple.SignalGen
instance Control.Monad.Fix.MonadFix FRP.Elerea.Simple.SignalGen
instance Control.Monad.IO.Class.MonadIO FRP.Elerea.Simple.SignalGen
instance Control.Monad.Base.MonadBase FRP.Elerea.Simple.SignalGen FRP.Elerea.Simple.SignalGen
instance GHC.Show.Show (FRP.Elerea.Simple.Signal a)
instance GHC.Classes.Eq (FRP.Elerea.Simple.Signal a)
instance GHC.Classes.Ord t => GHC.Classes.Ord (FRP.Elerea.Simple.Signal t)
instance GHC.Enum.Enum t => GHC.Enum.Enum (FRP.Elerea.Simple.Signal t)
instance GHC.Enum.Bounded t => GHC.Enum.Bounded (FRP.Elerea.Simple.Signal t)
instance GHC.Num.Num t => GHC.Num.Num (FRP.Elerea.Simple.Signal t)
instance GHC.Real.Real t => GHC.Real.Real (FRP.Elerea.Simple.Signal t)
instance GHC.Real.Integral t => GHC.Real.Integral (FRP.Elerea.Simple.Signal t)
instance GHC.Real.Fractional t => GHC.Real.Fractional (FRP.Elerea.Simple.Signal t)
instance GHC.Float.Floating t => GHC.Float.Floating (FRP.Elerea.Simple.Signal t)


-- | This module contains the reference implementation for the pure subset
--   of the simple variant of Elerea. I/O embedding is substituted by
--   conversion from and to lists.
module FRP.Elerea.Simple.Pure
type Signal a = Int -> a
type SignalGen a = Int -> a
fromList :: [a] -> Signal a
toList :: Signal a -> [a]
start :: SignalGen (Signal a) -> [a]
delay :: a -> Signal a -> SignalGen (Signal a)
snapshot :: Signal a -> SignalGen a
generator :: Signal (SignalGen a) -> SignalGen (Signal a)
memo :: Signal a -> SignalGen (Signal a)

-- | <tt><a>until</a> p f</tt> yields the result of applying <tt>f</tt>
--   until <tt>p</tt> holds.
until :: () => (a -> Bool) -> (a -> a) -> a -> a
stateful :: a -> (a -> a) -> SignalGen (Signal a)
transfer :: a -> (t -> a -> a) -> Signal t -> SignalGen (Signal a)
transfer2 :: a -> (t1 -> t2 -> a -> a) -> Signal t1 -> Signal t2 -> SignalGen (Signal a)
transfer3 :: a -> (t1 -> t2 -> t3 -> a -> a) -> Signal t1 -> Signal t2 -> Signal t3 -> SignalGen (Signal a)
transfer4 :: a -> (t1 -> t2 -> t3 -> t4 -> a -> a) -> Signal t1 -> Signal t2 -> Signal t3 -> Signal t4 -> SignalGen (Signal a)
