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


-- | Denotative, locally stateful programming DSL & platform
--   
--   (Up to date documentation is maintained at
--   <a>https://mstksg.github.com/auto</a>)
--   
--   Read the README first!
--   <a>https://github.com/mstksg/auto/blob/master/README.md</a> , for
--   motivating examples, and concrete explanations of things described
--   here.
--   
--   <i>auto</i> is a Haskell DSL and platform providing declarative,
--   compositional, denotative semantics for discrete-step, locally
--   stateful, interactive programs, games, and automations, with
--   implicitly derived serialization. It is suited for any domain where
--   either the input or the output can be described as a stream of values:
--   a stream of input events, output views, etc.
--   
--   <i>auto</i> works by providing a type that encapsulates "value stream
--   transformers", or locally stateful functions; by specifying your
--   program as a (potentially cyclic) graph of relationships between value
--   streams, you create a way of "declaring" a system based simply on
--   static relationships between quantities.
--   
--   Instead of a "state monad" type solution, where all functions have
--   access to a rigid global state, <i>auto</i> works by specifying
--   relationships which each exist independently and on their own, without
--   any global state.
--   
--   A more fuller exposition is in the <a>README.md</a>, in this project
--   directory and also online at
--   <a>https://github.com/mstksg/auto/blob/master/README.md</a>; you can
--   get started by reading the tutorial, which is also in this project
--   directory in the <a>tutorial</a> directory, and also incidentally
--   online at
--   <a>https://github.com/mstksg/auto/blob/master/tutorial/tutorial.md</a>.
--   Also, check out the <a>auto-examples</a> repository on github for
--   plenty of real-world and toy examples to learn from; I've also done a
--   <a>blog series</a> on this library, with examples and full tutorials!
--   
--   Support available on freenode's #haskell-auto, #haskell-game, and also
--   on the github issue tracker for the source repository.
--   
--   Import <a>Control.Auto</a> to begin!
@package auto
@version 0.4.3.1


-- | This module exposes an "unsafe" interface for working with the
--   internal representation of "blip streams". If you are programming at
--   the logic level or the application level, you should thoroughly be
--   able to avoid importing this, and should be happy with importing the
--   <a>Blip</a> type from <a>Control.Auto</a> and blip stream manipulators
--   from <a>Control.Auto.Blip</a>.
--   
--   If, however, you are programming a framework, library, or backend, you
--   might find it useful to manually create your own blip streams/sources.
--   In this case, this module will be useful.
--   
--   It is important, as with most of this library in general, to always
--   keep in mind when you are programming at the "logic" level, and when
--   you are programming at the "backend" level. If you can justify that
--   you are at the backend level and not at the logic level of whatever
--   you are programming, then this is useful.
--   
--   Be sure, of course, that whatever blip streams you do manually
--   construct and export preserve "Blip semantics", which is further
--   defined in <a>Control.Auto.Blip</a>.
--   
--   You have been warned!
module Control.Auto.Blip.Internal

-- | When used in the context of an input or output of an <tt>Auto</tt>, a
--   <tt><a>Blip</a> a</tt> represents a stream that occasionally, at
--   "independent" or "discrete" points, emits a value of type <tt>a</tt>.
--   
--   Contrast this to <tt>Interval</tt>, where things are meant to be "on"
--   or "off" for contiguous chunks at a time; blip streams are "blippy",
--   and <tt>Interval</tt>s are "chunky".
--   
--   It's here mainly because it's a pretty useful abstraction in the
--   context of the many combinators found in various modules of this
--   library. If you think of an <tt><tt>Auto</tt> m a (<a>Blip</a> b)</tt>
--   as producing a "blip stream", then there are various combinators and
--   functions that are specifically designed to manipulate blip streams.
--   
--   For the purposes of the semantics of what <a>Blip</a> is supposed to
--   represent, its constructors are hidden. (Almost) all of the various
--   <a>Blip</a> combinators (and its very useful <a>Functor</a> instance)
--   "preserve <a>Blip</a>ness" --- one-at-a-time occurrences remain
--   one-at-a-time under all of these combinators, and you should have
--   enough so that direct access to the constructor is not needed.
--   
--   If you are creating a framework, library, or backend, you might want
--   to manually create blip stream-producing <tt>Auto</tt>s for your users
--   to access. In this case, you can import the constructors and useful
--   internal (and, of course, semantically unsafe) functions from
--   <a>Control.Auto.Blip.Internal</a>.
data Blip a
NoBlip :: Blip a
Blip :: !a -> Blip a

-- | Merge two blip streams together; the result emits with <i>either</i>
--   of the two merged streams emit. When both emit at the same time, emit
--   the result of applying the given function on the two emitted values.
--   
--   Note that this might be too strict for some purposes; see
--   <a>mergeL</a> and <a>mergeR</a> for lazier alternatives.
merge :: (a -> a -> a) -> Blip a -> Blip a -> Blip a

-- | Slightly more powerful <a>merge</a>, but I can't imagine a situation
--   where this power is necessary.
--   
--   If only the first stream emits, emit with the first function applied
--   to the value. If only the second stream emits, emit with the second
--   function applied to the value. If both emit, then emit with the third
--   function applied to both emitted values.
merge' :: (a -> c) -> (b -> c) -> (a -> b -> c) -> Blip a -> Blip b -> Blip c

-- | Merges two blip streams together into one, which emits <i>either</i>
--   of the original blip streams emit. If both emit at the same time, the
--   left (first) one is favored.
--   
--   Lazy on the second stream if the first stream is emitting.
--   
--   If we discount laziness, this is <tt><a>merge</a> <a>const</a></tt>.
mergeL :: Blip a -> Blip a -> Blip a
infixr 5 `mergeL`

-- | Merges two blip streams together into one, which emits <i>either</i>
--   of the original blip streams emit. If both emit at the same time, the
--   right (second) one is favored.
--   
--   Lazy on the first stream if the second stream is emitting.
--   
--   If we discount laziness, this is <tt><a>merge</a> (<a>flip</a>
--   <a>const</a>)</tt>.
mergeR :: Blip a -> Blip a -> Blip a
infixl 5 `mergeR`

-- | Deconstruct a <a>Blip</a> by giving a default result if the
--   <a>Blip</a> is non-occuring and a function to apply on the contents,
--   if the <a>Blip</a> is occuring.
--   
--   Try not to use if possible, unless you are a framework developer. If
--   you're just making an application, try to use the other various
--   combinators in this library. It'll help you preserve the semantics of
--   what it means to be <a>Blip</a>py.
--   
--   Analogous to <a>maybe</a> from <a>Prelude</a>.
blip :: b -> (a -> b) -> Blip a -> b
instance GHC.Generics.Generic (Control.Auto.Blip.Internal.Blip a)
instance GHC.Show.Show a => GHC.Show.Show (Control.Auto.Blip.Internal.Blip a)
instance GHC.Base.Functor Control.Auto.Blip.Internal.Blip
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Control.Auto.Blip.Internal.Blip a)
instance GHC.Base.Semigroup a => GHC.Base.Monoid (Control.Auto.Blip.Internal.Blip a)
instance Data.Serialize.Serialize a => Data.Serialize.Serialize (Control.Auto.Blip.Internal.Blip a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Control.Auto.Blip.Internal.Blip a)


-- | This module defines and provides the core types, (smart) constructors,
--   and general high and low-level utilities used by the <i>auto</i>
--   library.
--   
--   Note that importing and using functions from this module in part voids
--   some of the "semantic contracts" of the <a>Auto</a> types you get, so
--   use with caution!
--   
--   A lot of low-level functionality is provided here which is most likely
--   unnecessary for most applications; many are mostly for internal usage
--   or advanced/fine-grained usage. It also isn't really enough to do too
--   many useful things, either. It's recommended that you import
--   <a>Control.Auto</a> instead, which re-organizes the more useful parts
--   of this module in addition with useful parts of others to provide a
--   nice packaged entry point. If something in here becomes useful for
--   more than just fine-tuning or low-level tweaking, it is probably
--   supposed to be in <a>Control.Auto</a> anyway.
--   
--   Information on how to use these types is available in the
--   <a>tutorial</a>!
module Control.Auto.Core

-- | The <a>Auto</a> type. For this library, an <a>Auto</a> semantically
--   represents<i>denotes a </i>a relationship/ between an input and an
--   output that is preserved over multiple steps, where that relationship
--   is (optionally) maintained within the context of a monad.
--   
--   A lot of fancy words, I know...but you can think of an <a>Auto</a> as
--   nothing more than a "stream transformer" of value streams. A stream of
--   sequential input values come in one at a time, and a stream of outputs
--   pop out one at a time, as well.
--   
--   Using the <tt>streamAuto</tt> function, you can "unwrap" the inner
--   value stream transformer from any <a>Auto</a>: if <tt>a :: <a>Auto</a>
--   m a b</tt>, <tt>streamAuto</tt> lets you turn it into an <tt>[a] -&gt;
--   m [b]</tt>. "Give me a stream of <tt>a</tt>s, one at a time, and I'll
--   give you a list of <tt>b</tt>s, matching a relationship to your stream
--   of <tt>a</tt>s."
--   
--   <pre>
--   -- unwrap your inner [a] -&gt; m [b]!
--   <tt>streamAuto</tt> :: Monad m =&gt; <a>Auto</a> m a b -&gt; ([a] -&gt; m [b])
--   </pre>
--   
--   You can also turn an <tt><a>Auto</a> m a b</tt> into an <i>effects
--   stream</i> that executes effects sequentially with
--   <tt>toEffectStream</tt> and <tt>streamAutoEffects</tt>, so you can run
--   it with a ListT-compatible library like <i>pipes</i>.
--   
--   There's a handy type synonym <a>Auto'</a> for relationships that don't
--   really need a monadic context; the <tt>m</tt> is just <a>Identity</a>:
--   
--   <pre>
--   type Auto' = Auto Identity
--   </pre>
--   
--   So if you had an <tt>a :: <a>Auto'</a> a b</tt>, you can use
--   <tt>streamAuto'</tt> to "unwrap" the inner stream transformer, <tt>[a]
--   -&gt; [b]</tt>.
--   
--   <pre>
--   -- unwrap your inner [a] -&gt; [b]!
--   <tt>streamAuto'</tt> :: <a>Auto'</a> a b -&gt; ([a] -&gt; [b])
--   </pre>
--   
--   All of the <a>Auto</a>s given in this library maintain some sort of
--   semantic relationship between streams --- for some, the outputs might
--   be the inputs with a function applied; for others, the outputs might
--   be the cumulative sum of the inputs.
--   
--   See the <a>tutorial</a> for more information!
--   
--   Operationally, an <tt><a>Auto</a> m a b</tt> is implemented as a
--   "stateful function". A function from an <tt>a</tt> where, every time
--   you "apply" it, you get a <tt>b</tt> and an "updated
--   <a>Auto</a>"/function with updated state.
--   
--   You can get this function using <a>stepAuto</a>:
--   
--   <pre>
--   <a>stepAuto</a> :: <a>Auto</a> m a b -&gt; (a -&gt; m (b, <a>Auto</a> m a b))
--   </pre>
--   
--   Or, for <a>Auto'</a>, <a>stepAuto'</a>:
--   
--   <pre>
--   <a>stepAuto'</a> :: <a>Auto'</a> a b -&gt; (a -&gt; (b, <a>Auto'</a> a b))
--   </pre>
--   
--   "Give me an <tt>a</tt> and I'll give you a <tt>b</tt> and your
--   "updated" <a>Auto</a>".
--   
--   <a>Auto</a>s really are mostly useful because they can be composed,
--   chained, and modified using their various typeclass instances, like
--   <a>Category</a>, <a>Applicative</a>, <a>Functor</a>, <a>Arrow</a>,
--   etc., and also with the combinators in this library. You can build
--   complex programs as a complex <a>Auto</a> by building up smaller and
--   smaller components. See the tutorial for more information on this.
--   
--   This type also contains information on its own serialization, so you
--   can serialize and re-load the internal state to binary or disk. See
--   the "serialization" section in the documentation for
--   <a>Control.Auto.Core</a>, or the documentation for <a>mkAutoM</a> for
--   more details.
data Auto m a b

-- | Special case of <a>Auto</a> where the underlying <a>Monad</a> is
--   <a>Identity</a>.
--   
--   Instead of "wrapping" an <tt>[a] -&gt; m [b]</tt>, it "wraps" an
--   <tt>[a] -&gt; [b]</tt>.
type Auto' = Auto Identity

-- | Returns a string representation of the internal constructor of the
--   <a>Auto</a>. Useful for debugging the result of compositions and
--   functions and seeing how they affect the internal structure of the
--   <a>Auto</a>.
--   
--   In the order of efficiency, <a>AutoFunc</a>s tend to be faster than
--   <a>AutoState</a>s tend to be faster than <a>AutoArb</a>s. However,
--   when composing one with the other (using <a>Category</a> or
--   <a>Applicative</a>), the two have to be "reduced" to the greatest
--   common denominator; composing an <a>AutoFunc</a> with an
--   <a>AutoArb</a> produces an <a>AutoArb</a>.
--   
--   More benchmarking is to be done to be able to rigorously say what
--   these really mean, performance wise.
autoConstr :: Auto m a b -> String

-- | Re-structure <a>Auto</a> internals to use the <tt>Arb</tt>
--   ("arbitrary") constructors, as recursion-based mealy machines.
--   
--   Mostly here for performance comparisons and benchmarking purposes.
toArb :: Monad m => Auto m a b -> Auto m a b

-- | In theory, "purifying" an <a>Auto'</a>" should prep it for faster
--   evaluation when used with <a>stepAuto'</a> or <tt>streamAuto'</tt>.
--   But the benchmarks have not been run yet, so stay tuned!
--   
--   TODO: Benchmark
purifyAuto :: Auto' a b -> Auto' a b

-- | <a>Runs</a> the <a>Auto</a> through one step.
--   
--   That is, given an <tt><a>Auto</a> m a b</tt>, returns a function that
--   takes an <tt>a</tt> and returns a <tt>b</tt> and an "updated"/"next"
--   <a>Auto</a>; an <tt>a -&gt; m (b, <a>Auto</a> m a b)</tt>.
--   
--   This is the main way of running an <a>Auto</a> "step by step", so if
--   you have some sort of game loop that updates everything every "tick",
--   this is what you're looking for. At every loop, gather input
--   <tt>a</tt>, feed it into the <a>Auto</a>, "render" the result
--   <tt>b</tt>, and get your new <a>Auto</a> to run the next time.
--   
--   Here is an example with <tt><tt>sumFrom</tt> 0</tt>, the <a>Auto</a>
--   whose output is the cumulative sum of the inputs, and an underying
--   monad of <tt>Identity</tt>. Here,
--   
--   <pre>
--   stepAuto :: Auto Identity Int Int
--            -&gt; (Int -&gt; Identity (Int, Auto Identity Int Int))
--   </pre>
--   
--   Every time you "step", you give it an <a>Int</a> and get a resulting
--   <a>Int</a> (the cumulative sum) and the "updated <a>Auto</a>", with
--   the updated accumulator.
--   
--   <pre>
--   &gt;&gt;&gt; let a0 :: Auto Identity Int Int
--           a0 = sumFrom 0
--   
--   &gt;&gt;&gt; let Identity (res1, a1) = stepAuto a0 4      -- run with 4
--   
--   &gt;&gt;&gt; res1
--   4                -- the cumulative sum, 4
--   
--   &gt;&gt;&gt; let Identity (res2, a2) = stepAuto a1 5      -- run with 5
--   
--   &gt;&gt;&gt; res2
--   9                -- the cumulative sum, 4 + 5
--   
--   &gt;&gt;&gt; let Identity (res3, _ ) = stepAuto a2 3      -- run with 3
--   
--   &gt;&gt;&gt; res3
--   12               -- the cumulative sum, 4 + 5 + 3
--   </pre>
--   
--   By the way, for the case where your <a>Auto</a> is under
--   <a>Identity</a>, we have a type synomym <a>Auto'</a>...and a
--   convenience function to make "running" it more streamlined:
--   
--   <pre>
--   &gt;&gt;&gt; let a0 :: Auto' Int Int
--           a0 = sumFrom 0
--   
--   &gt;&gt;&gt; let (res1, a1) = stepAuto' a0 4          -- run with 4
--   
--   &gt;&gt;&gt; res1
--   4                -- the cumulative sum, 4
--   
--   &gt;&gt;&gt; let (res2, a2) = stepAuto' a1 5          -- run with 5
--   
--   &gt;&gt;&gt; res2
--   9                -- the cumulative sum, 4 + 5
--   
--   &gt;&gt;&gt; let (res3, _ ) = stepAuto' a2 3          -- run with 3
--   
--   &gt;&gt;&gt; res3
--   12               -- the cumulative sum, 4 + 5 + 3
--   </pre>
--   
--   But, if your <a>Auto</a> actaully has effects when being stepped,
--   <a>stepAuto</a> will execute them:
--   
--   <pre>
--   &gt;&gt;&gt; let a0 :: Auto IO Int Int
--           a0 = effect (putStrLn "hey!") *&gt; sumFrom 0
--   
--   &gt;&gt;&gt; (res1, a1) &lt;- stepAuto a0 4              -- run with 4
--   hey!         -- IO effect
--   
--   &gt;&gt;&gt; res1
--   4                -- the cumulative sum, 4
--   
--   &gt;&gt;&gt; (res2, a2) &lt;- stepAuto a1 5              -- run with 5
--   hey!         -- IO effect
--   
--   &gt;&gt;&gt; res2
--   9                -- the cumulative sum, 4 + 5
--   
--   &gt;&gt;&gt; (res3, _ ) &lt;- stepAuto a2 3              -- run with 3
--   hey!         -- IO effect
--   
--   &gt;&gt;&gt; res3
--   12               -- the cumulative sum, 4 + 5 + 3
--   </pre>
--   
--   (Here, <tt><tt>effect</tt> (<a>putStrLn</a> "hey")</tt> is an
--   <tt><a>Auto</a> IO Int ()</tt>, which ignores its input and just
--   executes <tt><a>putStrLn</a> "hey"</tt> every time it is run. When we
--   use <a>*&gt;</a> from <a>Control.Applicative</a>, we "combine" the two
--   <a>Auto</a>s together and run them <i>both</i> on each input (4, 5,
--   3...)...but for the "final" output at the end, we only return the
--   output of the second one, <tt><tt>sumFrom</tt> 0</tt> (5, 9, 12...))
--   
--   If you think of an <tt><a>Auto</a> m a b</tt> as a "stateful function"
--   <tt>a -&gt; m b</tt>, then <a>stepAuto</a> lets you "run" it.
--   
--   In order to directly run an <a>Auto</a> on a stream, an <tt>[a]</tt>,
--   use <tt>streamAuto</tt>. That gives you an <tt>[a] -&gt; m [b]</tt>.
stepAuto :: Monad m => Auto m a b -> a -> m (b, Auto m a b)

-- | <a>Runs</a> an <a>Auto'</a> through one step.
--   
--   That is, given an <tt><a>Auto'</a> a b</tt>, returns a function that
--   takes an <tt>a</tt> and returns a <tt>b</tt> and an "updated"/"next"
--   <a>Auto'</a>; an <tt>a -&gt; (b, <a>Auto'</a> a b)</tt>.
--   
--   See <a>stepAuto</a> documentation for motivations, use cases, and more
--   details. You can use this instead of <a>stepAuto</a> when your
--   underyling monad is <a>Identity</a>, and your <a>Auto</a> doesn't
--   produce any effects.
--   
--   Here is an example with <tt><tt>sumFrom</tt> 0</tt>, the <a>Auto'</a>
--   whose output is the cumulative sum of the inputs
--   
--   <pre>
--   stepAuto' :: Auto' Int Int
--             -&gt; (Int -&gt; (Int, Auto' Int Int))
--   </pre>
--   
--   Every time you "step", you give it an <a>Int</a> and get a resulting
--   <a>Int</a> (the cumulative sum) and the "updated <a>Auto'</a>", with
--   the updated accumulator.
--   
--   <pre>
--   &gt;&gt;&gt; let a0 :: Auto' Int Int
--           a0 = sumFrom 0
--   
--   &gt;&gt;&gt; let (res1, a1) = stepAuto' a0 4          -- run with 4
--   
--   &gt;&gt;&gt; res1
--   4                -- the cumulative sum, 4
--   
--   &gt;&gt;&gt; let (res2, a2) = stepAuto' a1 5          -- run with 5
--   
--   &gt;&gt;&gt; res2
--   9                -- the cumulative sum, 4 + 5
--   
--   &gt;&gt;&gt; let (res3, _ ) = stepAuto' a2 3          -- run with 3
--   
--   &gt;&gt;&gt; res3
--   12               -- the cumulative sum, 4 + 5 + 3
--   </pre>
--   
--   If you think of an <tt><a>Auto'</a> a b</tt> as a "stateful function"
--   <tt>a -&gt; b</tt>, then <a>stepAuto'</a> lets you "run" it.
--   
--   In order to directly run an <a>Auto'</a> on a stream, an <tt>[a]</tt>,
--   use <tt>streamAuto'</tt>. That gives you an <tt>[a] -&gt; [b]</tt>.
stepAuto' :: Auto' a b -> a -> (b, Auto' a b)

-- | Like <a>stepAuto</a>, but drops the "next <a>Auto</a>" and just gives
--   the result.
evalAuto :: Monad m => Auto m a b -> a -> m b

-- | Like <a>stepAuto'</a>, but drops the "next <a>Auto'</a>" and just
--   gives the result. <a>evalAuto</a> for <a>Auto'</a>.
evalAuto' :: Auto' a b -> a -> b

-- | Like <a>stepAuto</a>, but drops the result and just gives the "updated
--   <a>Auto</a>".
execAuto :: Monad m => Auto m a b -> a -> m (Auto m a b)

-- | Like <a>stepAuto'</a>, but drops the result and just gives the
--   "updated <a>Auto'</a>". <a>execAuto</a> for <a>Auto'</a>.
execAuto' :: Auto' a b -> a -> Auto' a b

-- | Encode an <a>Auto</a> and its internal state into a <a>ByteString</a>.
encodeAuto :: Auto m a b -> ByteString

-- | <a>Resume</a> an <a>Auto</a> from its <a>ByteString</a> serialization,
--   giving a <a>Left</a> if the deserialization is not possible.
decodeAuto :: Auto m a b -> ByteString -> Either String (Auto m a b)

-- | Returns a <a>Put</a> --- instructions (from <a>Data.Serialize</a>) on
--   how to "freeze" the <a>Auto</a>, with its internal state, and save it
--   to a binary encoding. It can later be reloaded and "resumed" by
--   'resumeAuto'/'decodeAuto'.
saveAuto :: Auto m a b -> Put

-- | Returns a <a>Get</a> from an <a>Auto</a> --- instructions (from
--   <a>Data.Serialize</a>) on taking a ByteString and "restoring" the
--   originally saved <a>Auto</a>, in the originally saved state.
resumeAuto :: Auto m a b -> Get (Auto m a b)

-- | Takes an <a>Auto</a> that is serializable/resumable and returns an
--   <a>Auto</a> that is not. That is, when it is "saved", saves no data,
--   and when it is "resumed", resets itself back to the initial
--   configuration every time; in other words, <tt><a>decodeAuto</a>
--   (unserialize a) bs = Right (unserialize a)</tt>. Trying to "resume" it
--   will just always give itself, unchanged.
unserialize :: Monad m => Auto m a b -> Auto m a b

-- | Swaps out the underlying <a>Monad</a> of an <a>Auto</a> using the
--   given monad morphism "transforming function", a natural
--   transformation.
--   
--   Basically, given a function to "swap out" any <tt>m a</tt> with an
--   <tt>m' a</tt>, it swaps out the underlying monad of the <a>Auto</a>.
--   
--   This forms a functor, so you rest assured in things like this:
--   
--   <pre>
--   hoistA id == id
--   hoistA f a1 . hoistA f a2 == hoistA f (a1 . a2)
--   </pre>
hoistA :: (Monad m, Monad m') => (forall c. m c -> m' c) -> Auto m a b -> Auto m' a b

-- | Generalizes an <tt><a>Auto'</a> a b</tt> to an <tt><a>Auto</a> m a
--   b'</tt> for any <a>Monad</a> <tt>m</tt>, using <tt>hoist</tt>.
--   
--   You generally should be able to avoid using this if you never directly
--   write any <a>Auto'</a>s and always write 'Auto m' parameterized over
--   all <a>Monad</a>s, but...in case you import one from a library or
--   something, you can use this.
generalizeA :: Monad m => Auto' a b -> Auto m a b

-- | Abstraction over lower-level funging with serialization; lets you
--   modify the result of an <a>Auto</a> by being able to intercept the
--   <tt>(b, <a>Auto</a> m a b)</tt> output and return a new output value
--   <tt>m c</tt>.
--   
--   Note that this is a lot like <a>fmap</a>:
--   
--   <pre>
--   fmap :: (b -&gt; c) -&gt; Auto m a b -&gt; Auto m a c
--   </pre>
--   
--   Except gives you access to both the <tt>b</tt> and the "updated
--   <a>Auto</a>"; instead of an <tt>b -&gt; c</tt>, you get to pass a
--   <tt>(b, <a>Auto</a> m a b) -&gt; m c</tt>.
--   
--   Basically experimenting with a bunch of abstractions over different
--   lower-level modification of <a>Auto</a>s, because making sure the
--   serialization works as planned can be a bit difficult.
interceptO :: Monad m => ((b, Auto m a b) -> m c) -> Auto m a b -> Auto m a c

-- | Construct the <a>Auto</a> whose output is always the given value,
--   ignoring its input.
--   
--   Provided for API constency, but you should really be using <a>pure</a>
--   from the <a>Applicative</a> instance, from <a>Control.Applicative</a>,
--   which does the same thing.
mkConst :: b -> Auto m a b

-- | Construct the <a>Auto</a> that always "executes" the given monadic
--   value at every step, yielding the result as its output and ignoring
--   its input.
--   
--   Provided for API consistency, but you shold really be using
--   <tt>effect</tt> from <a>Control.Auto.Effects</a>, which does the same
--   thing.
mkConstM :: m b -> Auto m a b

-- | Construct a stateless <a>Auto</a> that simply applies the given (pure)
--   function to every input, yielding the output. The output stream is
--   just the result of applying the function to every input.
--   
--   <pre>
--   streamAuto' (mkFunc f) = map f
--   </pre>
--   
--   This is rarely needed; you should be using <a>arr</a> from the
--   <a>Arrow</a> instance, from <a>Control.Arrow</a>.
mkFunc :: (a -> b) -> Auto m a b

-- | Construct a stateless <a>Auto</a> that simply applies and executes the
--   givne (monadic) function to every input, yielding the output. The
--   output stream is the result of applying the function to every input,
--   executing/sequencing the action, and returning the returned value.
--   
--   <pre>
--   streamAuto (mkFuncM f) = mapM f
--   </pre>
--   
--   It's recommended that you use <tt>arrM</tt> from
--   <a>Control.Auto.Effects</a>. This is only really provided for
--   consistency.
mkFuncM :: (a -> m b) -> Auto m a b

-- | Construct an <a>Auto</a> from a state transformer: an <tt>a -&gt; s
--   -&gt; (b, s)</tt> gives you an <tt><a>Auto</a> m a b</tt>, for any
--   <a>Monad</a> <tt>m</tt>. At every step, it takes in the <tt>a</tt>
--   input, runs the function with the stored internal state, returns the
--   <tt>b</tt> result, and now contains the new resulting state. You have
--   to intialize it with an initial state, of course.
--   
--   From the "stream transformer" point of view, this is rougly equivalent
--   to <a>mapAccumL</a> from <a>Data.List</a>, with the function's
--   arguments and results in the backwards order.
--   
--   <pre>
--   streamAuto' (mkState f s0) = snd . mapAccumL (\s x -&gt; swap (f x s))
--   </pre>
--   
--   Try not to use this if it's ever avoidable, unless you're a framework
--   developer or something. Try make something by combining/composing the
--   various <a>Auto</a> combinators.
--   
--   If your state <tt>s</tt> does not have a <a>Serialize</a> instance,
--   then you should either write a meaningful one, provide the
--   serialization methods manually with <a>mkState'</a>, or throw away
--   serializability and use <a>mkState_</a>.
mkState :: Serialize s => (a -> s -> (b, s)) -> s -> Auto m a b

-- | A version of <a>mkState</a>, where the internal state isn't
--   serialized. It can be "saved" and "loaded", but the state is lost in
--   the process.
--   
--   See <a>mkState</a> for more details.
--   
--   Useful if your state <tt>s</tt> cannot have a meaningful
--   <a>Serialize</a> instance.
mkState_ :: (a -> s -> (b, s)) -> s -> Auto m a b

-- | Construct an <a>Auto</a> from a "monadic" state transformer: <tt>a
--   -&gt; s -&gt; m (b, s)</tt> gives you an <tt><a>Auto</a> m a b</tt>.
--   At every step, it takes in the <tt>a</tt> input, runs the function
--   with the stored internal state and "executes" the <tt>m (b, s)</tt> to
--   get the <tt>b</tt> output, and stores the <tt>s</tt> as the new,
--   updated state. Must be initialized with an initial state.
--   
--   Try not to use this if it's ever avoidable, unless you're a framework
--   developer or something. Try make something by combining/composing the
--   various <a>Auto</a> combinators.
--   
--   This version is a wrapper around <a>mkAuto</a>, that keeps track of
--   the serialization and re-loading of the internal state for you, so you
--   don't have to deal with it explicitly.
--   
--   If your state <tt>s</tt> does not have a <a>Serialize</a> instance,
--   then you should either write a meaningful one, provide the
--   serialization methods manually with <a>mkStateM'</a>, or throw away
--   serializability and use <a>mkStateM_</a>.
mkStateM :: Serialize s => (a -> s -> m (b, s)) -> s -> Auto m a b

-- | A version of <a>mkStateM</a>, where the internal state isn't
--   serialized. It can be "saved" and "loaded", but the state is lost in
--   the process.
--   
--   See <a>mkStateM</a> for more details.
--   
--   Useful if your state <tt>s</tt> cannot have a meaningful
--   <a>Serialize</a> instance.
mkStateM_ :: (a -> s -> m (b, s)) -> s -> Auto m a b

-- | A version of <a>mkState</a>, where the internal state doesn't have a
--   <a>Serialize</a> instance, so you provide your own instructions for
--   getting and putting the state.
--   
--   See <a>mkState</a> for more details.
mkState' :: Get s -> (s -> Put) -> (a -> s -> (b, s)) -> s -> Auto m a b

-- | A version of <a>mkStateM</a>, where the internal state doesn't have a
--   <a>Serialize</a> instance, so you provide your own instructions for
--   getting and putting the state.
--   
--   See <a>mkStateM</a> for more details.
mkStateM' :: Get s -> (s -> Put) -> (a -> s -> m (b, s)) -> s -> Auto m a b

-- | Construct an <a>Auto</a> from a "folding" function: <tt>b -&gt; a
--   -&gt; b</tt> yields an <tt><a>Auto</a> m a b</tt>. Basically acts like
--   a <a>foldl</a> or a <a>scanl</a>. There is an internal accumulator
--   that is "updated" with an <tt>a</tt> at every step. Must be given an
--   initial accumulator.
--   
--   Example: an <a>Auto</a> that sums up all of its input.
--   
--   <pre>
--   &gt;&gt;&gt; let summer = accum (+) 0
--   
--   &gt;&gt;&gt; let (sum1, summer')  = stepAuto' summer 3
--   
--   &gt;&gt;&gt; sum1
--   3
--   
--   &gt;&gt;&gt; let (sum2, summer'') = stepAuto' summer' 10
--   
--   &gt;&gt;&gt; sum2
--   13
--   
--   &gt;&gt;&gt; streamAuto'  summer'' [1..10]
--   [14,16,19,23,28,34,41,49,58,68]
--   </pre>
--   
--   If your accumulator <tt>b</tt> does not have a <a>Serialize</a>
--   instance, then you should either write a meaningful one, or throw away
--   serializability and use <a>accum_</a>.
accum :: Serialize b => (b -> a -> b) -> b -> Auto m a b

-- | A version of <a>accum</a>, where the internal accumulator isn't
--   serialized. It can be "saved" and "loaded", but the state is lost in
--   the process.
--   
--   See <a>accum</a> for more details.
--   
--   Useful if your accumulator <tt>b</tt> cannot have a meaningful
--   <a>Serialize</a> instance.
accum_ :: (b -> a -> b) -> b -> Auto m a b

-- | Construct an <a>Auto</a> from a "monadic" "folding" function: <tt>b
--   -&gt; a -&gt; m b</tt> yields an <tt><a>Auto</a> m a b</tt>. Basically
--   acts like a <a>foldM</a> or <tt>scanM</tt> (if it existed). here is an
--   internal accumulator that is "updated" with an input <tt>a</tt> with
--   the result of the executed <tt>m b</tt> at every step. Must be given
--   an initial accumulator.
--   
--   See <a>accum</a> for more details.
--   
--   If your accumulator <tt>b</tt> does not have a <a>Serialize</a>
--   instance, then you should either write a meaningful one, or throw away
--   serializability and use <a>accumM_</a>.
accumM :: (Serialize b, Monad m) => (b -> a -> m b) -> b -> Auto m a b

-- | A version of 'accumM_, where the internal accumulator isn't
--   serialized. It can be "saved" and "loaded", but the state is lost in
--   the process.
--   
--   See <a>accumM</a> for more details.
--   
--   Useful if your accumulator <tt>b</tt> cannot have a meaningful
--   <a>Serialize</a> instance.
accumM_ :: Monad m => (b -> a -> m b) -> b -> Auto m a b

-- | A "delayed" version of <a>accum</a>, where the first output is the
--   initial state of the accumulator, before applying the folding
--   function. Useful in recursive bindings.
--   
--   <pre>
--   &gt;&gt;&gt; let summerD = accumD (+) 0
--   
--   &gt;&gt;&gt; let (sum1, summerD')  = stepAuto' summerD 3
--   
--   &gt;&gt;&gt; sum1
--   0
--   
--   &gt;&gt;&gt; let (sum2, summerD'') = stepAuto' summerD' 10
--   
--   &gt;&gt;&gt; sum2
--   3
--   
--   &gt;&gt;&gt; streamAuto'  summerD'' [1..10]
--   [13,14,16,19,23,28,34,41,49,58]
--   </pre>
--   
--   (Compare with the example in <a>accum</a>)
--   
--   Note that this is more or less an encoding of <a>scanl</a>, that can
--   be "decoded" with <tt>streamAuto'</tt>:
--   
--   <pre>
--   &gt;&gt;&gt; let myScanl f z = streamAuto' (accumD f z)
--   
--   &gt;&gt;&gt; scanl (+) 0 [1..10]
--   [0,3,6,10,15,21,28,36,45,55]
--   
--   &gt;&gt;&gt; myScanl (+) 0 [1..10]
--   [0,3,6,10,15,21,28,36,45]
--   </pre>
--   
--   The only difference is that you don't get the last element. (You could
--   force it out, if you wanted, by feeding any nonsense value in --- even
--   <a>undefined</a>! --- and getting the result)
accumD :: Serialize b => (b -> a -> b) -> b -> Auto m a b

-- | The non-resuming/non-serializing version of <a>accumD</a>.
accumD_ :: (b -> a -> b) -> b -> Auto m a b

-- | A "delayed" version of <a>accumM</a>, where the first output is the
--   initial state of the accumulator, before applying the folding
--   function. Useful in recursive bindings.
accumMD :: (Serialize b, Monad m) => (b -> a -> m b) -> b -> Auto m a b

-- | The non-resuming/non-serializing version of <a>accumMD</a>.
accumMD_ :: Monad m => (b -> a -> m b) -> b -> Auto m a b

-- | Construct an <a>Auto</a> by explicity giving its serialization,
--   deserialization, and the function from <tt>a</tt> to a <tt>b</tt> and
--   "updated <a>Auto</a>".
--   
--   Ideally, you wouldn't have to use this unless you are making your own
--   framework. Try your best to make what you want by assembling primtives
--   together. Working with serilization directly is hard.
--   
--   See <a>mkAutoM</a> for more detailed instructions on doing this right.
mkAuto :: Get (Auto m a b) -> Put -> (a -> (b, Auto m a b)) -> Auto m a b

-- | Like <a>mkAuto</a>, but without any way of meaningful serializing or
--   deserializing.
--   
--   Be careful! This <a>Auto</a> can still carry arbitrary internal state,
--   but it cannot be meaningfully serialized or re-loaded/resumed. You can
--   still pretend to do so using
--   'resumeAuto'/'saveAuto'/'encodeAuto'/'decodeAuto' (and the type system
--   won't stop you), but when you try to "resume"/decode it, its state
--   will be lost.
mkAuto_ :: (a -> (b, Auto m a b)) -> Auto m a b

-- | Construct an <a>Auto</a> by explicitly giving its serializiation,
--   deserialization, and the (monadic) function from <tt>a</tt> to a
--   <tt>b</tt> and the "updated <a>Auto</a>".
--   
--   See the "serialization" section in the <a>Control.Auto.Core</a> module
--   for more information.
--   
--   Ideally, you wouldn't have to use this unless you are making your own
--   framework. Try your best to make what you want by assembling primtives
--   together.
--   
--   But sometimes you have to write your own combinators, and you're going
--   to have to use <a>mkAutoM</a> to make it work.
--   
--   Sometimes, it's simple:
--   
--   <pre>
--   fmap :: (a -&gt; b) -&gt; Auto r a -&gt; Auto r b
--   fmap f a0 = mkAutoM (do aResumed &lt;- resumeAuto a0
--                           return (fmap f aResumed)  )
--                       (saveAuto a0)
--                       $ x -&gt; do
--                           (y, a1) &lt;- stepAuto a0 x
--                           return (f y, fmap f a1)
--   </pre>
--   
--   Serializing <tt><a>fmap</a> f a0</tt> is just the same as serializing
--   <tt>a0</tt>. And to resume it, we resume <tt>a0</tt> to get a resumed
--   version of <tt>a0</tt>, and then we apply <tt><a>fmap</a> f</tt> to
--   the <a>Auto</a> that we resumed.
--   
--   Also another nice "simple" example is:
--   
--   <pre>
--   catchA :: Exception e
--          =&gt; Auto IO a b
--          -&gt; Auto IO a (Either e b)
--   catchA a = mkAutoM (do aResumed &lt;- resumeAuto a
--                          return (catchA aResumed) )
--                      (saveAuto a)
--                    $ x -&gt; do
--                        eya' &lt;- try $ stepAuto a x
--                        case eya' of
--                          Right (y, a') -&gt; return (Right y, catchA a')
--                          Left e        -&gt; return (Left e , catchA a )
--   </pre>
--   
--   Which is basically the same principle, in terms of serializing and
--   resuming strategies.
--   
--   When you have "switching" --- things that behave like different
--   <a>Auto</a>s at different points in time --- then things get a little
--   complicated, because you have to figure out which <a>Auto</a> to
--   resume.
--   
--   For example, let's look at the source of <tt>-?&gt;</tt>:
--   
--   <pre>
--   (-?&gt;) :: Monad m
--         =&gt; Interval m a b   -- ^ initial behavior
--         -&gt; Interval m a b   -- ^ final behavior, when the initial
--                             --   behavior turns off.
--         -&gt; Interval m a b
--   a1 -?&gt; a2 = mkAutoM l s t
--     where
--       l = do
--         flag &lt;- get
--         if flag
--           then resumeAuto (switched a2)
--           else (-?&gt; a2) <a>$</a> resumeAuto a1
--       s = put False *&gt; saveAuto a1
--       t x = do
--         (y1, a1') &lt;- stepAuto a1 x
--         case y1 of
--           Just _  -&gt;
--             return (y1, a1' -?&gt; a2)
--           Nothing -&gt; do
--             (y, a2') &lt;- stepAuto a2 x
--             return (y, switched a2')
--       switched a = mkAutoM l
--                            (put True  *&gt; saveAuto a)
--                          $ x -&gt; do
--                              (y, a') &lt;- stepAuto a x
--                              return (y, switched a')
--   </pre>
--   
--   We have to invent a serialization and reloading scheme, taking into
--   account the two states that the resulting <a>Auto</a> can be in:
--   
--   <ol>
--   <li>Initially, it is behaving like <tt>a1</tt>. So, to save it, we put
--   a flag saying that we are still in stage 1 (<a>False</a>), and then
--   put <tt>a1</tt>'s current serialization data.</li>
--   <li>After the switch, it is behaving like <tt>a2</tt>. So, to save it,
--   we put a flag saying that we are now in stage 2 (<a>True</a>), and
--   then put <tt>a2</tt>'s current.</li>
--   </ol>
--   
--   Now, when we <i>resume</i> <tt>a1 <tt>-?&gt;</tt> a2</tt>,
--   <a>resumeAuto</a> on <tt>a1 <tt>-?&gt;</tt> a2</tt> will give us
--   <tt>l</tt>. So the <a>Get</a> we use --- the process we use to resume
--   the entire <tt>a1 <tt>-?&gt;</tt> a2</tt>, will <i>start</i> at the
--   initial <a>Get</a>/loading function, <tt>l</tt> here. We have to
--   encode our branching and resuming/serialization scheme into the
--   initial, front-facing <tt>l</tt>. So <tt>l</tt> has to check for the
--   flag, and if the flag is true, load in the data for the switched
--   state; otherwise, load in the data for the pre-switched state.
--   
--   Not all of them are this tricky. Mostly "switching" combinators will
--   be tricky, because switching means changing what you are serializing.
--   
--   This one might be considerably easier, because of <a>mapM</a>:
--   
--   <pre>
--   zipAuto :: Monad m
--           =&gt; a                -- ^ default input value
--           -&gt; [Auto m a b]     -- ^ <a>Auto</a>s to zip up
--           -&gt; Auto m [a] [b]
--   zipAuto x0 as = mkAutoM (zipAuto x0 <a>$</a> mapM resumeAuto as)
--                           (mapM_ saveAuto as)
--                           $ xs -&gt; do
--                               res &lt;- zipWithM stepAuto as (xs ++ repeat x0)
--                               let (ys, as') = unzip res
--                               return (ys, zipAuto x0 as')
--   </pre>
--   
--   To serialize, we basically sequence <a>saveAuto</a> over all of the
--   internal <a>Auto</a>s --- serialize each of their serialization data
--   one-by-one one after the other in our binary.
--   
--   To load, we do the same thing; we go over every <a>Auto</a> in
--   <tt>as</tt> and <a>resumeAuto</a> it, and then collect the results in
--   a list --- a list of resumed <a>Auto</a>s. And then we apply
--   <tt><tt>zipAuto</tt> x0</tt> to that list of <a>Auto</a>s, to get our
--   resumed <tt><tt>zipAuto</tt> x0 as</tt>.
--   
--   So, it might be complicated. In the end, it might be all worth it,
--   too, to have implicit serialization compose like this. Think about
--   your serialization strategy first. Step back and think about what you
--   need to serialize at every step, and remember that it's _the initial_
--   "resuming" function that has to "resume everything"...it's not the
--   resuming function that exists when you finally save your <a>Auto</a>,
--   it's the resuming <a>Get</a> that was there <i>at the beginning</i>.
--   For <tt>-?&gt;</tt>, the intial <tt>l</tt> had to know how to "skip
--   ahead".
--   
--   And of course as always, test.
--   
--   If you need to make your own combinator or transformer but are having
--   trouble with the serializtion, feel free to contact me at
--   <a>justin@jle.im</a>, on freenode at <i>#haskell</i> or
--   <i>#haskell-auto</i>, open a <a>github issue</a>, etc. Just contact me
--   somehow, I'll be happy to help!
mkAutoM :: Get (Auto m a b) -> Put -> (a -> m (b, Auto m a b)) -> Auto m a b

-- | Like <a>mkAutoM</a>, but without any way of meaningful serializing or
--   deserializing.
--   
--   Be careful! This <a>Auto</a> can still carry arbitrary internal state,
--   but it cannot be meaningfully serialized or re-loaded/resumed. You can
--   still pretend to do so using
--   'resumeAuto'/'saveAuto'/'encodeAuto'/'decodeAuto' (and the type system
--   won't stop you), but when you try to "resume"/decode it, its state
--   will be reset.
mkAutoM_ :: (a -> m (b, Auto m a b)) -> Auto m a b

-- | Force the serializing components of an <a>Auto</a>.
--   
--   TODO: Test if this really works
forceSerial :: Auto m a b -> Auto m a b

-- | A special <a>Auto</a> that acts like the <a>id</a> <a>Auto</a>, but
--   forces results as they come through to be fully evaluated, when
--   composed with other <a>Auto</a>s.
--   
--   TODO: Test if this really works
forcer :: NFData a => Auto m a a

-- | A special <a>Auto</a> that acts like the <a>id</a> <a>Auto</a>, but
--   forces results as they come through to be evaluated to Weak Head
--   Normal Form, with <a>seq</a>, when composed with other <a>Auto</a>s.
--   
--   TODO: Test if this really works
seqer :: Auto m a a
instance GHC.Base.Monad m => GHC.Base.Functor (Control.Auto.Core.Auto m a)
instance GHC.Base.Monad m => GHC.Base.Applicative (Control.Auto.Core.Auto m a)
instance (GHC.Base.Monad m, GHC.Base.Alternative m) => GHC.Base.Alternative (Control.Auto.Core.Auto m a)
instance GHC.Base.Monad m => Control.Category.Category (Control.Auto.Core.Auto m)
instance GHC.Base.Monad m => Data.Profunctor.Unsafe.Profunctor (Control.Auto.Core.Auto m)
instance GHC.Base.Monad m => Data.Profunctor.Strong.Strong (Control.Auto.Core.Auto m)
instance GHC.Base.Monad m => Data.Profunctor.Choice.Choice (Control.Auto.Core.Auto m)
instance Control.Monad.Fix.MonadFix m => Data.Profunctor.Strong.Costrong (Control.Auto.Core.Auto m)
instance GHC.Base.Monad m => Control.Arrow.Arrow (Control.Auto.Core.Auto m)
instance GHC.Base.Monad m => Control.Arrow.ArrowChoice (Control.Auto.Core.Auto m)
instance Control.Monad.Fix.MonadFix m => Control.Arrow.ArrowLoop (Control.Auto.Core.Auto m)
instance (GHC.Base.Monad m, GHC.Base.Semigroup b) => GHC.Base.Semigroup (Control.Auto.Core.Auto m a b)
instance (GHC.Base.Monad m, GHC.Base.Monoid b) => GHC.Base.Monoid (Control.Auto.Core.Auto m a b)
instance (GHC.Base.Monad m, Data.String.IsString b) => Data.String.IsString (Control.Auto.Core.Auto m a b)
instance (GHC.Base.Monad m, GHC.Num.Num b) => GHC.Num.Num (Control.Auto.Core.Auto m a b)
instance (GHC.Base.Monad m, GHC.Real.Fractional b) => GHC.Real.Fractional (Control.Auto.Core.Auto m a b)
instance (GHC.Base.Monad m, GHC.Float.Floating b) => GHC.Float.Floating (Control.Auto.Core.Auto m a b)


-- | This module provides tools for generating and manipulating "blip
--   streams". The blip stream abstraction is not fundamental to
--   <a>Auto</a>, but rather, like <i>interval</i>, is a very useful
--   semantic tool for the denotation of many programs, games, simulations,
--   and computations in general that you are likely to write with this
--   library.
module Control.Auto.Blip

-- | When used in the context of an input or output of an <tt>Auto</tt>, a
--   <tt><a>Blip</a> a</tt> represents a stream that occasionally, at
--   "independent" or "discrete" points, emits a value of type <tt>a</tt>.
--   
--   Contrast this to <tt>Interval</tt>, where things are meant to be "on"
--   or "off" for contiguous chunks at a time; blip streams are "blippy",
--   and <tt>Interval</tt>s are "chunky".
--   
--   It's here mainly because it's a pretty useful abstraction in the
--   context of the many combinators found in various modules of this
--   library. If you think of an <tt><tt>Auto</tt> m a (<a>Blip</a> b)</tt>
--   as producing a "blip stream", then there are various combinators and
--   functions that are specifically designed to manipulate blip streams.
--   
--   For the purposes of the semantics of what <a>Blip</a> is supposed to
--   represent, its constructors are hidden. (Almost) all of the various
--   <a>Blip</a> combinators (and its very useful <a>Functor</a> instance)
--   "preserve <a>Blip</a>ness" --- one-at-a-time occurrences remain
--   one-at-a-time under all of these combinators, and you should have
--   enough so that direct access to the constructor is not needed.
--   
--   If you are creating a framework, library, or backend, you might want
--   to manually create blip stream-producing <tt>Auto</tt>s for your users
--   to access. In this case, you can import the constructors and useful
--   internal (and, of course, semantically unsafe) functions from
--   <a>Control.Auto.Blip.Internal</a>.
data Blip a

-- | Takes an <tt><a>Auto</a> m a b</tt> (an <a>Auto</a> that turns
--   incoming <tt>a</tt>s into outputting <tt>b</tt>s) into an
--   <tt><a>Auto</a> m (<a>Blip</a> a) (<a>Blip</a> b)</tt>; the original
--   <a>Auto</a> is lifted to only be applied to emitted contents of a blip
--   stream.
--   
--   When the stream emits, the original <a>Auto</a> is "stepped" with the
--   emitted value; when it does not, it is paused and frozen until the
--   next emission.
--   
--   <pre>
--   &gt;&gt;&gt; let sums = perBlip (sumFrom 0)
--   
--   &gt;&gt;&gt; let blps = eachAt 2 [1,5,2]
--   
--   &gt;&gt;&gt; take 8 . streamAuto' blps $ repeat ()
--   [NoBlip, Blip 1, NoBlip, Blip 5, NoBlip, Blip 2, NoBlip, NoBlip]
--   
--   &gt;&gt;&gt; take 8 . streamAuto' (sums . blps) $ repeat ()
--   [NoBlip, Blip 1, NoBlip, Blip 6, NoBlip, Blip 8, NoBlip, NoBlip]
--   </pre>
perBlip :: Monad m => Auto m a b -> Auto m (Blip a) (Blip b)

-- | Merge two blip streams together; the result emits with <i>either</i>
--   of the two merged streams emit. When both emit at the same time, emit
--   the result of applying the given function on the two emitted values.
--   
--   Note that this might be too strict for some purposes; see
--   <a>mergeL</a> and <a>mergeR</a> for lazier alternatives.
merge :: (a -> a -> a) -> Blip a -> Blip a -> Blip a

-- | Merges two blip streams together into one, which emits <i>either</i>
--   of the original blip streams emit. If both emit at the same time, the
--   left (first) one is favored.
--   
--   Lazy on the second stream if the first stream is emitting.
--   
--   If we discount laziness, this is <tt><a>merge</a> <a>const</a></tt>.
mergeL :: Blip a -> Blip a -> Blip a
infixr 5 `mergeL`

-- | Merges two blip streams together into one, which emits <i>either</i>
--   of the original blip streams emit. If both emit at the same time, the
--   right (second) one is favored.
--   
--   Lazy on the first stream if the second stream is emitting.
--   
--   If we discount laziness, this is <tt><a>merge</a> (<a>flip</a>
--   <a>const</a>)</tt>.
mergeR :: Blip a -> Blip a -> Blip a
infixl 5 `mergeR`

-- | Merge all the blip streams together into one, favoring the first
--   emitted value.
mergeLs :: [Blip a] -> Blip a

-- | Merge all the blip streams together into one, favoring the last
--   emitted value.
mergeRs :: [Blip a] -> Blip a

-- | Merge all of the blip streams together, using the given merging
--   function associating from the right.
--   
--   <b>DEPRECATED</b>: In its current form, <a>foldrB</a> will disappear
--   in <tt>0.5</tt>. The new version will be:
--   
--   <pre>
--   foldrB :: (a -&gt; a -&gt; a) -&gt; [Blip a] -&gt; Blip b
--   </pre>
--   
--   Which will not emit if nothing emits. This really was supposed to be
--   the intended behavior originally.
--   
--   For this reason, please do not use this anymore. As it is currently
--   implemented, it doesn't really make any sense, either.
--   
--   To begin using the new behavior, you can use:
--   
--   <pre>
--   foldr (merge f) mempty
--   </pre>

-- | <i>Deprecated: Starting in v0.5, will have new functionality.</i>
foldrB :: (a -> a -> a) -> a -> [Blip a] -> Blip a

-- | Merge all of the blip streams together, using the given merging
--   function associating from the left.
--   
--   <b>DEPRECATED</b>: In its current form, <a>foldlB'</a> will disappear
--   in <tt>0.5</tt>. The new version will be:
--   
--   <pre>
--   foldlB' :: (a -&gt; a -&gt; a) -&gt; [Blip a] -&gt; Blip b
--   </pre>
--   
--   Which will not emit if nothing emits. This really was supposed to be
--   the intended behavior originally.
--   
--   For this reason, please do not use this anymore. As it is currently
--   implemented, it doesn't really make any sense, either.
--   
--   To begin using the new behavior, you can use:
--   
--   <pre>
--   foldl' (merge f) mempty
--   </pre>

-- | <i>Deprecated: Starting in v0.5, will have new functionality.</i>
foldlB' :: (a -> a -> a) -> a -> [Blip a] -> Blip a

-- | An <a>Auto</a> that runs every input through a <tt>a -&gt;
--   <a>Maybe</a> b</tt> test and produces a blip stream that emits the
--   value inside every <a>Just</a> result.
--   
--   Particularly useful with prisms from the <i>lens</i> package, where
--   things like <tt>emitJusts (preview _Right)</tt> will emit the
--   <tt>b</tt> whenever the input <tt>Either a b</tt> stream is a
--   <tt>Right</tt>.
--   
--   Warning! Carries all of the same dangers of <a>emitOn</a>. You can
--   easily break blip semantics with this if you aren't sure what you are
--   doing. Remember to only emit at discrete, separate occurences, and not
--   for interval-like (on and off for chunks at a time) things. For
--   interval semantics, we have <a>Control.Auto.Interval</a>.
--   
--   See the examples of <a>emitOn</a> for more concrete good/bad use
--   cases.
emitJusts :: (a -> Maybe b) -> Auto m a (Blip b)

-- | Like <a>emitJusts</a>, except forks into two streams depending on the
--   function's result being <a>Left</a> or <a>Right</a>.
--   
--   Is only meaningful if you expect every 'Left'/'Right' choice to be
--   independent of the last.
emitEithers :: (a -> Either b c) -> Auto m a (Blip b, Blip c)

-- | An <a>Auto</a> that emits whenever it receives a <a>Just</a> input,
--   with the value inside the <a>Just</a>.
--   
--   Warning! Carries all of the same dangers of <a>emitOn</a>. You can
--   easily break blip semantics with this if you aren't sure what you are
--   doing. Remember to only emit at discrete, separate occurences, and not
--   for interval-like (on and off for chunks at a time) things. For
--   interval semantics, we have <a>Control.Auto.Interval</a>.
--   
--   See the examples of <a>emitOn</a> for more concrete good/bad use
--   cases.
--   
--   <pre>
--   onJusts == emitJusts id
--   </pre>
onJusts :: Auto m (Maybe a) (Blip a)

-- | Like <a>onJusts</a>, except forks into two streams depending on if the
--   input is <a>Left</a> or <a>Right</a>.
--   
--   Is only meaningful if you expect every 'Left'/'Right' choice to be
--   independent of the last.
--   
--   <pre>
--   onEithers == emitEithers id
--   </pre>
onEithers :: Auto m (Either a b) (Blip a, Blip b)

-- | Produces a blip stream that emits the input value whenever the input
--   satisfies a given predicate.
--   
--   Warning! This <a>Auto</a> has the capability of "breaking" blip
--   semantics. Be sure you know what you are doing when using this. Blip
--   streams are semantically supposed to only emit at discrete, separate
--   occurrences. Do not use this for interval-like (on and off for chunks
--   at a time) things; each input should be dealt with as a separate
--   thing.
--   
--   For interval semantics, we have <tt>Interval</tt> from
--   <a>Control.Auto.Interval</a>.
--   
--   Good example:
--   
--   <pre>
--   -- is only emitting at discrete blips
--   emitOn even . iterator (+ 1) 0
--   </pre>
--   
--   Bad examples:
--   
--   <pre>
--   -- is emitting for "durations" or "intervals" of time.
--   emitOn (&lt; 10) . iterator (+ 1) 0
--   
--   emitOn (const True) . foo
--   </pre>
--   
--   These bad examples would be good use cases of <tt>Interval</tt>.
--   
--   Can be particularly useful with prisms from the <i>lens</i> package,
--   where things like <tt>emitOn (has _Right)</tt> and <tt>emitOn (hasn't
--   _Right)</tt> will emit the input <tt>Either a b</tt> whenever it is or
--   isn't a <a>Right</a>. See <a>emitJusts</a> for more common uses with
--   <i>lens</i>.
emitOn :: (a -> Bool) -> Auto m a (Blip a)

-- | <tt><a>fromBlips</a> d</tt> is an <a>Auto</a> that decomposes the
--   incoming blip stream by constantly outputting <tt>d</tt> except when
--   the stream emits, and outputs the emitted value when it does.
fromBlips :: a -> Auto m (Blip a) a

-- | <tt><a>fromBlipsWith</a> d f</tt> is an <a>Auto</a> that decomposes
--   the incoming blip stream by constantly outputting <tt>d</tt> except
--   when the stream emits, and outputs the result of applying <tt>f</tt>
--   to the emitted value when it does.
fromBlipsWith :: b -> (a -> b) -> Auto m (Blip a) b

-- | Collapse a blip stream of <tt>a</tt>s into a stream of `Maybe a`'s
asMaybes :: Auto m (Blip a) (Maybe a)

-- | <tt><a>holdWith</a> y0</tt> is an <a>Auto</a> whose output is always
--   the /most recently emitted/ value from the input blip stream. Before
--   anything is emitted, <tt>y0</tt> is outputted as a placeholder.
--   
--   Contrast with <tt>hold</tt> from <a>Control.Auto.Interval</a>.
holdWith :: Serialize a => a -> Auto m (Blip a) a

-- | A non-serializing/non-resumable version of <a>holdWith</a>.
holdWith_ :: a -> Auto m (Blip a) a

-- | Take in a normal stream and a blip stream. Behave like the normal
--   stream when the blip stream doesn't emit...but when it does, output
--   the emitted value instead.
substituteB :: Auto m (a, Blip a) a

-- | An <a>Auto</a> that ignores its input and produces a blip stream never
--   emits.
never :: Auto m a (Blip b)

-- | Produces a blip stream that emits with the first received input value,
--   and never again after that.
--   
--   Often used with <a>pure</a>:
--   
--   <pre>
--   immediately . pure "Emit me!"
--   </pre>
--   
--   Or, in proc notation:
--   
--   <pre>
--   blp &lt;- immediately -&lt; "Emit me!"
--   </pre>
--   
--   to get a blip stream that emits a given value (eg., "Emit me!") once
--   and stops emitting ever again.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (immediately . pure "Emit me!") [1..5]
--   [Blip "Emit Me!", NoBlip, NoBlip, NoBlip, NoBlip]
--   </pre>
immediately :: Auto m a (Blip a)

-- | Produces a blip stream that only emits once, with the input value on
--   the given step number. It emits the input <i>on</i> that many steps.
--   
--   <pre>
--   immediately == inB 1
--   </pre>
inB :: Int -> Auto m a (Blip a)

-- | <tt><a>every</a> n</tt> is an <a>Auto</a> that emits with the incoming
--   inputs on every <tt>n</tt>th input value. First emitted value is on
--   the <tt>n</tt>th step.
--   
--   Will obviously break blip semantics when you pass in 1.
every :: Int -> Auto m a (Blip a)

-- | <tt><a>eachAt</a> n xs</tt> is an <a>Auto</a> that ignores its input
--   and creates a blip stream that emits each element of <tt>xs</tt> one
--   at a time, evey <tt>n</tt> steps. First emitted value is at step
--   <tt>n</tt>.
--   
--   Once the list is exhausted, never emits again.
--   
--   Obviously breaks blip semantics when you pass in 1.
--   
--   The process of serializing and resuming this <a>Auto</a> is O(n) space
--   and time with the length of <tt>xs</tt>. So don't serialize this if
--   you plan on passing an infinite list :) See
--   <a>Control.Auto.Generate</a> for more options.
--   
--   <pre>
--   eachAt n xs == perBlip (fromList xs) . every n
--   </pre>
eachAt :: Serialize b => Int -> [b] -> Auto m a (Blip b)

-- | The non-serializing/non-resumable version of <a>eachAt</a>.
eachAt_ :: Int -> [b] -> Auto m a (Blip b)

-- | <tt><a>collectN</a> n</tt> emits every <tt>n</tt> steps, emitting with
--   the <tt>n</tt> last items received.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (collectN 3) [1..10]
--   [ NoBlip, NoBlip, Blip [1,2,3], NoBlip, NoBlip, Blip [4,5,6]
--   , NoBlip, NoBlip, Blip [7,8,9], NoBlip ]
--   </pre>
collectN :: Serialize a => Int -> Auto m a (Blip [a])

-- | The non-serializing/non-resuming version of <a>collectN</a>
collectN_ :: Int -> Auto m a (Blip [a])

-- | Re-emits every emission from the input blip stream, but replaces its
--   value with the given value.
--   
--   <pre>
--   tagBlips x == modifyBlips (const x)
--   </pre>
tagBlips :: b -> Auto m (Blip a) (Blip b)

-- | Re-emits every emission from the input blip stream, but applies the
--   given function to the emitted value.
modifyBlips :: (a -> b) -> Auto m (Blip a) (Blip b)

-- | Takes two <a>Auto</a>s producing blip streams and returns a "merged"
--   <a>Auto</a> that emits when either of the original <a>Auto</a>s emit.
--   When both emit at the same time, the left (first) one is favored.
--   
--   <pre>
--   a1 &lt;&amp; a2 == mergeL &lt;$&gt; a1 &lt;*&gt; a2
--   </pre>
(<&) :: Monad m => Auto m a (Blip b) -> Auto m a (Blip b) -> Auto m a (Blip b)
infixr 5 <&

-- | Takes two <a>Auto</a>s producing blip streams and returns a "merged"
--   <a>Auto</a> that emits when either of the original <a>Auto</a>s emit.
--   When both emit at the same time, the right (second) one is favored.
--   
--   <pre>
--   a1 &amp;&gt; a2 == mergeR &lt;$&gt; a1 &lt;*&gt; a2
--   </pre>
(&>) :: Monad m => Auto m a (Blip b) -> Auto m a (Blip b) -> Auto m a (Blip b)
infixl 5 &>

-- | Supress all upstream emitted values except for the very first.
once :: Auto m (Blip a) (Blip a)

-- | Suppress only the first emission coming from upstream, and let all the
--   others pass uninhibited.
notYet :: Auto m (Blip a) (Blip a)

-- | Takes in a blip stream and outputs a blip stream where each emission
--   is delayed/lagged by one step.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (emitOn (\x -&gt; x `mod` 3 == 0)) [1..9]
--   
--   &gt;&gt;&gt; [NoBlip, NoBlip, Blip 3, NoBlip, NoBlip, Blip 6, NoBlip, NoBlip, Blip 9]
--   
--   &gt;&gt;&gt; streamAuto' (lagBlips . emitOn (\x -&gt; x `mod` 3 == 0)) [1..9]
--   
--   &gt;&gt;&gt; [NoBlip, NoBlip, NoBlip, Blip 3, NoBlip, NoBlip, Blip 6, NoBlip, NoBlip]
--   </pre>
lagBlips :: Serialize a => Auto m (Blip a) (Blip a)

-- | The non-serializing/non-resuming version of <a>lagBlips</a>.
lagBlips_ :: Auto m (Blip a) (Blip a)

-- | Suppress all upstream emissions when the predicate (on the emitted
--   value) fails.
filterB :: (a -> Bool) -> Auto m (Blip a) (Blip a)

-- | <a>Splits</a> a blip stream based on a predicate. Takes in one blip
--   stream and produces two: the first emits whenever the input emits with
--   a value that passes the predicate, and the second emits whenever the
--   input emits with a value that doesn't.
splitB :: (a -> Bool) -> Auto m (Blip a) (Blip a, Blip a)

-- | Applies the given function to every emitted value, and suppresses all
--   those for which the result is <a>Nothing</a>. Otherwise, lets it pass
--   through with the value in the <a>Just</a>.
mapMaybeB :: (a -> Maybe b) -> Auto m (Blip a) (Blip b)

-- | <a>Splits</a> a blip stream based on a predicate returning an
--   <a>Either</a>. All <a>Left</a> results go to the first output stream,
--   and all <a>Right</a> results go to the second.
--   
--   On an 'a -&gt; Either () b', is roughly analogous to <a>mapMaybeB</a>.
--   On an 'a -&gt; Either () ()', is roughly analogous to <a>filterB</a>
--   or <a>splitB</a>.
splitEitherB :: (a -> Either b c) -> Auto m (Blip a) (Blip b, Blip c)

-- | Waits on two streams, and emits with the first seen items when both
--   have emitted. Once it emits, starts over.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' collectB [(Blip 1, NoBlip), (Blip 2, Blip 'a'),(Blip 3, Blip 'b')]
--   [NoBlip, Blip (1, 'a'), Blip (3, 'b')]
--   </pre>
--   
--   Can be used to implement a sort of "parallel wait".
collectB :: (Serialize a, Serialize b) => Auto m (Blip a, Blip b) (Blip (a, b))

-- | The non-serializing/non-resuming version of <a>collectB</a>.
collectB_ :: Auto m (Blip a, Blip b) (Blip (a, b))

-- | A blip stream that listens to an input blip stream and emits after the
--   input stream emits a given number of times. Emits with a list of all
--   received emitted values.
collectBs :: Serialize a => Int -> Auto m (Blip a) (Blip [a])

-- | The non-serializing/non-resuming version of <a>collectBs</a>.
collectBs_ :: Int -> Auto m (Blip a) (Blip [a])

-- | <a>Collapses</a> a blip stream of blip streams into single blip
--   stream. that emits whenever the inner-nested stream emits.
joinB :: Auto m (Blip (Blip a)) (Blip a)

-- | <tt><a>takeB</a> n</tt> allows only the first <tt>n</tt> emissions to
--   pass; it suppresses all of the rest.
takeB :: Int -> Auto m (Blip a) (Blip a)

-- | Allow all emitted valuesto pass until the first that fails the
--   predicate.
takeWhileB :: (a -> Bool) -> Auto m (Blip a) (Blip a)

-- | <tt><a>dropB</a> n</tt> suppresses the first <tt>n</tt> emissions from
--   upstream and passes through the rest uninhibited.
dropB :: Int -> Auto m (Blip a) (Blip a)

-- | Suppress all emited values until the first one satisfying the
--   predicate, then allow the rest to pass through.
dropWhileB :: (a -> Bool) -> Auto m (Blip a) (Blip a)

-- | Accumulates all emissions in the incoming blip stream with a "folding
--   function", with a given starting value. <tt>b -&gt; a -&gt; b</tt>,
--   with a starting <tt>b</tt>, gives <tt><a>Auto</a> m (<a>Blip</a> a)
--   (<a>Blip</a> b)</tt>.
--   
--   The resulting blip stream will emit every time the input stream emits,
--   but with the "accumulated value".
--   
--   Basically <a>accum</a>, but on blip stream emissions.
--   
--   <pre>
--   accumB f x0 == perBlip (accum f x0)
--   </pre>
accumB :: Serialize b => (b -> a -> b) -> b -> Auto m (Blip a) (Blip b)

-- | The non-serializing/non-resuming version of <a>accumB</a>.
accumB_ :: (b -> a -> b) -> b -> Auto m (Blip a) (Blip b)

-- | The output is the result of folding up every emitted value seen thus
--   far, with the given folding function and initial value.
--   
--   <pre>
--   scanB f x0 == holdWith x0 . accumB f x0
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let a = scanB (+) 0 . eachAt 2 [1,2,3]
--   
--   &gt;&gt;&gt; take 8 . streamAuto' a $ repeat ()
--   [0, 1, 1, 3, 3, 6, 6, 6, 6]
--   </pre>
scanB :: Serialize b => (b -> a -> b) -> b -> Auto m (Blip a) b

-- | The non-serializing/non-resuming version of <a>scanB</a>.
scanB_ :: (b -> a -> b) -> b -> Auto m (Blip a) b

-- | The output is the <a>mconcat</a> (monoid sum) of all emitted values
--   seen this far.
mscanB :: (Monoid a, Serialize a) => Auto m (Blip a) a

-- | The non-serializing/non-resuming version of <a>mscanB</a>.
mscanB_ :: Monoid a => Auto m (Blip a) a

-- | The output is the number of emitted values received from the upstream
--   blip stream so far.
countB :: Auto m (Blip a) Int

-- | Blip stream that emits whenever the input value changes. Emits with
--   the new value.
--   
--   Warning: Note that, when composed on a value that is never expected to
--   keep the same value twice, this technically breaks blip semantics.
onChange :: (Serialize a, Eq a) => Auto m a (Blip a)

-- | The non-serializing/non-resumable version of <a>onChange</a>.
onChange_ :: Eq a => Auto m a (Blip a)

-- | Blip stream that emits whenever the predicate applied to the input
--   switches from false to true. Emits with the triggering input value.
became :: Serialize a => (a -> Bool) -> Auto m a (Blip a)

-- | The non-serializing/non-resumable version of <a>became</a>.
became_ :: (a -> Bool) -> Auto m a (Blip a)

-- | Like <a>became</a>, but emits a '()' instead of the triggering input
--   value.
--   
--   Useful because it can be serialized without the output needing a
--   <a>Serialize</a> instance.
became' :: (a -> Bool) -> Auto m a (Blip ())

-- | Blip stream that emits whenever the predicate applied to the input
--   switches from true to false. Emits with the triggering input value.
noLonger :: Serialize a => (a -> Bool) -> Auto m a (Blip a)

-- | The non-serializing/non-resumable version of <a>noLonger</a>.
noLonger_ :: (a -> Bool) -> Auto m a (Blip a)

-- | Like <a>noLonger</a>, but emits a '()' instead of the triggering input
--   value.
--   
--   Useful because it can be serialized without the output needing a
--   <a>Serialize</a> instance.
noLonger' :: (a -> Bool) -> Auto m a (Blip ())

-- | Blip stream that emits whenever the predicate applied to the input
--   switches from true to false or false to true. Emits with the
--   triggering input value.
onFlip :: (Serialize a, Monad m) => (a -> Bool) -> Auto m a (Blip a)

-- | The non-serializing/non-resumable version of <a>onFlip</a>.
onFlip_ :: Monad m => (a -> Bool) -> Auto m a (Blip a)

-- | Like <a>onFlip</a>, but emits a <a>Bool</a> instead of the triggering
--   input value. An emitted <a>True</a> indicates that the predicate just
--   became true; an emitted <a>False</a> indicates that the predicate just
--   became false.
--   
--   Useful because it can be serialized without the output needing a
--   <a>Serialize</a> instance.
onFlip' :: Monad m => (a -> Bool) -> Auto m a (Blip Bool)


-- | This module provides combinators and utilities for working with the
--   semantic concept of "intervals": an <a>Auto</a> whose output stream is
--   "on" or "off" for (conceputally) contiguous chunks of time.
module Control.Auto.Interval

-- | Represents a relationship between an input and an output, where the
--   output can be "on" or "off" (using <a>Just</a> and <a>Nothing</a>) for
--   contiguous chunks of time.
--   
--   "Just" a type alias for <tt><a>Auto</a> m a (<a>Maybe</a> b)</tt>. If
--   you ended up here with a link...no worries! If you see
--   <tt><a>Interval</a> m a b</tt>, just think <tt><a>Auto</a> m a
--   (<a>Maybe</a> b)</tt> for type inference/type checking purposes.
--   
--   If you see something of type <a>Interval</a>, you can rest assured
--   that it has "interval semantics" --- it is on and off for meaningfully
--   contiguous chunks of time, instead of just on and off willy nilly. If
--   you have a function that expects an <a>Interval</a>, then the function
--   expects its argument to behave in this way.
type Interval m a b = Auto m a (Maybe b)

-- | <a>Interval</a>, specialized with <tt>Identity</tt> as its underlying
--   <a>Monad</a>. Analogous to <a>Auto'</a> for <a>Auto</a>.
type Interval' a b = Auto' a (Maybe b)

-- | The output stream is alwayas off, regardless of the input.
--   
--   Note that any monadic effects of the input <a>Auto</a> when composed
--   with <a>off</a> are still executed, even though their result value is
--   suppressed.
--   
--   <pre>
--   off == pure Nothing
--   </pre>
off :: Interval m a b

-- | The output stream is always on, with exactly the value of the
--   corresponding input.
--   
--   <pre>
--   toOn == arr Just
--   </pre>
toOn :: Interval m a a

-- | An "interval collapsing" <a>Auto</a>. A stream of on/off values comes
--   in; the output is the value of the input when the input is on, and the
--   "default value" when the input is off.
--   
--   Much like <a>fromMaybe</a> from <a>Data.Maybe</a>.
--   
--   <pre>
--   fromInterval d = arr (fromMaybe d)
--   </pre>
fromInterval :: a -> Auto m (Maybe a) a

-- | An "interval collapsing" <a>Auto</a>. A stream of on/off values comes
--   in; when the input is off, the output is the "default value". When the
--   input is off, the output is the given function applied to the "on"
--   value.
--   
--   Much like <a>maybe</a> from <a>Data.Maybe</a>.
--   
--   <pre>
--   fromIntervalWith d f = arr (maybe d f)
--   </pre>
fromIntervalWith :: b -> (a -> b) -> Auto m (Maybe a) b

-- | For <tt><a>onFor</a> n</tt>, the first <tt>n</tt> items in the output
--   stream are always "on" (passing through with exactly the value of the
--   corresponding input); for the rest, the output stream is always "off",
--   suppressing all input values forevermore.
--   
--   If a number less than 0 is passed, 0 is used.
onFor :: Int -> Interval m a a

-- | For <tt><a>offFor</a> n</tt>, the first <tt>n</tt> items in the output
--   stream are always "off", suppressing all input; for the rest, the
--   output stream is always "on", outputting exactly the value of the
--   corresponding input.
offFor :: Int -> Interval m a a

-- | A combination of <a>onFor</a> and <a>offFor</a>; for <tt><a>window</a>
--   b e</tt>, the output stream will be "on" from item <tt>b</tt> to item
--   <tt>e</tt> inclusive with the value of the corresponding input; for
--   all other times, the output stream is always off, suppressing any
--   input.
window :: Int -> Int -> Interval m a a

-- | The output is "on" with exactly the value of he corresponding input
--   when the input passes the predicate, and is "off" otherwise.
--   
--   <pre>
--   &gt;&gt;&gt; let a = whenI (\x -&gt; x &gt;= 2 &amp;&amp; x &lt;= 4)
--   
--   &gt;&gt;&gt; streamAuto' a [1..6]
--   [Nothing, Just 2, Just 3, Just 4, Nothing, Nothing]
--   </pre>
--   
--   Careful when using this; you could exactly create an <a>Interval</a>
--   that "breaks" "interval semantics"; for example, 'whenI even', when
--   you know your input stream does not consist of chunks of even numbers
--   and odd numbers at a time.
whenI :: (a -> Bool) -> Interval m a a

-- | Like <a>whenI</a>, but only allows values to pass whenever the input
--   does not satisfy the predicate. Blocks whenever the predicate is true.
--   
--   <pre>
--   &gt;&gt;&gt; let a = unlessI (\x -&gt; x &lt; 2 || x &gt; 4)
--   
--   &gt;&gt;&gt; steamAuto' a [1..6]
--   [Nothing, Just 2, Just 3, Just 4, Nothing, Nothing]
--   </pre>
unlessI :: (a -> Bool) -> Interval m a a

-- | Forks a common input stream between an <a>Interval</a> and an
--   <a>Auto</a>, and returns, itself, a normal non-interval <a>Auto</a>..
--   If the output of the first one is "on", the output of the whole thing
--   is that "on" value. Otherwise, the output is exactly that of the
--   second one.
--   
--   <pre>
--   &gt;&gt;&gt; let a1 = (onFor 2 . pure "hello") &lt;|!&gt; pure "world"
--   
--   &gt;&gt;&gt; take 5 . streamAuto' a1 $ repeat ()
--   ["hello", "hello", "world", "world", "world"]
--   </pre>
--   
--   This one is neat because it associates from the right, so it can be
--   "chained":
--   
--   <pre>
--   &gt;&gt;&gt; let a2 = onFor 2 . pure "hello"
--           &lt;|!&gt; onFor 4 . pure "world"
--           &lt;|!&gt; pure "goodbye!"
--   
--   &gt;&gt;&gt; take 6 . streamAuto' a2 $ repeat ()
--   ["hello", "hello", "world", "world", "goodbye!", "goodbye!"]
--   </pre>
--   
--   <pre>
--   a &lt;|!&gt; b &lt;|!&gt; c
--   </pre>
--   
--   associates as
--   
--   <pre>
--   a &lt;|!&gt; (b &lt;|!&gt; c)
--   </pre>
--   
--   So using this, you can "chain" a bunch of choices between intervals,
--   and then at the right-most, "final" one, provide the default behavior.
--   
--   Warning: If your underlying monad produces effects, remember that
--   <i>both</i> <a>Auto</a>s are run at every step, along with any monadic
--   effects, regardless of whether they are "on" or "off".
(<|!>) :: Monad m => Interval m a b -> Auto m a b -> Auto m a b
infixr 3 <|!>

-- | Forks a common input stream between the two <a>Interval</a>s and
--   returns, itself, an <a>Interval</a>. If the output of the first one is
--   "on", the whole thing is on with that output. Otherwise, the output is
--   exactly that of the second one.
--   
--   <pre>
--   &gt;&gt;&gt; let a = (onFor 2 . pure "hello") &lt;|?&gt; (onFor 4 . pure "world")
--   
--   &gt;&gt;&gt; take 5 . streamAuto' a $ repeat ()
--   [Just "hello", Just "hello", Just "world", Just "world", Nothing]
--   </pre>
--   
--   You can drop the parentheses, because of precedence; the above could
--   have been written as:
--   
--   <pre>
--   &gt;&gt;&gt; let a' = onFor 2 . pure "hello" &lt;|?&gt; onFor 4 . pure "world"
--   </pre>
--   
--   Warning: If your underlying monad produces effects, remember that
--   <i>both</i> <a>Auto</a>s are run at every step, along with any monadic
--   effects, regardless of whether they are "on" or "off".
--   
--   Note that more often than not, <a>&lt;|!&gt;</a> is probably more
--   useful. This is useful only in the case that you really, really want
--   an interval at the end of it all.
(<|?>) :: Monad m => Interval m a b -> Interval m a b -> Interval m a b
infixr 3 <|?>

-- | Forks an input stream between all <a>Interval</a>s in the list. The
--   result is an <a>Interval</a> whose output is "on" when any of the
--   original <a>Interval</a>s is on, with the value of the <i>first</i>
--   "on" one.
--   
--   <pre>
--   chooseInterval == foldr (&lt;|?&gt;) off
--   </pre>
chooseInterval :: Monad m => [Interval m a b] -> Interval m a b

-- | Forks an input stream between all <a>Interval</a>s in the list, plus a
--   "default <a>Auto</a>. The output is the value of the first "on"
--   <a>Interval</a>; if there isn't any, the output from the "default
--   <a>Auto</a>" is used.
--   
--   <pre>
--   choose == foldr (&lt;|!&gt;)
--   </pre>
choose :: Monad m => Auto m a b -> [Interval m a b] -> Auto m a b

-- | Takes two input streams --- a stream of normal values, and a blip
--   stream. Before the first emitted value of the input blip stream, the
--   output is always "off", suppressing all inputs. <i>After</i> the first
--   emitted value of the input blip stream, the output is always "on" with
--   the corresponding value of the first input stream.
--   
--   <pre>
--   &gt;&gt;&gt; let a = after . (count &amp;&amp;&amp; inB 3)
--   
--   &gt;&gt;&gt; take 6 . streamAuto' a $ repeat ()
--   [Nothing, Nothing, Just 2, Just 3, Just 4, Just 5]
--   </pre>
--   
--   (<tt>count</tt> is the <a>Auto</a> that ignores its input and outputs
--   the current step count at every step, and <tt><tt>inB</tt> 3</tt> is
--   the <a>Auto</a> generating a blip stream that emits at the third
--   step.)
--   
--   Be careful to remember that in the above example, <tt>count</tt> is
--   still "run" at every step, and is progressed (and if it were an
--   <a>Auto</a> with monadic effects, they would still be executed). It
--   just isn't allowed to pass its output values through <a>after</a>
--   until the blip stream emits.
after :: Interval m (a, Blip b) a

-- | Takes two input streams --- a stream of normal values, and a blip
--   stream. Before the first emitted value of the input blip stream, the
--   output is always "on" with the corresponding value of the first input
--   stream. <i>After</i> the first emitted value of the input blip stream,
--   the output will be "off" forever, suppressing all input.
--   
--   <pre>
--   &gt;&gt;&gt; let a = before . (count &amp;&amp;&amp; inB 3)
--   
--   &gt;&gt;&gt; take 5 . streamAuto' a $ repeat ()
--   [Just 0, Just 1, Nothing, Nothing, Nothing]
--   </pre>
--   
--   (<tt>count</tt> is the <a>Auto</a> that ignores its input and outputs
--   the current step count at every step, and <tt><tt>inB</tt> 3</tt> is
--   the <a>Auto</a> generating a blip stream that emits at the third
--   step.)
--   
--   Be careful to remember that in the above example, <tt>count</tt> is
--   still "run" at every step, and is progressed (and if it were an
--   <a>Auto</a> with monadic effects, they would still be executed). It
--   just isn't allowed to pass its output values through <a>before</a>
--   after the blip stream emits.
before :: Interval m (a, Blip b) a

-- | Takes three input streams: a stream of normal values, a blip stream of
--   "turning-on" blips, and a blip stream of "turning-off" blips. After
--   the first blip stream emits, the output will switch to "on" with the
--   value of the first input stream. After the second blip stream emits,
--   the output will switch to "off", supressing all inputs. An emission
--   from the first stream toggles this "on"; an emission from the second
--   stream toggles this "off".
--   
--   <pre>
--   &gt;&gt;&gt; let a = between . (count &amp;&amp;&amp; (inB 3 &amp;&amp;&amp; inB 5))
--   
--   &gt;&gt;&gt; take 7 . streamAuto' a $ repeat ()
--   [Nothing, Nothing, Just 2, Just 3, Nothing, Nothing, Nothing]
--   </pre>
between :: Interval m (a, (Blip b, Blip c)) a

-- | The output is constantly "on" with the last emitted value of the input
--   blip stream. However, before the first emitted value, it is "off".
--   value of the input blip stream. From then on, the output is always the
--   last emitted value
--   
--   <pre>
--   &gt;&gt;&gt; let a = hold . inB 3
--   
--   &gt;&gt;&gt; streamAuto' a [1..5]
--   [Nothing, Nothing, Just 3, Just 3, Just 3]
--   </pre>
--   
--   If you want an <tt><a>Auto</a> m (<a>Blip</a> a) a</tt> (no
--   <a>Nothing</a>...just a "default value" before everything else), then
--   you can use <tt>holdWith</tt> from <a>Control.Auto.Blip</a>...or also
--   just <a>hold</a> with <a>&lt;|!&gt;</a> or <a>fromInterval</a>.
hold :: Serialize a => Interval m (Blip a) a

-- | The non-serializing/non-resuming version of <a>hold</a>.
hold_ :: Interval m (Blip a) a

-- | For <tt><a>holdFor</a> n</tt>, The output is only "on" if there was an
--   emitted value from the input blip stream in the last <tt>n</tt> steps.
--   Otherwise, is off.
--   
--   Like <a>hold</a>, but it only "holds" the last emitted value for the
--   given number of steps.
--   
--   <pre>
--   &gt;&gt;&gt; let a = holdFor 2 . inB 3
--   
--   &gt;&gt;&gt; streamAuto' a [1..7]
--   [Nothing, Nothing, Just 3, Just 3, Nothing, Nothing, Nothing]
--   </pre>
holdFor :: Serialize a => Int -> Interval m (Blip a) a

-- | The non-serializing/non-resuming version of <a>holdFor</a>.
holdFor_ :: Int -> Interval m (Blip a) a

-- | <a>Stretches</a> the last "on"/<a>Just</a> input over the entire range
--   of following "off"/<a>Nothing</a> inputs. Holds on to the last
--   <a>Just</a> until another one comes along.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' holdJusts [Nothing, Just 1, Just 3, Nothing, Nothing, Just 5]
--   [Nothing, Just 1, Just 3, Just 3, Just 3, Just 5]
--   </pre>
holdJusts :: Serialize a => Interval m (Maybe a) a

-- | The non-resuming/non-serializing version of <a>holdJusts</a>.
holdJusts_ :: Interval m (Maybe a) a

-- | <a>Lifts</a> an <tt><a>Auto</a> m a b</tt> (transforming <tt>a</tt>s
--   into <tt>b</tt>s) into an <tt><a>Auto</a> m (<a>Maybe</a> a)
--   (<a>Maybe</a> b)</tt> (or, <tt><a>Interval</a> m (<a>Maybe</a> a)
--   b</tt>, transforming <i>intervals</i> of <tt>a</tt>s into
--   <i>intervals</i> of <tt>b</tt>.
--   
--   It does this by running the <a>Auto</a> as normal when the input is
--   "on", and freezing it<i>being "off" when the input is </i>off/.
--   
--   <pre>
--   &gt;&gt;&gt; let a1 = during (sumFrom 0) . onFor 2 . pure 1
--   
--   &gt;&gt;&gt; take 5 . streamAuto' a1 $ repeat ()
--   [Just 1, Just 2, Nothing, Nothing, Nothing]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let a2 = during (sumFrom 0) . offFor 2 . pure 1
--   
--   &gt;&gt;&gt; take 5 . streamAuto' a2 $ repeat ()
--   [Nothing, Nothing, Just 1, Just 2, Just 3]
--   </pre>
--   
--   (Remember that <tt><a>pure</a> x</tt> is the <a>Auto</a> that ignores
--   its input and constantly just pumps out <tt>x</tt> at every step)
--   
--   Note the difference between putting the <tt>sumFrom</tt> "after" the
--   <a>offFor</a> in the chain with <a>during</a> (like the previous
--   example) and putting the <tt>sumFrom</tt> "before":
--   
--   <pre>
--   &gt;&gt;&gt; let a3 = offFor 2 . sumFrom 0 . pure 1
--   
--   &gt;&gt;&gt; take 5 . streamAuto' a3 $ repeat ()
--   [Nothing, Nothing, Just 3, Just 4, Just 5]
--   </pre>
--   
--   In the first case (with <tt>a2</tt>), the output of <tt><a>pure</a>
--   1</tt> was suppressed by <a>offFor</a>, and <tt><a>during</a>
--   (<tt>sumFrom</tt> 0)</tt> was only summing on the times that the 1's
--   were "allowed through"...so it only "starts counting" on the third
--   step.
--   
--   In the second case (with <tt>a3</tt>), the output of the
--   <tt><a>pure</a> 1</tt> is never suppressed, and went straight into the
--   <tt><tt>sumFrom</tt> 0</tt>. <tt>sumFrom</tt> is always summing, the
--   entire time. The final output of that <tt><tt>sumFrom</tt> 0</tt> is
--   suppressed at the end with <tt><a>offFor</a> 2</tt>.
during :: Monad m => Auto m a b -> Interval m (Maybe a) b

-- | Composes two <a>Interval</a>s, the same way that <a>.</a> composes two
--   <a>Auto</a>s:
--   
--   <pre>
--   (.)   :: Auto     m b c -&gt; Auto     m a b -&gt; Auto     m a c
--   compI :: Interval m b c -&gt; Interval m a b -&gt; Interval m a c
--   </pre>
--   
--   Basically, if any <a>Interval</a> in the chain is "off", then the
--   entire rest of the chain is "skipped", short-circuiting a la
--   <a>Maybe</a>.
--   
--   (Users of libraries with built-in inhibition semantics like Yampa and
--   netwire might recognize this as the "default" composition in those
--   other libraries)
--   
--   As a contrived example, how about an <a>Auto</a> that only allows
--   values through during a window...between, say, the second and fourth
--   steps:
--   
--   <pre>
--   &gt;&gt;&gt; let window' start dur = onFor dur `compI` offFor (start - 1)
--   
--   &gt;&gt;&gt; streamAuto' (window' 2 3)
--   [Nothing, Just 2, Just 3, Just 4, Nothing, Nothing]
--   </pre>
compI :: Monad m => Interval m b c -> Interval m a b -> Interval m a c
infixr 1 `compI`

-- | <a>Lifts</a> (more technically, "binds") an <tt><a>Interval</a> m a
--   b</tt> into an <tt><a>Interval</a> m (<a>Maybe</a> a) b</tt>.
--   
--   Does this by running the <a>Auto</a> as normal when the input is "on",
--   and freezing it<i>being "off" when the input is </i>off/.
--   
--   It's kind of like <a>during</a>, but the resulting <tt><a>Maybe</a>
--   (<a>Maybe</a> b))</tt> is "joined" back into a <tt><a>Maybe</a>
--   b</tt>.
--   
--   <pre>
--   bindI a == fmap join (during a)
--   </pre>
--   
--   This is really an alternative formulation of <a>compI</a>; typically,
--   you will be using <a>compI</a> more often, but this form can also be
--   useful (and slightly more general). Note that:
--   
--   <pre>
--   bindI f == compI f id
--   </pre>
--   
--   This combinator allows you to properly "chain" ("bind") together
--   series of inhibiting <a>Auto</a>s. If you have an <tt><a>Interval</a>
--   m a b</tt> and an <tt><a>Interval</a> m b c</tt>, you can chain them
--   into an <tt><a>Interval</a> m a c</tt>.
--   
--   <pre>
--   f             :: <a>Interval</a> m a b
--   g             :: <a>Interval</a> m b c
--   <a>bindI</a> g . f :: <a>Interval</a> m a c
--   </pre>
--   
--   (Users of libraries with built-in inhibition semantics like Yampa and
--   netwire might recognize this as the "default" composition in those
--   other libraries)
--   
--   See <a>compI</a> for examples of this use case.
bindI :: Monad m => Interval m a b -> Interval m (Maybe a) b


-- | This module contains various <a>Auto</a>s that act as "producing"
--   streams; they all ignore their input streams and produce output
--   streams through a pure or monadic process.
module Control.Auto.Generate

-- | An <a>Interval</a> that ignores the input stream and just outputs
--   items from the given list. Is "on" as long as there are still items in
--   the list left, and "off" after there is nothing left in the list to
--   output.
--   
--   Serializes itself by storing the entire rest of the list in binary, so
--   if your list is long, it might take up a lot of space upon storage. If
--   your list is infinite, it makes an infinite binary, so be careful!
--   
--   <a>fromLongList</a> can be used for longer lists or infinite lists;
--   or, if your list can be boild down to an <tt>unfoldr</tt>, you can use
--   <a>unfold</a>.
--   
--   <ul>
--   <li>Storing: O(n) time and space on length of remaining list</li>
--   <li>Loading: O(1) time in the number of times the <a>Auto</a> has been
--   stepped + O(n) time in the length of the remaining list.</li>
--   </ul>
fromList :: Serialize b => [b] -> Interval m a b

-- | The non-resuming/non-serializing version of <a>fromList</a>.
fromList_ :: [b] -> Interval m a b

-- | A version of <a>fromList</a> that is safe for long or infinite lists,
--   or lists with unserializable elements.
--   
--   There is a small cost in the time of loading/resuming, which is
--   <tt>O(n)</tt> on the number of times the Auto had been stepped at the
--   time of saving. This is because it has to drop the <tt>n</tt> first
--   elements in the list, to "resume" to the proper position.
--   
--   <ul>
--   <li>Storing: O(1) time and space on the length of the remaining
--   list</li>
--   <li>Loading: O(n) time on the number of times the <a>Auto</a> has been
--   stepped, maxing out at O(n) on the length of the entire input
--   list.</li>
--   </ul>
fromLongList :: [b] -> Interval m a b

-- | Lift a value.
pure :: Applicative f => a -> f a

-- | To get every output, executes the monadic action and returns the
--   result as the output. Always ignores input.
--   
--   This is basically like an "effectful" <a>pure</a>:
--   
--   <pre>
--   <a>pure</a>   :: b   -&gt; <a>Auto</a> m a b
--   <a>effect</a> :: m b -&gt; <a>Auto</a> m a b
--   </pre>
--   
--   The output of <a>pure</a> is always the same, and the output of
--   <a>effect</a> is always the result of the same monadic action. Both
--   ignore their inputs.
--   
--   Fun times when the underling <a>Monad</a> is, for instance,
--   <tt>Reader</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; let a = effect ask    :: Auto (Reader b) a b
--   
--   &gt;&gt;&gt; let r = evalAuto a () :: Reader b b
--   
--   &gt;&gt;&gt; runReader r "hello"
--   "hello"
--   
--   &gt;&gt;&gt; runReader r 100
--   100
--   </pre>
--   
--   If your underling monad has effects (<a>IO</a>, <tt>State</tt>,
--   <a>Maybe</a>, <tt>Writer</tt>, etc.), then it might be fun to take
--   advantage of <a>*&gt;</a> from <a>Control.Applicative</a> to "tack on"
--   an effect to a normal <a>Auto</a>:
--   
--   <pre>
--   &gt;&gt;&gt; let a = effect (modify (+1)) *&gt; sumFrom 0 :: Auto (State Int) Int Int
--   
--   &gt;&gt;&gt; let st = streamAuto a [1..10]
--   
--   &gt;&gt;&gt; let (ys, s') = runState st 0
--   
--   &gt;&gt;&gt; ys
--   [1,3,6,10,15,21,28,36,45,55]
--   
--   &gt;&gt;&gt; s'
--   10
--   </pre>
--   
--   Our <a>Auto</a> <tt>a</tt> behaves exactly like <tt><tt>sumFrom</tt>
--   0</tt>, except at each step, it also increments the underlying/global
--   state by one. It is <tt><tt>sumFrom</tt> 0</tt> with an "attached
--   effect".
effect :: m b -> Auto m a b

-- | Analogous to <a>iterate</a> from <a>Prelude</a>. Keeps accumulator
--   value and continually applies the function to the accumulator at every
--   step, outputting the result.
--   
--   The first result is the initial accumulator value.
--   
--   <pre>
--   &gt;&gt;&gt; take 10 . streamAuto' (iterator (*2) 1) $ repeat ()
--   [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
--   </pre>
iterator :: Serialize b => (b -> b) -> b -> Auto m a b

-- | The non-resuming/non-serializing version of <a>iterator</a>.
iterator_ :: (b -> b) -> b -> Auto m a b

-- | Like <a>iterator</a>, but with a monadic function.
iteratorM :: (Serialize b, Monad m) => (b -> m b) -> b -> Auto m a b

-- | The non-resuming/non-serializing version of <a>iteratorM</a>.
iteratorM_ :: Monad m => (b -> m b) -> b -> Auto m a b

-- | Given a function from discrete enumerable inputs, iterates through all
--   of the results of that function.
--   
--   <pre>
--   &gt;&gt;&gt; take 10 . streamAuto' (discreteF (^2) 0) $ repeat ()
--   [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
--   </pre>
discreteF :: (Enum c, Serialize c) => (c -> b) -> c -> Auto m a b

-- | The non-resuming/non-serializing version of <a>discreteF</a>.
discreteF_ :: Enum c => (c -> b) -> c -> Auto m a b

-- | Analogous to <tt>unfoldr</tt> from <a>Prelude</a>. Creates an
--   <a>Interval</a> (that ignores its input) by maintaining an internal
--   accumulator of type <tt>c</tt> and, at every step, applying to the
--   unfolding function to the accumulator. If the result is
--   <a>Nothing</a>, then the <a>Interval</a> will turn "off" forever
--   (output <a>Nothing</a> forever); if the result is <tt><a>Just</a> (y,
--   acc)</tt>, then it will output <tt>y</tt> and store <tt>acc</tt> as
--   the new accumulator.
--   
--   Given an initial accumulator.
--   
--   <pre>
--   &gt;&gt;&gt; let countFromTil n m = flip unfold n $ \i -&gt; if i &lt;= m
--                                                      then Just (i, i+1)
--                                                      else Nothing
--   
--   &gt;&gt;&gt; take 8 . streamAuto' (countFromTil 5 10) $ repeat ()
--   [Just 5, Just 6, Just 7, Just 8, Just 9, Just 10, Nothing, Nothing]
--   </pre>
--   
--   <tt><a>unfold</a> f c0</tt> behaves like <tt><tt>overList</tt>
--   (<tt>unfoldr</tt> f c0)</tt>.
unfold :: Serialize c => (c -> Maybe (b, c)) -> c -> Interval m a b

-- | The non-resuming &amp; non-serializing version of <a>unfold</a>.
unfold_ :: (c -> Maybe (b, c)) -> c -> Interval m a b

-- | Like <a>unfold</a>, but the unfolding function is monadic.
unfoldM :: (Serialize c, Monad m) => (c -> m (Maybe (b, c))) -> c -> Interval m a b

-- | The non-resuming &amp; non-serializing version of <a>unfoldM</a>.
unfoldM_ :: Monad m => (c -> m (Maybe (b, c))) -> c -> Interval m a b

-- | Continually enumerate from the starting value, using <a>succ</a>.
enumFromA :: (Serialize b, Enum b) => b -> Auto m a b

-- | The non-serializing/non-resuming version of <a>enumFromA</a>.
enumFromA_ :: Enum b => b -> Auto m a b


-- | This module exports the preferred ways of interacting with the
--   underlying <a>Monad</a> of the <a>Auto</a> type, including accessing,
--   executing, and manipulating such effects.
module Control.Auto.Effects

-- | Applies the given "monadic function" (function returning a monadic
--   action) to every incoming item; the result is the result of executing
--   the action returned.
--   
--   Note that this essentially lifts a "Kleisli arrow"; it's like
--   <tt>arr</tt>, but for "monadic functions" instead of normal functions:
--   
--   <pre>
--   arr  :: (a -&gt; b)   -&gt; Auto m a b
--   arrM :: (a -&gt; m b) -&gt; Auto m a b
--   </pre>
--   
--   <pre>
--   arrM f . arrM g == arrM (f &lt;=&lt; g)
--   </pre>
--   
--   One neat trick you can do is that you can "tag on effects" to a normal
--   <a>Auto</a> by using <a>*&gt;</a> from <a>Control.Applicative</a>. For
--   example:
--   
--   <pre>
--   &gt;&gt;&gt; let a = arrM print *&gt; sumFrom 0
--   
--   &gt;&gt;&gt; ys &lt;- streamAuto a [1..5]
--   1                -- IO output
--   2
--   3
--   4
--   5
--   
--   &gt;&gt;&gt; ys
--   [1,3,6,10,15]    -- the result
--   </pre>
--   
--   Here, <tt>a</tt> behaves "just like" <tt><tt>sumFrom</tt>
--   0</tt>...except, when you step it, it prints out to stdout as a
--   side-effect. We just gave automatic stdout logging behavior!
arrM :: (a -> m b) -> Auto m a b

-- | To get every output, executes the monadic action and returns the
--   result as the output. Always ignores input.
--   
--   This is basically like an "effectful" <a>pure</a>:
--   
--   <pre>
--   <a>pure</a>   :: b   -&gt; <a>Auto</a> m a b
--   <a>effect</a> :: m b -&gt; <a>Auto</a> m a b
--   </pre>
--   
--   The output of <a>pure</a> is always the same, and the output of
--   <a>effect</a> is always the result of the same monadic action. Both
--   ignore their inputs.
--   
--   Fun times when the underling <a>Monad</a> is, for instance,
--   <tt>Reader</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; let a = effect ask    :: Auto (Reader b) a b
--   
--   &gt;&gt;&gt; let r = evalAuto a () :: Reader b b
--   
--   &gt;&gt;&gt; runReader r "hello"
--   "hello"
--   
--   &gt;&gt;&gt; runReader r 100
--   100
--   </pre>
--   
--   If your underling monad has effects (<a>IO</a>, <tt>State</tt>,
--   <a>Maybe</a>, <tt>Writer</tt>, etc.), then it might be fun to take
--   advantage of <a>*&gt;</a> from <a>Control.Applicative</a> to "tack on"
--   an effect to a normal <a>Auto</a>:
--   
--   <pre>
--   &gt;&gt;&gt; let a = effect (modify (+1)) *&gt; sumFrom 0 :: Auto (State Int) Int Int
--   
--   &gt;&gt;&gt; let st = streamAuto a [1..10]
--   
--   &gt;&gt;&gt; let (ys, s') = runState st 0
--   
--   &gt;&gt;&gt; ys
--   [1,3,6,10,15,21,28,36,45,55]
--   
--   &gt;&gt;&gt; s'
--   10
--   </pre>
--   
--   Our <a>Auto</a> <tt>a</tt> behaves exactly like <tt><tt>sumFrom</tt>
--   0</tt>, except at each step, it also increments the underlying/global
--   state by one. It is <tt><tt>sumFrom</tt> 0</tt> with an "attached
--   effect".
effect :: m b -> Auto m a b

-- | The input stream is a stream of monadic actions, and the output stream
--   is the result of their executions, through executing them.
effects :: Monad m => Auto m (m a) a

-- | Maps one blip stream to another; replaces every emitted value with the
--   result of the monadic function, executing it to get the result.
arrMB :: Monad m => (a -> m b) -> Auto m (Blip a) (Blip b)

-- | Maps one blip stream to another; replaces every emitted value with the
--   result of a fixed monadic action, run every time an emitted value is
--   received.
effectB :: Monad m => m b -> Auto m (Blip a) (Blip b)

-- | Outputs the identical blip stream that is received; however, every
--   time it sees an emitted value, executes the given monadic action on
--   the side.
execB :: Monad m => m b -> Auto m (Blip a) (Blip a)

-- | The very first output executes a monadic action and uses the result as
--   the output, ignoring all input. From then on, it persistently outputs
--   that first result.
--   
--   Like <a>execOnce</a>, except outputs the result of the action instead
--   of ignoring it.
--   
--   Useful for loading resources in IO on the "first step", like a word
--   list:
--   
--   <pre>
--   dictionary :: Auto IO a [String]
--   dictionary = cache (lines <a>$</a> readFile "wordlist.txt")
--   </pre>
cache :: (Serialize b, Monad m) => m b -> Auto m a b

-- | Always outputs '()', but when asked for the first output, executes the
--   given monadic action.
--   
--   Pretty much like <a>cache</a>, but always outputs '()'.
execOnce :: Monad m => m b -> Auto m a ()

-- | The non-resumable/non-serializable version of <a>cache</a>. Every time
--   the <a>Auto</a> is deserialized/reloaded, it re-executes the action to
--   retrieve the result again.
--   
--   Useful in cases where you want to "re-load" an expensive resource on
--   every startup, instead of saving it to in the save states.
--   
--   <pre>
--   dictionary :: Auto IO a [String]
--   dictionary = cache_ (lines <a>$</a> readFile "dictionary.txt")
--   </pre>
cache_ :: Monad m => m b -> Auto m a b

-- | The non-resumable/non-serializable version of <a>execOnce</a>. Every
--   time the <a>Auto</a> is deserialized/reloaded, the action is
--   re-executed again.
execOnce_ :: Monad m => m b -> Auto m a ()

-- | Swaps out the underlying <a>Monad</a> of an <a>Auto</a> using the
--   given monad morphism "transforming function", a natural
--   transformation.
--   
--   Basically, given a function to "swap out" any <tt>m a</tt> with an
--   <tt>m' a</tt>, it swaps out the underlying monad of the <a>Auto</a>.
--   
--   This forms a functor, so you rest assured in things like this:
--   
--   <pre>
--   hoistA id == id
--   hoistA f a1 . hoistA f a2 == hoistA f (a1 . a2)
--   </pre>
hoistA :: (Monad m, Monad m') => (forall c. m c -> m' c) -> Auto m a b -> Auto m' a b

-- | Generalizes an <tt><a>Auto'</a> a b</tt> to an <tt><a>Auto</a> m a
--   b'</tt> for any <a>Monad</a> <tt>m</tt>, using <tt>hoist</tt>.
--   
--   You generally should be able to avoid using this if you never directly
--   write any <a>Auto'</a>s and always write 'Auto m' parameterized over
--   all <a>Monad</a>s, but...in case you import one from a library or
--   something, you can use this.
generalizeA :: Monad m => Auto' a b -> Auto m a b

-- | <a>Unrolls</a> the underlying <a>ReaderT</a> of an <a>Auto</a> into an
--   <a>Auto</a> that takes in the input "environment" every turn in
--   addition to the normal input.
--   
--   So you can use any <tt><a>ReaderT</a> r m</tt> as if it were an
--   <tt>m</tt>. Useful if you want to compose and create some isolated
--   <a>Auto</a>s with access to an underlying environment, but not your
--   entire program.
--   
--   Also just simply useful as a convenient way to use an <a>Auto</a> over
--   <tt>Reader</tt> with <a>stepAuto</a> and friends.
--   
--   When used with <tt><tt>Reader</tt> r</tt>, it turns an <tt><a>Auto</a>
--   (<tt>Reader</tt> r) a b</tt> into an <tt><a>Auto'</a> (a, r) b</tt>.
runReaderA :: Monad m => Auto (ReaderT r m) a b -> Auto m (a, r) b

-- | Takes an <a>Auto</a> that operates under the context of a read-only
--   environment, an environment value, and turns it into a normal
--   <a>Auto</a> that always "sees" that value when it asks for one.
--   
--   <pre>
--   &gt;&gt;&gt; let a   = effect ask :: Auto (Reader b) a b
--   
--   &gt;&gt;&gt; let rdr = streamAuto' a [1..5] :: Reader b [b]
--   
--   &gt;&gt;&gt; runReader rdr "hey"
--   ["hey", "hey", "hey", "hey", "hey"]
--   </pre>
--   
--   Useful if you wanted to use it inside/composed with an <a>Auto</a>
--   that does not have a global environment:
--   
--   <pre>
--   bar :: Auto' Int String
--   bar = proc x -&gt; do
--       hey &lt;- sealReader (effect ask) "hey" -&lt; ()
--       id -&lt; hey ++ show x
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' bar [1..5]
--   ["hey1", "hey2", "hey3", "hey4", "hey5"]
--   </pre>
--   
--   Note that this version serializes the given <tt>r</tt> environment, so
--   that every time the <a>Auto</a> is reloaded/resumed, it resumes with
--   the originally given <tt>r</tt> environment, ignoring whatever
--   <tt>r</tt> is given to it when trying to resume it. If this is not the
--   behavior you want, use <a>sealReader_</a>.
--   
--   <tt>Reader</tt> is convenient because it allows you to "chain" and
--   "compose" <a>Auto</a>s with a common environment, instead of
--   explicitly passing in values every time. For a convenient way of
--   generating <a>Auto</a>s under <a>ReaderT</a>, and also for some
--   motivating examples, see <a>readerA</a> and <a>runReaderA</a>.
sealReader :: (Monad m, Serialize r) => Auto (ReaderT r m) a b -> r -> Auto m a b

-- | The non-resuming/non-serializing version of <a>sealReader</a>. Does
--   not serialize/reload the <tt>r</tt> environment, so that whenever you
--   "resume" the <a>Auto</a>, it uses the new <tt>r</tt> given when you
--   are trying to resume, instead of loading the originally given one.
--   
--   <i>DOES</i> serialize the actual <a>Auto</a>!
sealReader_ :: Monad m => Auto (ReaderT r m) a b -> r -> Auto m a b

-- | Transforms an <a>Auto</a> on two input streams ( a "normal input"
--   stream <tt>a</tt> and an "environment input stream" <tt>r</tt>) into
--   an <a>Auto</a> on one input stream <tt>a</tt> with an underlying
--   environment <tt>r</tt> through a <tt>Reader</tt> monad.
--   
--   Why is this useful? Well, if you have several <a>Auto</a>s that all
--   take in a side <tt>r</tt> stream, and you want to convey that every
--   single one should get the <i>same</i> <tt>r</tt> at every step, you
--   can instead have all of them pull from a common underlying global
--   environment.
--   
--   Note: Function is the inverse of <a>runReaderA</a>:
--   
--   <pre>
--   <a>readerA</a> . <a>runReaderA</a> == <a>id</a>
--   <a>runReaderA</a> . <a>readerA</a> == <a>id</a>
--   </pre>
readerA :: Monad m => Auto m (a, r) b -> Auto (ReaderT r m) a b

-- | Takes an <a>Auto</a> that operates under the context of a read-only
--   environment, an environment value, and turns it into a normal
--   <a>Auto</a> that always gets its environment value from an
--   <a>MVar</a>.
--   
--   This allows for "hot swapping" configurations. If your whole program
--   runs under a configuration data structure as the environment, you can
--   load the configuration data to the <a>MVar</a> and then "hot swap" it
--   out by just changing the value in the <a>MVar</a> from a different
--   thread.
--   
--   Note that this will block on every "step" until the <a>MVar</a> is
--   readable<i>full</i>has a value, if it does not.
--   
--   Basically a disciplined wrapper/usage over <a>sealReaderM</a>.
sealReaderMVar :: MonadIO m => Auto (ReaderT r m) a b -> MVar r -> Auto m a b

-- | Takes an <a>Auto</a> that operates under the context of a read-only
--   environment, an environment value, and turns it into a normal
--   <a>Auto</a> that always gets its environment value by executing an
--   action every step in the underlying monad.
--   
--   This can be abused to write unmaintainble code really fast if you
--   don't use it in a disciplined way. One possible usage is to query a
--   database in <a>IO</a> (or <a>MonadIO</a>) for a value at every step.
--   If you're using underlying global state, you can use it to query that
--   too, with <a>get</a> or <tt>gets</tt>. You could even use
--   <a>getLine</a>, maybe, to get the result from standard input at every
--   step.
--   
--   One disciplined wrapper around this is <a>sealReaderMVar</a>, where
--   the environment at every step comes from reading an <a>MVar</a>. This
--   can be used to "hot swap" configuration files.
sealReaderM :: Monad m => Auto (ReaderT r m) a b -> m r -> Auto m a b

-- | Transforms an <a>Auto</a> on with two output streams (a "normal output
--   stream" <tt>b</tt>, and a "logging output stream" <tt>w</tt>) into an
--   <a>Auto</a> with just one output stream <tt>a</tt>, funneling the
--   logging stream <tt>w</tt> into an underlying <a>WriterT</a> monad.
--   
--   Note: Function is the inverse of <a>runWriterA</a>:
--   
--   <pre>
--   <a>writerA</a> . <a>runWriterA</a> == <a>id</a>
--   <a>runWriterA</a> . <a>writerA</a> == <a>id</a>
--   </pre>
writerA :: (Monad m, Monoid w) => Auto m a (b, w) -> Auto (WriterT w m) a b

-- | <a>Unrolls</a> the underlying <tt><a>WriterT</a> w m</tt>
--   <a>Monad</a>, so that an <a>Auto</a> that takes in a stream of
--   <tt>a</tt> and outputs a stream of <tt>b</tt> will now output a stream
--   <tt>(b, w)</tt>, where <tt>w</tt> is the "new log" of the underlying
--   <tt>Writer</tt> at every step.
--   
--   Examples:
--   
--   <pre>
--   foo :: Auto (Writer (Sum Int)) Int Int
--   foo = effect (tell 1) *&gt; effect (tell 1) *&gt; sumFrom 0
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let fooWriter = streamAuto foo
--   
--   &gt;&gt;&gt; runWriter $ fooWriter [1..10]
--   ([1,3,6,10,15,21,28,36,45,55], Sum 20)
--   </pre>
--   
--   <tt>foo</tt> increments an underlying counter twice every time it is
--   stepped; its "result" is just the cumulative sum of the inputs.
--   
--   When we "stream" it, we get a <tt>[Int] -&gt; <tt>Writer</tt> (Sum
--   Int) [Int]</tt>...which we can give an input list and
--   <tt>runWriter</tt> it, getting a list of outputs and a "final
--   accumulator state" of 10, for stepping it ten times.
--   
--   However, if we use <a>runWriterA</a> before streaming it, we get:
--   
--   <pre>
--   &gt;&gt;&gt; let fooW = runWriterA foo
--   
--   &gt;&gt;&gt; streamAuto' fooW [1..10]
--   [ (1 , Sum 2), (3 , Sum 2), (6 , Sum 2)
--   , (10, Sum 2), (15, Sum 2), (21, Sum 2), -- ...
--   </pre>
--   
--   Instead of accumulating it between steps, we get to "catch" the
--   <tt>Writer</tt> output at every individual step.
--   
--   We can write and compose our own <a>Auto</a>s under <tt>Writer</tt>,
--   using the convenience of a shared accumulator, and then "use them"
--   with other <a>Auto</a>s:
--   
--   <pre>
--   bar :: Auto' Int Int
--   bar = proc x -&gt; do
--     (y, w) &lt;- runWriterA foo -&lt; x
--     blah &lt;- blah -&lt; w
--   </pre>
--   
--   And now you have access to the underlying accumulator of <tt>foo</tt>
--   to access. There, <tt>w</tt> represents the continually updating
--   accumulator under <tt>foo</tt>, and will be different/growing at every
--   "step".
--   
--   For a convenient way to <i>create</i> an <a>Auto</a> under
--   <a>WriterT</a>, see <a>writerA</a>.
runWriterA :: (Monad m, Monoid w) => Auto (WriterT w m) a b -> Auto m a (b, w)

-- | Takes an <a>Auto</a> that works with underlying global, mutable state,
--   and "seals off the state" from the outside world.
--   
--   An 'Auto (StateT s m) a b' maps a stream of <tt>a</tt> to a stream of
--   <tt>b</tt>, but does so in the context of requiring an initial
--   <tt>s</tt> to start, and outputting a modified <tt>s</tt>.
--   
--   Consider this example <tt>State</tt> <a>Auto</a>:
--   
--   <pre>
--   foo :: Auto (State Int) Int Int
--   foo = proc x -&gt; do
--       execB (modify (+1)) . emitOn odd  -&lt; x
--       execB (modify (*2)) . emitOn even -&lt; x
--       st   &lt;- effect get -&lt; ()
--       sumX &lt;- sumFrom 0  -&lt; x
--       id    -&lt; sumX + st
--   </pre>
--   
--   On every output, the "global" state is incremented if the input is odd
--   and doubled if the input is even. The stream <tt>st</tt> is always the
--   value of the global state at that point. <tt>sumX</tt> is the
--   cumulative sum of the inputs. The final result is the sum of the value
--   of the global state and the cumulative sum.
--   
--   In writing like this, you lose some of the denotative properties
--   because you are working with a global state that updates at every
--   output. You have some benefit of now being able to work with global
--   state, if that's what you wanted I guess.
--   
--   To "run" it, you could use <tt>streamAuto</tt> to get a
--   <tt><tt>State</tt> Int Int</tt>:
--   
--   <pre>
--   &gt;&gt;&gt; let st = streamAuto foo [1..10] :: State Int Int
--   
--   &gt;&gt;&gt; runState st 5
--   ([  7, 15, 19, 36, 42, 75, 83,136,156,277], 222)
--   </pre>
--   
--   (The starting state is 5 and the ending state after all of that is
--   222)
--   
--   However, writing your entire program with global state is a bad bad
--   idea! So, how can you get the "benefits" of having small parts like
--   <tt>foo</tt> be written using <tt>State</tt>, and being able to use it
--   in a program with no global state?
--   
--   Using <a>sealState</a>! Write the part of your program that would like
--   shared global state with <tt>State</tt>...and compose it with the rest
--   as if it doesn't, locking it away!
--   
--   <pre>
--   sealState       :: Auto (State s) a b -&gt; s -&gt; Auto' a b
--   sealState foo 5 :: Auto' Int Int
--   </pre>
--   
--   <pre>
--   bar :: Auto' Int (Int, String)
--   bar = proc x -&gt; do
--       food &lt;- sealState foo 5 -&lt; x
--       id -&lt; (food, show x)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' bar [1..10]
--   [ (7, "1"), (15, "2"), (19, "3"), (36, "4"), (42, "5"), (75, "6") ...
--   </pre>
--   
--   We say that <tt><a>sealState</a> f s0</tt> takes an input stream, and
--   the output stream is the result of running the stream through
--   <tt>f</tt>, first with an initial state of <tt>s0</tt>, and afterwards
--   with each next updated state.
--   
--   If you wanted to "seal" the state and have it be untouchable to the
--   outside world, yet still have a way to "monitor"/"view" it, you can
--   modify the original <a>Auto</a> using <tt>&amp;&amp;&amp;</tt>,
--   <a>effect</a>, and 'get to get a "view" of the state:
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (sealState (foo &amp;&amp;&amp; effect get) 5) [1..10]
--   [(7,6),(15,12),(19,13),(36,26),(42,27),(75,54),(83,55),(146,110),(156,111),(277,222)]
--   </pre>
--   
--   Now, every output of <tt><a>sealState</a> foo 5</tt> is tuplied up
--   with a peek of its state at that point.
--   
--   For a convenient way of "creating" an <a>Auto</a> under <a>StateT</a>
--   in the first place, see <a>stateA</a>.
sealState :: (Monad m, Serialize s) => Auto (StateT s m) a b -> s -> Auto m a b

-- | The non-resuming/non-serializing version of <a>sealState</a>.
sealState_ :: Monad m => Auto (StateT s m) a b -> s -> Auto m a b

-- | <a>Unrolls</a> the underlying <a>StateT</a> of an <a>Auto</a> into an
--   <a>Auto</a> that takes in an input state every turn (in addition to
--   the normal input) and outputs, along with the original result, the
--   modified state.
--   
--   So now you can use any <tt><a>StateT</a> s m</tt> as if it were an
--   <tt>m</tt>. Useful if you want to compose and create some isolated
--   <a>Auto</a>s with access to an underlying state, but not your entire
--   program.
--   
--   Also just simply useful as a convenient way to use an <a>Auto</a> over
--   <tt>State</tt> with <a>stepAuto</a> and friends.
--   
--   When used with <tt><tt>State</tt> s</tt>, it turns an <tt><a>Auto</a>
--   (<tt>State</tt> s) a b</tt> into an <tt><a>Auto'</a> (a, s) (b,
--   s)</tt>.
--   
--   For a convenient way to "generate" an <a>Auto</a> <a>StateT</a>, see
--   <a>stateA</a>
runStateA :: Monad m => Auto (StateT s m) a b -> Auto m (a, s) (b, s)

-- | Transforms an <a>Auto</a> with two input streams and two output
--   streams (a "normal" input <tt>a</tt> output <tt>b</tt> stream, and a
--   "state transforming" side-stream taking in <tt>s</tt> and outputting
--   <tt>s</tt>), abstracts away the <tt>s</tt> stream as a modifcation to
--   an underyling <a>StateT</a> monad. That is, your normal inputs and
--   outputs are now your <i>only</i> inputs and outputs, and your input
--   <tt>s</tt> comes from the underlying global mutable state, and the
--   output <tt>s</tt> goes to update the underlying global mutable state.
--   
--   For example, you might have a bunch of <a>Auto</a>s that interact with
--   a global mutable state:
--   
--   <pre>
--   foo :: Auto (StateT Double m) Int Bool
--   bar :: Auto (StateT Double m) Bool Int
--   baz :: Auto (StateT Double m) Bool String
--   </pre>
--   
--   Where <tt>foo</tt>, <tt>bar</tt>, and <tt>baz</tt> all interact with
--   global mutable state. You'd use them like this:
--   
--   <pre>
--   full :: Auto (StateT Double m) Int String
--   full = proc inp -&gt; do
--       fo &lt;- foo -&lt; inp
--       br &lt;- bar -&lt; fo
--       bz &lt;- baz -&lt; fo
--       id -&lt; replicae br bz
--   </pre>
--   
--   <a>stateA</a> allows you generate a new <tt>Auto</tt> under
--   <a>StateT</a>:
--   
--   <pre>
--   thing :: Auto m (Int, Double) (Bool, Double)
--   stateA thing :: Auto (StateT Double m) Int Bool
--   </pre>
--   
--   So now the two side-channels are interpreted as working with the
--   global state:
--   
--   <pre>
--   full :: Auto (StateT Double m) Int String
--   full = proc inp -&gt; do
--       fo &lt;- foo          -&lt; inp
--       tg &lt;- stateA thing -&lt; inp
--       br &lt;- bar          -&lt; fo || tg
--       bz &lt;- baz          -&lt; fo &amp;&amp; tg
--       id -&lt; replicae br bz
--   </pre>
--   
--   You can then "seal it all up" in the end with an initial state, that
--   keeps on re-running itself with the resulting state every time:
--   
--   <pre>
--   full' :: Double -&gt; Auto m Int String
--   full' = sealState full
--   </pre>
--   
--   Admittedly, this is a bit more esoteric and dangerous (programming
--   with global state? what?) than its components <a>readerA</a> and
--   <a>writerA</a>; I don't actually recommend you programming with global
--   state unless it really is the best solution to your problem...it tends
--   to encourage imperative code/loops, and "unreasonable" and manageable
--   code. See documentation for <tt>sealStateA</tt> for best practices.
--   Basically every bad thing that comes with global mutable state. But,
--   this is provided here for sake of completeness with <a>readerA</a> and
--   <a>writerA</a>.
--   
--   Note: function is the inverse of <tt>runstateA</tt>.
--   
--   <pre>
--   <a>stateA</a> . <a>runStateA</a> == <a>id</a>
--   <a>runStateA</a> . <a>stateA</a> == <a>id</a>
--   </pre>
stateA :: Monad m => Auto m (a, s) (b, s) -> Auto (StateT s m) a b

-- | Like <a>stateA</a>, but assumes that the output is the modified state.
accumA :: Monad m => Auto m (a, s) s -> Auto (StateT s m) a s

-- | <a>Unrolls</a> the underlying <a>Monad</a> of an <a>Auto</a> if it
--   happens to be <a>Traversable</a> ('[]', <a>Maybe</a>, etc.).
--   
--   It can turn, for example, an <tt><a>Auto</a> [] a b</tt> into an
--   <tt><a>Auto'</a> a [b]</tt>; it collects all of the results together.
--   Or an <tt><a>Auto</a> <a>Maybe</a> a b</tt> into an <tt><a>Auto'</a> a
--   (<a>Maybe</a> b)</tt>.
--   
--   This might be useful if you want to make some sort of "underlying
--   inhibiting" <a>Auto</a> where the entire computation might just end up
--   being <a>Nothing</a> in the end. With this, you can turn that
--   possibly-catastrophically-failing <a>Auto</a> (with an underlying
--   <a>Monad</a> of <a>Maybe</a>) into a normal <a>Auto</a>, and use it as
--   a normal <a>Auto</a> in composition with other
--   <a>Auto</a>s...returning <a>Just</a> if your computation succeeded.
--   
--   <pre>
--   <a>runTraversableA</a> :: <a>Auto</a> <a>Maybe</a> a b -&gt; <tt>Interval'</tt> a b
--   </pre>
--   
--   <pre>
--   foo :: Auto Maybe Int Int
--   foo = arrM $ x -&gt; if even x then Just (x <a>div</a> 2) else Nothing
--   
--   bar :: Auto Maybe Int Int
--   bar = arrM Just
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto foo [2,4,6,7]
--   Nothing
--   
--   &gt;&gt;&gt; streamAuto' (runTraversableA foo) [2,4,6,7]
--   [Just 1, Just 2, Just 3, Nothing]
--   
--   &gt;&gt;&gt; streamAuto (foo &amp;&amp;&amp; bar) [2,4,6]
--   Just [(1, 2),(2, 4),(3, 6)]
--   
--   &gt;&gt;&gt; streamAuto (foo &amp;&amp;&amp; bar) [2,4,6,7]
--   Nothing
--   
--   &gt;&gt;&gt; streamAuto' (runTraversableA foo &lt;|?&gt; runTraversableA bar) [2,4,6,7]
--   [Just 1, Just 2, Just 3, Just 7]
--   </pre>
runTraversableA :: (Monad f, Traversable f) => Auto f a b -> Auto m a (f b)

-- | Wraps a "try" over an underlying <a>IO</a> monad; if the Auto
--   encounters a runtime exception while trying to "step" itself, it'll
--   output a <a>Left</a> with the <a>Exception</a>. Otherwise, will output
--   <tt>left</tt>.
--   
--   Note that you have to explicitly specify the type of the exceptions
--   you are catching; see <a>Control.Exception</a> documentation for more
--   details.
catchA :: Exception e => Auto IO a b -> Auto IO a (Either e b)


-- | Various <a>Auto</a>s describing relationships following common
--   processes, like <a>sumFrom</a>, whose output is the cumulative sum of
--   the input.
--   
--   Also has some <a>Auto</a> constructors inspired from digital signal
--   processing signal transformation systems and statistical models.
--   
--   Note that all of these can be turned into an equivalent version acting
--   on blip streams, with <tt>perBlip</tt>:
--   
--   <pre>
--   <a>sumFrom</a> n           :: <a>Num</a> a =&gt; <a>Auto</a> m a a
--   <tt>perBlip</tt> (<a>sumFrom</a> n) :: <a>Num</a> a =&gt; <a>Auto</a> m (<tt>Blip</tt> a) (<tt>Blip</tt> a)
--   </pre>
module Control.Auto.Process

-- | The stream of outputs is the cumulative/running sum of the inputs so
--   far, starting with an initial count.
--   
--   The first output takes into account the first input. See
--   <a>sumFromD</a> for a version where the first output is the initial
--   count itself.
--   
--   <pre>
--   sumFrom x0 = accum (+) x0
--   </pre>
sumFrom :: (Serialize a, Num a) => a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>sumFrom</a>.
sumFrom_ :: Num a => a -> Auto m a a

-- | Like <a>sumFrom</a>, except the first output is the starting count.
--   
--   <pre>
--   &gt;&gt;&gt; let a = sumFromD 5
--   
--   &gt;&gt;&gt; let (y1, a') = stepAuto' a 10
--   
--   &gt;&gt;&gt; y1
--   5
--   
--   &gt;&gt;&gt; let (y2, _ ) = stepAuto' a' 3
--   
--   &gt;&gt;&gt; y2
--   10
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (sumFrom 0) [1..10]
--   [1,3,6,10,15,21,28,36,45,55]
--   
--   &gt;&gt;&gt; streamAuto' (sumFromD 0) [1..10]
--   [0,1,3,6,10,15,21,28,36,45]
--   </pre>
--   
--   It's <a>sumFrom</a>, but "delayed".
--   
--   Useful for recursive bindings, where you need at least one value to be
--   able to produce its "first output" without depending on anything else.
--   
--   <pre>
--   sumFromD x0 = sumFrom x0 . delay 0
--   </pre>
--   
--   <pre>
--   sumFromD x0 = delay x0 . sumFrom x0
--   </pre>
sumFromD :: (Serialize a, Num a) => a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>sumFromD</a>.
sumFromD_ :: Num a => a -> Auto m a a

-- | The output is the running/cumulative product of all of the inputs so
--   far, starting from an initial product.
--   
--   <pre>
--   productFrom x0 = accum (*) x0
--   </pre>
productFrom :: (Serialize a, Num a) => a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>productFrom</a>.
productFrom_ :: Num a => a -> Auto m a a

-- | The output is the the difference between the input and the previously
--   received input.
--   
--   First result is a <a>Nothing</a>, so you can use <a>&lt;|!&gt;</a> or
--   <a>fromInterval</a> or <tt>fromMaybe</tt> to get a "default first
--   value".
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' deltas [1,6,3,5,8]
--   
--   &gt;&gt;&gt; [Nothing, Just 5, Just (-3), Just 2, Just 3]
--   </pre>
--   
--   Usage with <a>&lt;|!&gt;</a>:
--   
--   <pre>
--   &gt;&gt;&gt; let a = deltas &lt;|!&gt; pure 100
--   
--   &gt;&gt;&gt; streamAuto' (deltas &lt;|!&gt; pure 100) [1,6,3,5,8]
--   [100, 5, -3, 2, 3]
--   </pre>
--   
--   Usage with <tt>fromMaybe</tt>:
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (fromMaybe 100 &lt;$&gt; deltas) [1,6,3,5,8]
--   [100, 5, -3, 2, 3]
--   </pre>
deltas :: (Serialize a, Num a) => Interval m a a

-- | The non-resuming/non-serializing version of <a>deltas</a>.
deltas_ :: Num a => Interval m a a

-- | The output is the sum of the past inputs, multiplied by a moving
--   window of weights.
--   
--   For example, if the last received inputs are <tt>[1,2,3,4]</tt> (from
--   most recent to oldest), and the window of weights is
--   <tt>[2,0.5,4]</tt>, then the output will be <tt>1*2 + 0.5*2 +
--   4*3</tt>, or <tt>15</tt>. (The weights are assumed to be zero past the
--   end of the weight window)
--   
--   The immediately received input is counted as a part of the history.
--   
--   Mathematically, <tt>y_n = w_0 * x_(n-0) + w_1 + x_(n-1) + w_2 *
--   x_(n-1) + ...</tt>, for all <tt>w</tt>s in the weight window, where
--   the first item is <tt>w_0</tt>. <tt>y_n</tt> is the <tt>n</tt>th
--   output, and <tt>x_n</tt> is the <tt>n</tt>th input.
--   
--   Note that this serializes the history of the input...or at least the
--   history as far back as the entire window of weights. (A weight list of
--   five items will serialize the past five received items) If your weight
--   window is very long (or infinite), then serializing is a bad idea!
--   
--   The second parameter is a list of a "starting history", or initial
--   conditions, to be used when the actual input history isn't long
--   enough. If you want all your initial conditions/starting history to be
--   <tt>0</tt>, just pass in <tt>[]</tt>.
--   
--   Minus serialization, you can implement <a>sumFrom</a> as:
--   
--   <pre>
--   sumFrom n = movingAverage (repeat 1) [n]
--   </pre>
--   
--   And you can implement a version of <a>deltas</a> as:
--   
--   <pre>
--   deltas = movingAverage [1,-1] []
--   </pre>
--   
--   It behaves the same, except the first step outputs the initially
--   received value. So it's realy a bit like
--   
--   <pre>
--   (movingAverage [1,-1] []) == (deltas <a>|!</a> id)
--   </pre>
--   
--   Where for the first step, the actual input is used instead of the
--   delta.
--   
--   Name comes from the statistical model.
movingAverage :: (Num a, Serialize a) => [a] -> [a] -> Auto m a a

-- | The non-serializing/non-resuming version of <a>movingAverage</a>.
movingAverage_ :: Num a => [a] -> [a] -> Auto m a a

-- | Any linear time independent stream transformation can be encoded by
--   the response of the transformation when given <tt>[1,0,0,0...]</tt>,
--   or <tt>1 : <a>repeat</a> 0</tt>. So, given an <a>LTI</a> <a>Auto</a>,
--   if you feed it <tt>1 : <a>repeat</a> 0</tt>, the output is what is
--   called an "impulse response function".
--   
--   For any <a>LTI</a> <a>Auto</a>, we can reconstruct the behavior of the
--   original <a>Auto</a> given its impulse response. Give
--   <a>impulseResponse</a> an impulse response, and it will
--   recreate/reconstruct the original <a>Auto</a>.
--   
--   <pre>
--   &gt;&gt;&gt; let getImpulseResponse a = streamAuto' a (1 : repeat 0)
--   
--   &gt;&gt;&gt; let sumFromImpulseResponse = getImpulseResponse (sumFrom 0)
--   
--   &gt;&gt;&gt; streamAuto' (sumFrom 0) [1..10]
--   [1,3,6,10,15,21,28,36,45,55]
--   
--   &gt;&gt;&gt; streamAuto' (impulseResponse sumFromImpulseResponse) [1..10]
--   [1,3,6,10,15,21,28,36,45,55]
--   </pre>
--   
--   Use this function to create an LTI system when you know its impulse
--   response.
--   
--   <pre>
--   &gt;&gt;&gt; take 10 . streamAuto' (impulseResponse (map (2**) [0,-1..])) $ repeat 1
--   [1.0,1.5,1.75,1.875,1.9375,1.96875,1.984375,1.9921875,1.99609375,1.998046875]
--   </pre>
--   
--   All impulse response after the end of the given list is assumed to be
--   zero.
--   
--   Mathematically, <tt>y_n = h_0 * x_(n-0) + h_1 + x_(n-1) + h_2 *
--   x_(n-1) + ...</tt>, for all <tt>h_n</tt> in the input response, where
--   the first item is <tt>h_0</tt>.
--   
--   Note that when this is serialized, it must serialize a number of input
--   elements equal to the length of the impulse response list...so if you
--   give an infinite impulse response, you might want to use
--   <a>impulseResponse_</a>, or not serialize.
--   
--   By the way, <tt><a>impulseResponse</a> ir == <a>movingAverage</a> ir
--   []</tt>.
impulseResponse :: (Num a, Serialize a) => [a] -> Auto m a a

-- | The non-serializing/non-resuming version of <a>impulseResponse</a>.
impulseResponse_ :: Num a => [a] -> Auto m a a

-- | The output is the sum of the past outputs, multiplied by a moving
--   window of weights. Ignores all input.
--   
--   For example, if the last outputs are <tt>[1,2,3,4]</tt> (from most
--   recent to oldest), and the window of weights is <tt>[2,0.5,4]</tt>,
--   then the output will be <tt>1*2 + 0.5*2 + 4*3</tt>, or <tt>15</tt>.
--   (The weights are assumed to be zero past the end of the weight window)
--   
--   Mathematically, <tt>y_n = w_1 * y_(n-1) + w_2 * y_(n-2) + ...</tt>,
--   for all <tt>w</tt> in the weight window, where the first item is
--   <tt>w_1</tt>.
--   
--   Note that this serializes the history of the outputs...or at least the
--   history as far back as the entire window of weights. (A weight list of
--   five items will serialize the past five outputted items) If your
--   weight window is very long (or infinite), then serializing is a bad
--   idea!
--   
--   The second parameter is a list of a "starting history", or initial
--   conditions, to be used when the actual output history isn't long
--   enough. If you want all your initial conditions/starting history to be
--   <tt>0</tt>, just pass in <tt>[]</tt>.
--   
--   You can use this to implement any linear recurrence relationship, like
--   he fibonacci sequence:
--   
--   <pre>
--   &gt;&gt;&gt; evalAutoN' 10 (autoRegression [1,1] [1,1]) ()
--   [2,3,5,8,13,21,34,55,89,144]
--   
--   &gt;&gt;&gt; evalAutoN' 10 (fromList [1,1] --&gt; autoRegression [1,1] [1,1]) ()
--   [1,1,2,3,5,8,13,21,34,55]
--   </pre>
--   
--   Which is 1 times the previous value, plus one times the value before
--   that.
--   
--   You can create a series that doubles by having it be just twice the
--   previous value:
--   
--   <pre>
--   &gt;&gt;&gt; evalAutoN' 10 (autoRegression [2] [1]) ()
--   [2,,4,8,16,32,64,128,256,512,1024]
--   </pre>
--   
--   Name comes from the statistical model.
autoRegression :: (Num b, Serialize b) => [b] -> [b] -> Auto m a b

-- | The non-serializing/non-resuming version of <a>autoRegression</a>.
autoRegression_ :: Num b => [b] -> [b] -> Auto m a b

-- | A combination of <a>autoRegression</a> and <a>movingAverage</a>.
--   Inspired by the statistical model.
--   
--   Mathematically:
--   
--   <pre>
--   y_n = wm_0 * x_(n-0) + wm_1 * x_(n-1) + wm_2 * x_(n-2) + ...
--                        + wa_1 * y_(n-1) + wa_2 * y_(n-1) + ...
--   </pre>
--   
--   Where <tt>wm_n</tt>s are all of the "moving average" weights, where
--   the first weight is <tt>wm_0</tt>, and <tt>wa_n</tt>s are all of the
--   "autoregression" weights, where the first weight is <tt>wa_1</tt>.
arma :: (Num a, Serialize a) => [a] -> [a] -> [a] -> [a] -> Auto m a a

-- | The non-serializing/non-resuming version of <a>arma</a>.
arma_ :: Num a => [a] -> [a] -> [a] -> [a] -> Auto m a a

-- | The output is the running/cumulative <a>mconcat</a> of all of the
--   input seen so far, starting with <a>mempty</a>.
--   
--   <pre>
--   &gt;&gt;&gt; streamauto' mappender . map Last $ [Just 4, Nothing, Just 2, Just 3]
--   [Last (Just 4), Last (Just 4), Last (Just 2), Last (Just 3)]
--   
--   &gt;&gt;&gt; streamAuto' mappender ["hello","world","good","bye"]
--   ["hello","helloworld","helloworldgood","helloworldgoodbye"]
--   </pre>
--   
--   <pre>
--   mappender = accum mappend mempty
--   </pre>
mappender :: (Serialize a, Monoid a) => Auto m a a

-- | The non-resuming/non-serializing version of <a>mappender</a>.
mappender_ :: Monoid a => Auto m a a

-- | The output is the running <a>&lt;&gt;</a>-sum (<a>mappend</a> for
--   <a>Semigroup</a>) of all of the input values so far, starting with a
--   given starting value. Basically like <a>mappender</a>, but with a
--   starting value.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (mappendFrom (Max 0)) [Max 4, Max (-2), Max 3, Max 10]
--   [Max 4, Max 4, Max 4, Max 10]
--   </pre>
--   
--   <pre>
--   mappendFrom m0 = accum (&lt;&gt;) m0
--   </pre>
mappendFrom :: (Serialize a, Semigroup a) => a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>mappender</a>.
mappendFrom_ :: Semigroup a => a -> Auto m a a


-- | This module provides <a>Auto</a>s (purely) generating entropy in the
--   form of random or noisy processes, as well as <a>Auto</a>s to
--   purify/seal <a>Auto</a>s with underlying entropy.
--   
--   Note that every <a>Auto</a> and combinator here is completely
--   deterministic --- given the same initial seed, one would expect the
--   same stream of outputs on every run. Furthermore, if a serializable
--   <a>Auto</a> is serialized and resumed, it will continue along the
--   deterministic path dictated by the <i>original</i> seed given.
--   
--   All of these <a>Auto</a>s and combinators come in three flavors: one
--   serializing one that works with any serializable <a>RandomGen</a>
--   instance, one serializing one that works specifically with
--   <a>StdGen</a> from <a>System.Random</a>, and one that takes any
--   <a>RandomGen</a> (including <a>StdGen</a>) and runs it without the
--   ability to serialize and resume deterministically.
--   
--   The reason why there's a specialized <a>StdGen</a> version for all of
--   these is that <a>StdGen</a> actually doesn't have a <a>Serialize</a>
--   instance, so a rudimentary serialization process is provded with the
--   <a>StdGen</a> versions.
--   
--   The first class of generators take arbitrary <tt>g -&gt; (b, g)</tt>
--   functions: "Generate a random <tt>b</tt>, using the given function,
--   and replace the seed with the resulting seed". Most "random" functions
--   follow this pattern, including <a>random</a> and <a>randomR</a>, and
--   if you are using something from <a>MonadRandom</a>, then you can use
--   the <tt>runRand</tt> function to turn a <tt><tt>Rand</tt> g b</tt>
--   into a <tt>g -&gt; (b, g)</tt>, as well:
--   
--   <pre>
--   <tt>runRand</tt> :: <a>RandomGen</a> g =&gt; <tt>Rand</tt> g b -&gt; (g -&gt; (b, g))
--   </pre>
--   
--   These are useful for generating noise...a new random value at every
--   step. They are entropy sources.
--   
--   Alternatively, if you want to give up parallelizability and
--   determinism and have your entire <a>Auto</a> be sequential, you can
--   make your entire <a>Auto</a> run under <tt>Rand</tt> or <a>RandT</a>
--   as its internal monad, from <a>MonadRandom</a>.
--   
--   <pre>
--   <a>Auto</a> (<tt>Rand</tt> g) a b
--   <a>Auto</a> (<a>RandT</a> g m) a b
--   </pre>
--   
--   In this case, if you wanted to pull a random number, you could do:
--   
--   <pre>
--   <a>effect</a> <a>random</a> :: (<a>Random</a> r, <a>RandomGen</a> g) =&gt; <a>Auto</a> (<tt>Rand</tt> g) a r
--   <a>effect</a> <a>random</a> :: (<a>Random</a> r, <a>RandomGen</a> g) =&gt; <a>Auto</a> (<a>RandT</a> g m) a r
--   </pre>
--   
--   Which pulls a random <tt>r</tt> from "thin air" (from the internal
--   <tt>Rand</tt> monad).
--   
--   However, you lose a great deal of determinism from this method, as
--   your <a>Auto</a>s are no longer deterministic with a given seed...and
--   resumability becomes dependent on starting everything with the same
--   seed every time you re-load your <a>Auto</a>. Also, <a>Auto'</a>s are
--   parallelizable, while <tt><a>Auto</a> (<tt>Rand</tt> g)</tt>s are not.
--   
--   As a compromise, you can then "seal" away the underlying monad with
--   <a>sealRandom</a>, which takes an <tt><a>Auto</a> (<a>RandT</a> g m) a
--   b</tt>, a starting <tt>g</tt>, and turns it into a normal
--   <tt><a>Auto</a> m a b</tt>, with no underlying randomness monad.
--   
--   In this way, you can run any <a>Auto</a> under <tt>Rand</tt> or
--   <a>RandT</a> as if it was a normal <a>Auto</a> "without" underlying
--   randomness. This lets you compose your sequential/non-parallel parts
--   in <tt>Rand</tt>...and the later, use it as a part of a
--   parallelizable/potentially non-sequential <a>Auto'</a>. It's also
--   convenient because you don't have to manually split and pass around
--   seeds to every <a>Auto</a> that requires entropy.
--   
--   The other generators given are for useful random processes you might
--   run into. The first is a <a>Blip</a> stream that emits at random times
--   with the given frequency<i>probability. The second works </i>Interval/
--   semantics from <a>Control.Auto.Interval</a>, and is a stream that is
--   "on" or "off", chunks at a time, for random lengths. The average
--   length of each on or off period is controlled by the parameter you
--   pass in.
module Control.Auto.Process.Random

-- | Given a seed-consuming generating function of form <tt>g -&gt; (b,
--   g)</tt> (where <tt>g</tt> is the seed, and <tt>b</tt> is the result)
--   and an initial seed, return an <a>Auto</a> that continually generates
--   random values using the given generating funcion.
--   
--   You'll notice that most of the useful functions from
--   <a>System.Random</a> fit this form:
--   
--   <pre>
--   <a>random</a>  :: <a>RandomGen</a> g =&gt;            g -&gt; (b, g)
--   <a>randomR</a> :: <a>RandomGen</a> g =&gt; (b, b) -&gt; (g -&gt; (b, g))
--   </pre>
--   
--   If you are using something from <a>MonadRandom</a>, then you can use
--   the <tt>runRand</tt> function to turn a <tt><tt>Rand</tt> g b</tt>
--   into a <tt>g -&gt; (b, g)</tt>:
--   
--   <pre>
--   <tt>runRand</tt> :: <a>RandomGen</a> g =&gt; <tt>Rand</tt> g b -&gt; (g -&gt; (b, g))
--   </pre>
--   
--   Here is an example using <a>stdRands</a> (for <a>StdGen</a>), but
--   <a>rands</a> works exactly the same way, I promise!
--   
--   <pre>
--   &gt;&gt;&gt; let g = mkStdGen 8675309
--   
--   &gt;&gt;&gt; let a = stdRands (randomR (1,100)) g :: Auto' a Int
--   
--   &gt;&gt;&gt; let (res, _) = stepAutoN' 10 a ()
--   
--   &gt;&gt;&gt; res
--   [67, 15, 97, 13, 55, 12, 34, 86, 57, 42]
--   </pre>
--   
--   Yeah, if you are using <a>StdGen</a> from <a>System.Random</a>, you'll
--   notice that <a>StdGen</a> has no <a>Serialize</a> instance, so you
--   can't use it with this; you have to either use <a>stdRands</a> or
--   <a>rands_</a> (if you don't want serialization/resumability).
--   
--   In the context of these generators, resumability basically means
--   deterministic behavior over re-loads...if "reloading", it'll ignore
--   the seed you pass in, and use the original seed given when originally
--   saved.
rands :: (Serialize g, RandomGen g) => (g -> (b, g)) -> g -> Auto m a b

-- | Like <a>rands</a>, but specialized for <a>StdGen</a> from
--   <a>System.Random</a>, so that you can serialize and resume. This is
--   needed because <a>StdGen</a> doesn't have a <a>Serialize</a> instance.
--   
--   See the documentation of <a>rands</a> for more information on this
--   <a>Auto</a>.
stdRands :: (StdGen -> (b, StdGen)) -> StdGen -> Auto m a b

-- | The non-serializing/non-resuming version of <a>rands</a>.
rands_ :: RandomGen g => (g -> (b, g)) -> g -> Auto m a b

-- | Like <a>rands</a>, except taking a "monadic" random seed function
--   <tt>g -&gt; m (b, g)</tt>, instead of <tt>g -&gt; (b, g)</tt>. Your
--   random generating function has access to the underlying monad.
--   
--   If you are using something from <a>MonadRandom</a>, then you can use
--   the <a>runRandT</a> function to turn a <tt><a>RandT</a> g m b</tt>
--   into a <tt>g -&gt; m (b, g)</tt>:
--   
--   <pre>
--   <a>runRandT</a> :: (<a>Monad</a> m, <a>RandomGen</a> g)
--              =&gt; <a>RandT</a> g m b -&gt; (g -&gt; m (b, g))
--   </pre>
randsM :: (Serialize g, RandomGen g, Monad m) => (g -> m (b, g)) -> g -> Auto m a b

-- | Like <a>randsM</a>, but specialized for <a>StdGen</a> from
--   <a>System.Random</a>, so that you can serialize and resume. This is
--   needed because <a>StdGen</a> doesn't have a <a>Serialize</a> instance.
--   
--   See the documentation of <a>randsM</a> for more information on this
--   <a>Auto</a>.
stdRandsM :: Monad m => (StdGen -> m (b, StdGen)) -> StdGen -> Auto m a b

-- | The non-serializing/non-resuming version of <a>randsM</a>.
randsM_ :: (RandomGen g, Monad m) => (g -> m (b, g)) -> g -> Auto m a b

-- | Takes a "random function", or "random arrow" --- a function taking an
--   input value and a starting seed/entropy generator and returning a
--   result and an ending seed/entropy generator --- and turns it into an
--   <a>Auto</a> that feeds its input into such a function and outputs the
--   result, with a new seed every time.
--   
--   <pre>
--   &gt;&gt;&gt; let f x = randomR (0 :: Int, x)
--   
--   &gt;&gt;&gt; streamAuto' (arrRandStd f (mkStdGen 782065)) [1..10]
--   -- [1,2,3,4,5,6,7,8,9,10] &lt;- upper bounds
--      [1,2,0,1,5,3,7,6,8,10] -- random number from 0 to upper bound
--   </pre>
--   
--   If you are using something from <a>MonadRandom</a>, then you can use
--   the <tt>(<tt>runRand</tt> .)</tt> function to turn a <tt>a -&gt;
--   <tt>Rand</tt> g b</tt> into a <tt>a -&gt; g -&gt; (b, g)</tt>:
--   
--   <pre>
--   (<tt>runRand</tt> .) :: <a>RandomGen</a> g =&gt; (a -&gt; <tt>Rand</tt> g b) -&gt; (a -&gt; g -&gt; (b, g))
--   </pre>
--   
--   (This is basically <a>mkState</a>, specialized.)
arrRand :: (Serialize g, RandomGen g) => (a -> g -> (b, g)) -> g -> Auto m a b

-- | Like <a>arrRand</a>, except the result is the result of a monadic
--   action. Your random arrow function has access to the underlying monad.
--   
--   If you are using something from <a>MonadRandom</a>, then you can use
--   the <tt>(<a>runRandT</a> .)</tt> function to turn a <tt>a -&gt;
--   <a>RandT</a> m g b</tt> into a <tt>a -&gt; g -&gt; m (b, g)</tt>:
--   
--   <pre>
--   (<a>runRandT</a> .) :: <a>RandomGen</a> g =&gt; (a -&gt; <a>RandT</a> g b) -&gt; (a -&gt; g -&gt; m (b, g))
--   </pre>
arrRandM :: (Monad m, Serialize g, RandomGen g) => (a -> g -> m (b, g)) -> g -> Auto m a b

-- | Like <a>arrRand</a>, but specialized for <a>StdGen</a> from
--   <a>System.Random</a>, so that you can serialize and resume. This is
--   needed because <a>StdGen</a> doesn't have a <a>Serialize</a> instance.
--   
--   See the documentation of <a>arrRand</a> for more information on this
--   <a>Auto</a>.
arrRandStd :: (a -> StdGen -> (b, StdGen)) -> StdGen -> Auto m a b

-- | Like <a>arrRandM</a>, but specialized for <a>StdGen</a> from
--   <a>System.Random</a>, so that you can serialize and resume. This is
--   needed because <a>StdGen</a> doesn't have a <a>Serialize</a> instance.
--   
--   See the documentation of <a>arrRandM</a> for more information on this
--   <a>Auto</a>.
arrRandStdM :: (a -> StdGen -> m (b, StdGen)) -> StdGen -> Auto m a b

-- | The non-serializing/non-resuming version of <a>arrRand</a>.
arrRand_ :: RandomGen g => (a -> g -> (b, g)) -> g -> Auto m a b

-- | The non-serializing/non-resuming version of <a>arrRandM</a>.
arrRandM_ :: RandomGen g => (a -> g -> m (b, g)) -> g -> Auto m a b

-- | Simulates a <a>Bernoulli Process</a>: a process of sequential
--   independent trials each with a success of probability <tt>p</tt>.
--   
--   Implemented here is an <a>Auto</a> producing a blip stream that emits
--   whenever the bernoulli process succeeds with the value of the received
--   input of the <a>Auto</a>, with its probability of succuss per each
--   trial as the <a>Double</a> parameter.
--   
--   It is expected that, for probability <tt>p</tt>, the stream will emit
--   a value on average once every <tt>1/p</tt> ticks.
bernoulli :: (Serialize g, RandomGen g) => Double -> g -> Auto m a (Blip a)

-- | Like <a>bernoulli</a>, but specialized for <a>StdGen</a> from
--   <a>System.Random</a>, so that you can serialize and resume. This is
--   needed because <a>StdGen</a> doesn't have a <a>Serialize</a> instance.
--   
--   See the documentation of <a>bernoulli</a> for more information on this
--   <a>Auto</a>.
stdBernoulli :: Double -> StdGen -> Auto m a (Blip a)

-- | The non-serializing/non-resuming version of <a>bernoulli</a>.
bernoulli_ :: RandomGen g => Double -> g -> Auto m a (Blip a)

-- | An <a>Interval</a> that is "on" and "off" for contiguous but random
--   intervals of time...when "on", allows values to pass as "on"
--   (<a>Just</a>), but when "off", suppresses all incoming values
--   (outputing <a>Nothing</a>).
--   
--   You provide a <a>Double</a>, an <tt>l</tt> parameter, representing the
--   average<i>expected length of each on</i>off interval.
--   
--   The distribution of interval lengths follows a <a>Geometric
--   Distribution</a>. This distribution is, as we call it in maths,
--   "memoryless", which means that the "time left" that the <a>Auto</a>
--   will be "on" or "off" at any given time is going to be, on average,
--   the given <tt>l</tt> parameter.
--   
--   Internally, the "toggling" events follow a bernoulli process with a
--   <tt>p</tt> parameter of <tt>1 / l</tt>.
randIntervals :: (Serialize g, RandomGen g) => Double -> g -> Interval m a a

-- | Like <a>randIntervals</a>, but specialized for <a>StdGen</a> from
--   <a>System.Random</a>, so that you can serialize and resume. This is
--   needed because <a>StdGen</a> doesn't have a <a>Serialize</a> instance.
--   
--   See the documentation of <a>randIntervals</a> for more information on
--   this <a>Auto</a>.
stdRandIntervals :: Double -> StdGen -> Interval m a a

-- | The non-serializing/non-resuming version of <a>randIntervals</a>.
randIntervals_ :: RandomGen g => Double -> g -> Interval m a a

-- | Takes an <a>Auto</a> over an <tt>Rand</tt> or <a>RandT</a> underlying
--   monad as an entropy source, and "seals it away" to just be a normal
--   <a>Auto</a> or <a>Auto'</a>:
--   
--   <pre>
--   <a>sealRandom</a> :: <a>Auto</a> (<tt>Rand</tt> g) a b -&gt; g -&gt; <a>Auto'</a> a b
--   </pre>
--   
--   You can now compose your entropic <a>Auto</a> with other <a>Auto</a>s
--   (using <a>.</a>, and other combinators) as if it were a normal
--   <a>Auto</a>.
--   
--   Useful because you can create entire programs that have access to an
--   underlying entropy souce by composing with <tt>Rand</tt>...and then,
--   at the end of it all, use/compose it with normal <a>Auto</a>s as if it
--   were a "pure" <a>Auto</a>.
sealRandom :: (RandomGen g, Serialize g, Monad m) => Auto (RandT g m) a b -> g -> Auto m a b

-- | Like <a>sealRandom</a>, but specialized for <a>StdGen</a> from
--   <a>System.Random</a>, so that you can serialize and resume. This is
--   needed because <a>StdGen</a> doesn't have a <a>Serialize</a> instance.
--   
--   See the documentation of <a>sealRandom</a> for more information on
--   this combinator.
sealRandomStd :: Monad m => Auto (RandT StdGen m) a b -> StdGen -> Auto m a b

-- | The non-serializing/non-resuming version of <a>sealRandom_</a>. The
--   random seed is not re-loaded/resumed, so every time you resume, the
--   stream of available randomness begins afresh.
sealRandom_ :: (RandomGen g, Monad m) => Auto (RandT g m) a b -> g -> Auto m a b

-- | <a>bernoulli</a>, but uses an underlying entropy source
--   (<a>MonadRandom</a>) to get its randomness from, instead of an
--   initially passed seed.
--   
--   You can recover exactly <tt><a>bernoulli</a> p</tt> by using
--   <tt><a>sealRandom</a> (<a>bernoulliMR</a> p)</tt>.
--   
--   See <a>sealRandom</a> for more information.
bernoulliMR :: MonadRandom m => Double -> Auto m a (Blip a)

-- | <a>randIntervals</a>, but uses an underlying entropy source
--   (<a>MonadRandom</a>) to get its randomness from, instead of an
--   initially passed seed.
--   
--   You can recover exactly <tt><a>randIntervals</a> l</tt> by using
--   <tt><a>sealRandom</a> (<a>randIntervalsMR</a> l)</tt>.
--   
--   See <a>sealRandom</a> for more information.
randIntervalsMR :: MonadRandom m => Double -> Interval m a a


-- | This module provides utilities for "running" and "unrolling"
--   <a>Auto</a>s. You'll find "enhanced" versions of <a>stepAuto</a>,
--   mechanisms for running <a>Auto</a>s "interactively" inside <a>IO</a>,
--   monadic and non-monadic "self-runners" (provide the handlers, and the
--   <a>Auto</a> just recursively runs intself), and finally, ways of
--   "unrolling" the underlying <a>Monad</a> of <a>Auto</a>s into more
--   manageable and composable and easy to work with forms.
module Control.Auto.Run

-- | Lifts an <tt><a>Auto</a> m a b</tt> to one that runs "through" a
--   <a>Traversable</a>, <tt><a>Auto</a> m (t a) (t b)</tt>. It does this
--   by running itself sequentially over every element "in" the
--   <a>Traversable</a> at every input.
--   
--   This can be thought of as a polymorphic version of many other
--   combinators in this library:
--   
--   <pre>
--   during        = throughT :: Auto m a b -&gt; Interval m (Maybe a) b
--   perBlip       = throughT :: Auto m a b -&gt; Auto m (Blip a) (Blip b)
--   accelOverList = throughT :: Auto m a b -&gt; Auto m [a] [b]
--   </pre>
--   
--   The specialized versions will still be more performant, but this will
--   be more general...you can run the <a>Auto</a> through an input
--   <tt>IntMap</tt>, for example.
--   
--   Note that this is actually an endofunctor on the <a>Auto</a>
--   <tt>Category</tt>. That is, for all <a>Auto</a>s lifted and all lawful
--   <a>Traversable</a>s, usage should obey the laws:
--   
--   <pre>
--   throughT id = id
--   throughT g . throughT f = throughT (g . f)
--   </pre>
throughT :: (Monad m, Traversable t) => Auto m a b -> Auto m (t a) (t b)

-- | Stream an <a>Auto</a> over a list, returning the list of results. Does
--   this "lazily" (over the Monad), so with most Monads, this should work
--   fine with infinite lists. (That is, <tt><a>streamAuto</a>
--   (<tt>arrM</tt> f)</tt> behaves exactly like <tt><a>mapM</a> f</tt>,
--   and you can reason with <a>Auto</a>s as if you'd reason with
--   <tt>mapM</tt> on an infinite list)
--   
--   Note that, conceptually, this turns an <tt><a>Auto</a> m a b</tt> into
--   an <tt>[a] -&gt; m [b]</tt>.
--   
--   See <a>streamAuto'</a> for a simpler example; here is one taking
--   advantage of monadic effects:
--   
--   <pre>
--   &gt;&gt;&gt; let a = arrM print *&gt; sumFrom 0 :: Auto IO Int Int
--   
--   &gt;&gt;&gt; ys &lt;- streamAuto a [1..5]
--   1                -- IO effects
--   2
--   3
--   4
--   5
--   
--   &gt;&gt;&gt; ys
--   [1,3,6,10,15]    -- the result
--   </pre>
--   
--   <tt>a</tt> here is like <tt><tt>sumFrom</tt> 0</tt>, except at every
--   step, prints the input item to stdout as a side-effect.
--   
--   Note that we use "stream" here slightly differently than in libraries
--   like <i>pipes</i> or <i>conduit</i>. We don't stream over the
--   <tt>m</tt> Monad (like <tt>IO</tt>)...we stream over the <b>input
--   elements</b>. Using <a>streamAuto</a> on an infinite list allows you
--   to "stop", for example, to find the result...but it will still
--   sequence all the *effects*.
--   
--   For example:
--   
--   <pre>
--   &gt;&gt;&gt; take 10 &lt;$&gt; streamAuto (arrM print *&gt; id) [1..]
--   </pre>
--   
--   Will execute <a>print</a> on every element before "returning" with
--   [1..10].
--   
--   <pre>
--   &gt;&gt;&gt; flip runState 0 $ take 10 &lt;$&gt; streamAuto (arrM (modify . (+)) *&gt; id) [1..]
--   ([1,2,3,4,5,6,7,8,9,10], .... (never terminates)
--   </pre>
--   
--   This will immediately return the "result", and you can bind to the
--   result with `(&gt;&gt;=)`, but it'll never return a "final state",
--   because the final state involves executing all of the <a>modify</a>s.
--   
--   In other words, we stream <i>values</i>, not <i>effects</i>. You would
--   analyze this behavior the same way you would look at something like
--   <a>mapM</a>.
--   
--   If you want to stream effects, you can use <a>streamAutoEffects</a> or
--   <a>toEffectStream</a>, and use an effects streaming library like
--   <i>pipes</i> (or anything with <i>ListT</i>)...this will give the
--   proper streaming of effects with resource handling, handling infinite
--   streams in finite space with finite effects, etc.
streamAuto :: Monad m => Auto m a b -> [a] -> m [b]

-- | Stream an <a>Auto'</a> over a list, returning the list of results.
--   Does this lazily, so this should work fine with (and is actually
--   somewhat designed for) infinite lists.
--   
--   Note that conceptually this turns an <tt><a>Auto'</a> a b</tt> into an
--   <tt>[a] -&gt; [b]</tt>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (arr (+3)) [1..10]
--   [4,5,6,7,8,9,10,11,12,13]
--   
--   &gt;&gt;&gt; streamAuto' (sumFrom 0) [1..5]
--   [1,3,6,10,15]
--   
--   &gt;&gt;&gt; streamAuto' (productFrom 1) . streamAuto' (sumFrom 0) $ [1..5]
--   [1,3,18,180,2700]
--   
--   &gt;&gt;&gt; streamAuto' (productFrom 1 . sumFrom 0) $ [1..5]
--   [1,3,18,180,2700]
--   
--   &gt;&gt;&gt; streamAuto' id [1..5]
--   [1,2,3,4,5]
--   </pre>
streamAuto' :: Auto' a b -> [a] -> [b]

-- | Streams the <a>Auto</a> over a list of inputs; that is, "unwraps" the
--   <tt>[a] -&gt; m [b]</tt> inside. Streaming is done in the context of
--   the underlying monad; when done consuming the list, the result is the
--   list of outputs updated/next <a>Auto</a> in the context of the
--   underlying monad.
--   
--   Basically just steps the <a>Auto</a> by feeding in every item in the
--   list and pops out the list of results and the updated/next
--   <a>Auto</a>, monadically chaining the steppings.
--   
--   See <a>overList'</a> for a simpler example; the following example uses
--   effects from <a>IO</a> to demonstrate the monadic features of
--   <a>overList</a>.
--   
--   <pre>
--   &gt;&gt;&gt; let a = arrM print *&gt; sumFrom 0 :: Auto IO Int Int
--   
--   &gt;&gt;&gt; (ys, a') &lt;- overList a [1..5]
--   1    -- IO effects
--   2
--   3
--   4
--   5
--   
--   &gt;&gt;&gt; ys
--   [1,3,6,10,15]
--   
--   &gt;&gt;&gt; (ys', _) &lt;- overList a' [11..15]
--   11   -- IO effects
--   12
--   13
--   14
--   15
--   
--   &gt;&gt;&gt; ys'
--   [26,38,51,65,80]
--   </pre>
--   
--   <tt>a</tt> is like <tt><tt>sumFrom</tt> 0</tt>, except at every step,
--   prints the input item to stdout as a side-effect. Note that in
--   executing we get the updated <tt>a'</tt>, which ends up with an
--   accumulator of 15. Now, when we stream <tt>a'</tt>, we pick up were we
--   left off (from 15) on the results.
overList :: Monad m => Auto m a b -> [a] -> m ([b], Auto m a b)

-- | Streams an <a>Auto'</a> over a list of inputs; that is, "unwraps" the
--   <tt>[a] -&gt; [b]</tt> inside. When done comsuming the list, returns
--   the outputs and the updated/next <a>Auto'</a>.
--   
--   <pre>
--   &gt;&gt;&gt; let (ys, updatedSummer) = overList' (sumFrom 0) [1..5]
--   
--   &gt;&gt;&gt; ys
--   [1, 3, 6, 10, 15]
--   
--   &gt;&gt;&gt; let (ys', _) = streamAuto' updatedSummer [1..5]
--   
--   &gt;&gt;&gt; ys'
--   [16, 18, 21, 25, 30]
--   </pre>
--   
--   If you wanted to stream over an infinite list then you don't care
--   about the <a>Auto'</a> at the end, and probably want
--   <a>streamAuto'</a>.
overList' :: Auto' a b -> [a] -> ([b], Auto' a b)

-- | Like <a>overList</a>, but "streams" the <a>Auto</a> over all elements
--   of any <a>Traversable</a>, returning the final updated <a>Auto</a>.
overTraversable :: (Monad m, Traversable t) => Auto m a b -> t a -> m (t b, Auto m a b)

-- | Like <a>overList'</a>, but "streams" the <a>Auto'</a> over all
--   elements of any <tt>Traversable'</tt>, returning the final updated
--   <a>Auto'</a>.
overTraversable' :: Traversable t => Auto' a b -> t a -> (t b, Auto' a b)

-- | Streams (in the context of the underlying monad) the given <a>Auto</a>
--   with a stream of constant values as input, a given number of times.
--   After the given number of inputs, returns the list of results and the
--   next/updated <a>Auto</a>, in the context of the underlying monad.
--   
--   <pre>
--   stepAutoN n a0 x = overList a0 (replicate n x)
--   </pre>
--   
--   See <a>stepAutoN'</a> for a simpler example; here is one taking
--   advantage of monadic effects:
--   
--   <pre>
--   &gt;&gt;&gt; let a = arrM print *&gt; sumFrom 0 :: Auto IO Int Int
--   
--   &gt;&gt;&gt; (ys, a') &lt;- stepAutoN 5 a 3
--   3                -- IO effects
--   3
--   3
--   3
--   3
--   
--   &gt;&gt;&gt; ys
--   [3,6,9,12,15]    -- the result
--   
--   &gt;&gt;&gt; (ys'', _) &lt;- stepAutoN 5 a' 5
--   5                -- IO effects
--   5
--   5
--   5
--   5
--   
--   &gt;&gt;&gt; ys''
--   [20,25,30,35,50] -- the result
--   </pre>
--   
--   <tt>a</tt> here is like <tt><tt>sumFrom</tt> 0</tt>, except at every
--   step, prints the input item to stdout as a side-effect.
stepAutoN :: Monad m => Int -> Auto m a b -> a -> m ([b], Auto m a b)

-- | Streams the given <a>Auto'</a> with a stream of constant values as
--   input, a given number of times. After the given number of inputs,
--   returns the list of results and the next/updated <a>Auto</a>.
--   
--   <pre>
--   stepAutoN' n a0 x = overList' a0 (replicate n x)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let (ys, a') = stepAutoN' 5 (sumFrom 0) 3
--   
--   &gt;&gt;&gt; ys
--   [3,6,9,12,15]
--   
--   &gt;&gt;&gt; let (ys', _) = stepAutoN' 5 a' 5
--   
--   &gt;&gt;&gt; ys'
--   [20,25,30,35,40]
--   </pre>
stepAutoN' :: Int -> Auto' a b -> a -> ([b], Auto' a b)

-- | Streams (in the context of the underlying monad) the given <a>Auto</a>
--   with a stream of constant values as input, a given number of times.
--   After the given number of inputs, returns the list of results in the
--   context of the underlying monad.
--   
--   Like <a>stepAutoN</a>, but drops the "next <a>Auto</a>". Only returns
--   the list of results.
--   
--   <pre>
--   &gt;&gt;&gt; let a = arrM print *&gt; sumFrom 0 :: Auto IO Int Int
--   
--   &gt;&gt;&gt; ys &lt;- evalAutoN 5 a 3
--   3                -- IO effects
--   3
--   3
--   3
--   3
--   
--   &gt;&gt;&gt; ys
--   [3,6,9,12,15]    -- the result
--   </pre>
--   
--   <tt>a</tt> here is like <tt><tt>sumFrom</tt> 0</tt>, except at every
--   step, prints the input item to stdout as a side-effect.
evalAutoN :: Monad m => Int -> Auto m a b -> a -> m [b]

-- | Streams the given <a>Auto'</a> with a stream of constant values as
--   input, a given number of times. After the given number of inputs,
--   returns the list of results and the next/updated <a>Auto</a>.
--   
--   Like <a>stepAutoN'</a>, but drops the "next <a>Auto'</a>". Only
--   returns the list of results.
--   
--   <pre>
--   &gt;&gt;&gt; evalAutoN' 5 (sumFrom 0) 3
--   [3,6,9,12,15]
--   </pre>
evalAutoN' :: Int -> Auto' a b -> a -> [b]

-- | Run an <a>Auto'</a> "interactively". Every step grab a string from
--   stdin, and feed it to the <a>Interval'</a>. If the <a>Interval'</a> is
--   "off", ends the session; if it is "on", then prints the output value
--   to stdout and repeat all over again.
--   
--   If your <a>Auto</a> outputs something other than a <a>String</a>, you
--   can use <a>fmap</a> to transform the output into a <a>String</a>
--   en-route (like <tt><a>fmap</a> <a>show</a></tt>).
--   
--   If your <a>Auto</a> takes in something other than a <a>String</a>, you
--   can <a>lmap</a> a function to convert the input <a>String</a> to
--   whatever intput your <a>Auto</a> expects.
--   
--   You can use <a>duringRead</a> or <a>bindRead</a> if you have an
--   <a>Auto'</a> or <a>Interval'</a> that takes something <a>read</a>able,
--   to chug along until you find something non-readable; there's also
--   <a>interactRS</a> which handles most of that for you.
--   
--   Outputs the final <a>Interval'</a> when the interaction terminates.
interactAuto :: Interval' String String -> IO (Interval' String String)

-- | Like <tt>interact</tt>, but instead of taking <tt><a>Interval'</a>
--   <a>String</a> <a>String</a></tt>, takes any <tt><a>Interval'</a> a
--   b</tt> as long as <tt>a</tt> is <a>Read</a> and <tt>b</tt> is
--   <a>Show</a>.
--   
--   Will "stop" if either (1) the input is not <a>read</a>-able or (2) the
--   <a>Interval'</a> turns off.
--   
--   Outputs the final <a>Auto'</a> when the interaction terminates.
interactRS :: (Read a, Show b) => Interval' a b -> IO (Interval' String String)

-- | Like <tt>interact</tt>, but much more general. You can run it with an
--   <a>Auto</a> of any underlying <a>Monad</a>, as long as you provide the
--   natural transformation from that <a>Monad</a> to <a>IO</a>.
--   
--   The <a>Auto</a> can any <tt><a>Maybe</a> b</tt>; you have to provide a
--   function to "handle" it yourself; a <tt>b -&gt; <a>IO</a>
--   <a>Bool</a></tt>. You can print the result, or write the result to a
--   file, etc.; the <a>Bool</a> parameter determines whether or not to
--   "continue running", or to stop and return the final updated
--   <a>Auto</a>.
interactM :: Monad m => (forall c. m c -> IO c) -> (b -> IO Bool) -> Auto m String b -> IO (Auto m String b)

-- | Turn an <a>Auto</a> that takes a "readable" <tt>a</tt> and outputs a
--   <tt>b</tt> into an <a>Auto</a> that takes a <a>String</a> and outputs
--   a <tt><a>Maybe</a> b</tt>. When the <a>String</a> is successfuly
--   readable as the <tt>a</tt>, it steps the <a>Auto</a> and outputs a
--   succesful <a>Just</a> result; when it isn't, it outputs a
--   <a>Nothing</a> on that step.
--   
--   <pre>
--   &gt;&gt;&gt; let a0 = duringRead (accum (+) (0 :: Int))
--   
--   &gt;&gt;&gt; let (y1, a1) = stepAuto' a0 "12"
--   
--   &gt;&gt;&gt; y1
--   Just 12
--   
--   &gt;&gt;&gt; let (y2, a2) = stepAuto' a1 "orange"
--   
--   &gt;&gt;&gt; y2
--   Nothing
--   
--   &gt;&gt;&gt; let (y3, _ ) = stepAuto' a2 "4"
--   
--   &gt;&gt;&gt; y3
--   Just 16
--   </pre>
--   
--   See <tt>interact</tt> for neat use cases.
duringRead :: (Monad m, Read a) => Auto m a b -> Interval m String b

-- | Like <a>duringRead</a>, but the original <a>Auto</a> would output a
--   <tt><a>Maybe</a> b</tt> instead of a <tt>b</tt>. Returns
--   <a>Nothing</a> if either the <a>String</a> fails to parse or if the
--   original <a>Auto</a> returned <a>Nothing</a>; returns <a>Just</a> if
--   the <a>String</a> parses and the original <a>Auto</a> returned
--   <a>Just</a>.
--   
--   See <tt>interact</tt> for neat use cases.
bindRead :: (Monad m, Read a) => Interval m a b -> Interval m String b

-- | Heavy duty abstraction for "self running" an <a>Auto</a>. Give a
--   starting input action, a (possibly side-effecting) function from an
--   output to the next input to feed in, and the <a>Auto</a>, and you get
--   a feedback loop that constantly feeds back in the result of the
--   function applied to the previous output. <a>Stops</a> when the "next
--   input" function returns <a>Nothing</a>.
--   
--   Note that the none of the results are actually returned from the loop.
--   Instead, if you want to process the results, they must be utilized in
--   the "side-effects' of the "next input" function. (ie, a write to a
--   file, or an accumulation to a state).
run :: Monad m => m a -> (b -> m (Maybe a)) -> Auto m a b -> m (Auto m a b)

-- | A generalized version of <a>run</a> where the <a>Monad</a> you are
--   "running" the <a>Auto</a> in is different than the <a>Monad</a>
--   underneath the <a>Auto</a>. You just need to provide the natural
--   transformation.
runM :: (Monad m, Monad m') => (forall c. m' c -> m c) -> m a -> (b -> m (Maybe a)) -> Auto m' a b -> m (Auto m' a b)

-- | Runs the <a>Auto'</a> in IO with inputs read from a <a>Chan</a> queue,
--   from <a>Control.Concurrency.Chan</a>. It'll block until the
--   <a>Chan</a> has a new input, run the <a>Auto</a> with the received
--   input, process the output with the given handling function, and start
--   over if the handling function returns <a>True</a>.
runOnChan :: (b -> IO Bool) -> Chan a -> Auto' a b -> IO (Auto' a b)

-- | A generalized version of <a>runOnChan</a> that can run on any
--   <tt><a>Auto</a> m</tt>; all that is required is a natural
--   transformation from the underyling <a>Monad</a> <tt>m</tt> to
--   <a>IO</a>.
runOnChanM :: Monad m => (forall c. m c -> IO c) -> (b -> IO Bool) -> Chan a -> Auto m a b -> IO (Auto m a b)

-- | Turns an <tt>Auto m' a b</tt> with a list of inputs into a "ListT
--   compatible effectful stream", as described at
--   <a>http://www.haskellforall.com/2014/11/how-to-build-library-agnostic-streaming.html</a>
--   
--   Any library that offers a "<tt>ListT</tt>" type can use this
--   result...and usually turn it into an effectful stream.
--   
--   For example, the <i>pipes</i> library offers <tt>runListT</tt> so you
--   can run this, running the <a>Auto</a> over the input list, all with
--   the effect stream manipulation tools and resource handling of
--   <i>pipes</i>.
--   
--   This is useful because <i>auto</i>, the library, mainly provides tools
--   for working with transformers for <i>value</i> streams, and not effect
--   streams or streams of effects. Using this, you can potentially have
--   the best of both worlds.
streamAutoEffects :: (Monad m, MonadTrans t, MonadPlus (t m), Monad m') => (forall c. m' c -> m c) -> [a] -> Auto m' a b -> t m b

-- | Turns an <tt>Auto m' a b</tt> and an "input producer" <tt>m a</tt>
--   into a "ListT compatible effectful stream", as described at
--   <a>http://www.haskellforall.com/2014/11/how-to-build-library-agnostic-streaming.html</a>
--   
--   Any library that offers a "<tt>ListT</tt>" type can use this
--   result...and usually turn it into an effectful stream.
--   
--   For example, the <i>pipes</i> library offers <tt>runListT</tt> so you
--   can run this, constantly pulling out <tt>a</tt>s from the stream using
--   the <tt>m a</tt>, feeding it in, and moving forward, all with the
--   effect stream manipulation tools and resource handling of
--   <i>pipes</i>.
--   
--   This is useful because <i>auto</i>, the library, mainly provides tools
--   for working with transformers for <i>value</i> streams, and not effect
--   streams or streams of effects. Using this, you can potentially have
--   the best of both worlds.
toEffectStream :: (Monad m, MonadTrans t, MonadPlus (t m), Monad m') => (forall c. m' c -> m c) -> m a -> Auto m' a b -> t m b


-- | This module provides tools for working with the automatically derived
--   serializability and resumability of <a>Auto</a>s. The first half
--   contains boring wrappers around encoding and decoding to and from
--   binary, filepaths on disk, etc.
--   
--   The second half contains <a>Auto</a> transformers that "imbue" an
--   <a>Auto</a> with IO serialization abilities. Note that these all
--   require an underlying <a>Monad</a> that is an instance of
--   <a>MonadIO</a>.
--   
--   You have "identity-like" transformers that take an <a>Auto</a> and
--   spit it back out operationally unchanged...but every step, it might do
--   some behind-the-scenes saving or re-load itself from disk when it is
--   first stepped. Or you have some "trigger enhancers" that take normal
--   <a>Auto</a>s and give you the ability to "trigger" saving and loading
--   events on the <a>Auto</a> using the <a>Blip</a> mechanisms and blip
--   stream semantics from <a>Control.Auto.Blip</a>.
--   
--   Note that the entire <a>Auto</a> construct is a little bit awkward
--   when it comes to performing IO effects --- it isn't exactly what they
--   were designed for originally. Hooking on effects to stepping can be
--   powerful, but as of now, not much has been looked into meaningful
--   error handling when working with IO. If you have any experience with
--   this and are willing to help, please feel free to send me an e-mail or
--   open an issue on the <a>issue tracker</a>!
module Control.Auto.Serialize

-- | Returns a <a>Put</a> --- instructions (from <a>Data.Serialize</a>) on
--   how to "freeze" the <a>Auto</a>, with its internal state, and save it
--   to a binary encoding. It can later be reloaded and "resumed" by
--   'resumeAuto'/'decodeAuto'.
saveAuto :: Auto m a b -> Put

-- | Returns a <a>Get</a> from an <a>Auto</a> --- instructions (from
--   <a>Data.Serialize</a>) on taking a ByteString and "restoring" the
--   originally saved <a>Auto</a>, in the originally saved state.
resumeAuto :: Auto m a b -> Get (Auto m a b)

-- | Encode an <a>Auto</a> and its internal state into a <a>ByteString</a>.
encodeAuto :: Auto m a b -> ByteString

-- | <a>Resume</a> an <a>Auto</a> from its <a>ByteString</a> serialization,
--   giving a <a>Left</a> if the deserialization is not possible.
decodeAuto :: Auto m a b -> ByteString -> Either String (Auto m a b)

-- | Given a <a>FilePath</a> and an <a>Auto</a>, serialize and freeze the
--   state of the <a>Auto</a> as binary to that <a>FilePath</a>.
writeAuto :: FilePath -> Auto m a b -> IO ()

-- | Give a <a>FilePath</a> and an <a>Auto</a>, and <a>readAuto</a> will
--   attempt to resume the saved state of the <a>Auto</a> from disk,
--   reading from the given <a>FilePath</a>. Will return <a>Left</a> upon a
--   decoding error, with the error, and <a>Right</a> if the decoding is
--   succesful.
readAuto :: FilePath -> Auto m a b -> IO (Either String (Auto m a b))

-- | Like <a>readAuto</a>, but will return the <i>original</i> <a>Auto</a>
--   (instead of a resumed one) if the file does not exist.
--   
--   Useful if you want to "resume an <a>Auto</a>" "if there is" a save
--   state, or just use it as-is if there isn't.
readAutoDef :: FilePath -> Auto m a b -> IO (Either String (Auto m a b))

-- | <a>Transforms</a> the given <a>Auto</a> into an <a>Auto</a> that
--   constantly saves its state to the given <a>FilePath</a> at every
--   "step". Requires an underlying <a>MonadIO</a>.
--   
--   Note that (unless the <a>Auto</a> depends on IO), the resulting
--   <a>Auto</a> is meant to be operationally <i>identical</i> in its
--   inputs/outputs to the original one.
saving :: MonadIO m => FilePath -> Auto m a b -> Auto m a b

-- | Like <a>loading</a>, except silently suppresses all I/O and decoding
--   errors; if there are errors, it returns back the given <a>Auto</a>
--   as-is.
--   
--   Useful for when you aren't sure the save state is on disk or not yet,
--   and want to resume it only in the case that it is.
loading' :: MonadIO m => FilePath -> Auto m a b -> Auto m a b

-- | <a>Transforms</a> the given <a>Auto</a> into an <a>Auto</a> that, when
--   you <i>first</i> try to run or step it, "loads" itself from disk at
--   the given <a>FilePath</a>.
--   
--   Will throw a runtime exception on either an I/O error or a decoding
--   error.
--   
--   Note that (unless the <a>Auto</a> depends on IO), the resulting
--   <a>Auto</a> is meant to be operationally <i>identical</i> in its
--   inputs/outputs to the <i>fast-forwarded</i> original <a>Auto</a>.
loading :: MonadIO m => FilePath -> Auto m a b -> Auto m a b

-- | Like <a>serializing</a>, except suppresses all I/O and decoding
--   errors.
--   
--   Useful in the case that when the <a>Auto</a> is first run and there is
--   no save state yet on disk (or the save state is corrupted), it'll
--   "start a new one"; if there is one, it'll load it automatically. Then,
--   on every further step in both cases, it'll update the save state.
serializing' :: MonadIO m => FilePath -> Auto m a b -> Auto m a b

-- | A combination of <a>saving</a> and <a>loading</a>. When the
--   <a>Auto</a> is first run, it loads the save state from the given
--   <a>FilePath</a> and fast forwards it. Then, subsequently, it updates
--   the save state on disk on every step.
serializing :: MonadIO m => FilePath -> Auto m a b -> Auto m a b

-- | Takes an <a>Auto</a> and basically "wraps" it so that you can trigger
--   saves with a blip stream.
--   
--   For example, we can take <tt><tt>sumFrom</tt> 0</tt>:
--   
--   <pre>
--   <a>saveOnB</a> (<tt>sumFrom</tt> 0) :: <a>Auto</a> <a>IO</a> (<a>Int</a>, <a>Blip</a> <a>FilePath</a>) <a>Int</a>
--   </pre>
--   
--   It'll behave just like <tt><tt>sumFrom</tt> 0</tt> (with the input you
--   pass in the first field of the tuple)...and whenever the blip stream
--   (the second field of the input tuple) emits, it'll save the state of
--   <tt><tt>sumFrom</tt> 0</tt> to disk at the given <a>FilePath</a>.
--   
--   Contrast to <a>saveFromB</a>, where the <a>Auto</a> itself can trigger
--   saves; in this one, saves are triggered "externally".
--   
--   Might be useful in similar situations as <a>saveFromB</a>, except if
--   you want to trigger the save externally.
saveOnB :: MonadIO m => Auto m a b -> Auto m (a, Blip FilePath) b

-- | Like <a>loadOnB</a>, except silently ignores errors. When a load is
--   requested, but there is an IO or parse error, the loading is skipped.
loadOnB' :: MonadIO m => Auto m a b -> Auto m (a, Blip FilePath) b

-- | Takes an <a>Auto</a> and basically "wraps" it so that you can trigger
--   loads/resumes from a file with a blip stream.
--   
--   For example, we can take <tt><tt>sumFrom</tt> 0</tt>:
--   
--   <pre>
--   <a>loadOnB</a> (<tt>sumFrom</tt> 0) :: <a>Auto</a> <a>IO</a> (<a>Int</a>, <a>Blip</a> <a>FilePath</a>) <a>Int</a>
--   </pre>
--   
--   It'll behave just like <tt><tt>sumFrom</tt> 0</tt> (with the input you
--   pass in the first field of the tiple)...and whenever the blip stream
--   (the second field of the input tuple) emits, it'll "reset" and
--   "reload" the <tt><tt>sumFrom</tt> 0</tt> from the <a>FilePath</a> on
--   disk.
--   
--   Will throw a runtime exception if there is an IO error or a parse
--   error.
--   
--   Contrast to <a>loadFromB</a>, where the <a>Auto</a> itself can trigger
--   reloads/resets; in this one, the loads are triggered "externally".
--   
--   Might be useful in similar situations as <a>loadFromB</a>, except if
--   you want to trigger the loading externally.
loadOnB :: MonadIO m => Auto m a b -> Auto m (a, Blip FilePath) b

-- | Takes an <a>Auto</a> that produces a blip stream with a
--   <a>FilePath</a> and a value, and turns it into an <a>Auto</a> that,
--   outwardly, produces just the value.
--   
--   Whenever the output blip stream emits, it automatically serializes and
--   saves the state of the <a>Auto</a> to the emitted <a>FilePath</a>.
--   
--   In practice, this allows any <a>Auto</a> to basically control when it
--   wants to "save", by providing a blip stream.
--   
--   The following is an alternative implementation of <a>saving</a>,
--   except saving every two steps instead of every step:
--   
--   <pre>
--   saving2 fp a = <a>saveFromB</a> (a <tt>&amp;&amp;&amp;</tt> (<tt>every</tt> 2 . <a>pure</a> fp))
--   </pre>
--   
--   Or, in proc notation:
--   
--   <pre>
--   saving2 fp a = saveFromB $ proc x -&gt; do
--       y &lt;- a       -&lt; x
--       b &lt;- every 2 -&lt; fp
--       id -&lt; (y, b)
--   </pre>
--   
--   (Recall that <tt><tt>every</tt> n</tt> is the <a>Auto</a> that emits
--   the received value every <tt>n</tt> steps)
--   
--   In useful real-world cases, you can have the <a>Auto</a> decide
--   whether or not to save itself based on its input. Like, for example,
--   when it detects a certain user command, or when the user has reached a
--   given location.
--   
--   The following takes a <a>FilePath</a> and an <a>Auto</a> (<tt>a</tt>),
--   and turns it into an <a>Auto</a> that "saves" whenever <tt>a</tt>
--   crosses over from positive to negative.
--   
--   <pre>
--   saveOnNegative fp a = saveFromB $ proc x -&gt; do
--       y       &lt;- a            -&lt; x
--       saveNow &lt;- <tt>became</tt> (&lt; 0) -&lt; y
--       id       -&lt; (y, fp <a>&lt;$</a> saveNow)
--   </pre>
--   
--   Contrast to <a>saveOnB</a>, where the saves are triggered by outside
--   input. In this case, the saves are triggered by the <a>Auto</a> to be
--   saved itself.
saveFromB :: MonadIO m => Auto m a (b, Blip FilePath) -> Auto m a b

-- | Like <a>loadFromB</a>, except silently ignores errors. When a load is
--   requested, but there is an IO or parse error, the loading is skipped.
loadFromB' :: MonadIO m => Auto m a (b, Blip FilePath) -> Auto m a b

-- | Takes an <a>Auto</a> that outputs a <tt>b</tt> and a blip stream of
--   <a>FilePath</a>s and returns an <a>Auto</a> that ouputs only that
--   <tt>b</tt> stream...but every time the blip stream emits, it
--   "resets/loads" itself from that <a>FilePath</a>.
--   
--   The following is a re-implementation of <a>loading</a>...except
--   delayed by one (the second step that is run is the first "resumed"
--   step).
--   
--   <pre>
--   loading2 fp a = <a>loadFromB</a> $ proc x -&gt; do
--       y       &lt;- a           -&lt; x
--       loadNow &lt;- <tt>immediately</tt> -&lt; fp
--       <a>id</a>       -&lt; (y, loadNow)
--   </pre>
--   
--   (the blip stream emits only once, immediately, to re-load).
--   
--   In the real world, you could have the <a>Auto</a> decide to reset or
--   resume itself based on a user command:
--   
--   <pre>
--   loadFrom = loadFromB $ proc x -&gt; do
--       steps  &lt;- count -&lt; ()
--       toLoad &lt;- case words x of
--                     ("load":fp:_) -&gt; do
--                         immediately -&lt; fp
--                     _             -&gt; do
--                         never       -&lt; ()
--       id      -&lt; (steps, toLoad)
--   </pre>
--   
--   This will throw a runtime error on an IO exception or parsing error.
loadFromB :: MonadIO m => Auto m a (b, Blip FilePath) -> Auto m a b


-- | A collection of versatile switching mechanisms. Switching is really a
--   core mechanic at the heart of how to structure a lot of program
--   logics. Switching from one "mode" to another, from dead to alive, from
--   room to room, menu to menu...switching between <a>Auto</a>s is a core
--   part about how many programs are built.
--   
--   All of the switches here take advantage of either blip semantics (from
--   <a>Control.Auto.Blip</a>) or <i>Interval</i> semantics (from
--   <a>Control.Auto.Interval</a>)...so this is where maintaining
--   semantically meaningful blip streams and intervals pays off!
--   
--   Each switch here has various examples, and you'll find many of these
--   in use in the <a>example projects</a>.
--   
--   Note the naming convention going on here (also used in
--   <a>Control.Auto.Serialize</a>): A switch "from" a blip stream is
--   triggered "internally" by the <a>Auto</a> being switched itself; a
--   switch "on" a blip stream is triggered "externally" by an <a>Auto</a>
--   that is <i>not</i> swiched.
module Control.Auto.Switch

-- | "This, then that". Behave like the first <a>Interval</a> (and run its
--   effects) as long as it is "on" (outputting <a>Just</a>). As soon as it
--   turns off (is <a>Nothing</a>), it'll "switch over" and begin behaving
--   like the second <a>Auto</a> forever, running the effects of the second
--   <a>Auto</a>, too. Works well if the <a>Auto</a>s follow interval
--   semantics from <a>Control.Auto.Interval</a>.
--   
--   <pre>
--   &gt;&gt;&gt; let a1 = whenI (&lt;= 4) --&gt; pure 0
--   
--   &gt;&gt;&gt; streamAuto' a1 [1..10]
--   [1, 2, 3, 4, 0, 0, 0, 0, 0, 0]
--   </pre>
--   
--   (<a>whenI</a> only lets items satisfying the predicate pass through as
--   "on", and is "off" otherwise; <a>pure</a> is the <a>Auto</a> that
--   always produces the same output)
--   
--   Association works in a way that you can "chain" <a>--&gt;</a>s, as
--   long as you have an appropriate <a>Auto</a> (and not <a>Interval</a>)
--   at the end:
--   
--   <pre>
--   &gt;&gt;&gt; let a2 = onFor 3 . sumFrom 0
--            --&gt; onFor 3 . sumFrom 100
--            --&gt; pure 0
--   
--   &gt;&gt;&gt; streamAuto' a2 [1..10]
--   [1,3,6,104,109,115,0,0,0,0]
--   </pre>
--   
--   <tt>a --&gt; b --&gt; c</tt> associates as <tt>a --&gt; (b --&gt;
--   c)</tt>
--   
--   This is pretty invaluable for having <a>Auto</a>s "step" through a
--   series of different <a>Auto</a>s, progressing their state from one
--   stage to the next. <a>Auto</a>s can control when they want to be
--   "moved on" from by turning "off" (outputting <a>Nothing</a>).
--   
--   Note that recursive bindings work just fine, so:
--   
--   <pre>
--   &gt;&gt;&gt; let a3 = onFor 2 . pure "hello"
--            --&gt; onFor 2 . pure "world"
--            --&gt; a3
--   
--   &gt;&gt;&gt; let (res3, _) = stepAutoN' 8 a3 ()
--   
--   &gt;&gt;&gt; res3
--   ["hello", "hello", "world", "world", "hello", "hello", "world", "world"]
--   </pre>
--   
--   the above represents an infinite loop between outputting "hello" and
--   outputting "world".
--   
--   For serialization, an extra byte cost is incurred per invocation of
--   <a>--&gt;</a>. For cyclic switches like <tt>a3</tt>, every time the
--   cycle "completes", it adds another layer of <a>--&gt;</a> byte costs.
--   For example, initially, saving <tt>a3</tt> incurs a cost for the two
--   <a>--&gt;</a>s. After <tt>a3</tt> loops once, it incurs a cost for
--   another two <a>--&gt;</a>s, so it costs four <a>--&gt;</a>s. After
--   <tt>a3</tt> loops another time, it is like a cost of six
--   <a>--&gt;</a>s. So be aware that for cyclic bindings like <tt>a3</tt>,
--   space for serialization grows at O(n).
--   
--   By the way, it might be worth contrasting this with <a>&lt;|!&gt;</a>
--   and <a>&lt;|?&gt;</a> from <a>Control.Auto.Interval</a>, which have
--   the same type signatures. Those alternative-y operators always <i>feed
--   the input to both sides</i>, <i>run both sides</i>, and output the
--   first <a>Just</a>. With <a>&lt;|!&gt;</a>, you can "switch back and
--   forth" to the first <a>Auto</a> as soon as the first <a>Auto</a> is
--   "on" (<a>Just</a>) again.
--   
--   <a>--&gt;</a>, in contrast, runs <i>only</i> the first <a>Auto</a>
--   until it is off (<a>Nothing</a>)...then runs <i>only</i> the second
--   <a>Auto</a>. This transition is one-way, as well.
(-->) :: Monad m => Interval m a b -> Auto m a b -> Auto m a b
infixr 1 -->

-- | A variation of <a>--&gt;</a>, where the right hand side can also be an
--   <a>Interval</a> / <a>Maybe</a>. The entire result is, then, a
--   <a>Maybe</a>. Probably less useful than <a>--&gt;</a> in most
--   situations.
(-?>) :: Monad m => Interval m a b -> Interval m a b -> Interval m a b
infixr 1 -?>

-- | <tt><a>switchIn</a> n a1 a2</tt> will behave like <tt>a1</tt> for
--   <tt>n</tt> steps of output, and then behave like <tt>a2</tt> forever
--   after.
--   
--   More or less a more efficient/direct implementation of the common
--   idiom:
--   
--   <pre>
--   onFor n a1 --&gt; a2
--   </pre>
switchIn :: Monad m => Int -> Auto m a b -> Auto m a b -> Auto m a b

-- | Takes an <a>Auto</a> who has both a normal output stream and a blip
--   stream output stream, where the blip stream emits new <a>Auto</a>s.
--   
--   You can imagine <a>switchFrom_</a> as a box containing a single
--   <a>Auto</a> like the one just described. It feeds its input into the
--   contained <a>Auto</a>, and its output stream is the "normal value"
--   output stream of the contained <a>Auto</a>.
--   
--   However, as soon as the blip stream of the contained <a>Auto</a> emits
--   a new <a>Auto</a>, it <i>replaces</i> the contained <a>Auto</a> with
--   the <i>new</i> one (just after emitting the "normal value"), and the
--   whole thing starts all over again.
--   
--   <tt><a>switchFrom_</a> a0</tt> will "start" with <tt>a0</tt> already
--   in the box.
--   
--   This is mostly useful to allow <a>Auto</a>s to "replace themselves" or
--   control their own destiny, or the behavior of their successors.
--   
--   In the following example, <tt>a1</tt> is an <a>Auto</a> that behaves
--   like a cumulative sum but also outputs a blip stream that will emit an
--   <a>Auto</a> containing <tt><a>pure</a> 100</tt> (the <a>Auto</a> that
--   always emits 100) after three steps.
--   
--   <pre>
--   a1 :: Auto' Int (Int, Blip (Auto' Int Int))
--   a1 = proc x -&gt; do
--       sums       &lt;- sumFrom 0 -&lt; x
--       switchBlip &lt;- inB 4     -&lt; pure 100
--       id -&lt; (sums, switchBlip)
--   
--   -- alternatively
--   a1' = sumFrom 0 &amp;&amp;&amp; (tagBlips (pure 100) . inB 4)
--   </pre>
--   
--   So, <tt><a>switchFrom_</a> a1</tt> will be the output of
--   <tt>count</tt> for three steps, and then switch to <tt><a>pure</a>
--   100</tt> afterwards (when the blip stream emits):
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (switchFrom_ a1) [1..10]
--   [1,3,6,10,100,100,100,100,100,100]
--   </pre>
--   
--   This is fun to use with recursion, so you can get looping switches:
--   
--   <pre>
--   a2 :: Auto' Int (Int, Blip (Auto' Int Int))
--   a2 = proc x -&gt; do
--       sums       &lt;- sumFrom 0 -&lt; x
--       switchBlip &lt;- inB 3     -&lt; switchFrom_ a2
--       id -&lt; (c, switchBlip)
--   
--   -- alternatively
--   a2' = sumFrom 0 &amp;&amp;&amp; (tagBlips (switchFrom_ a2') . inB 3)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (switchFrom_ a2) [101..112]
--   [ 101, 203, 306 -- first 'sumFrom', on first three items [101, 102, 103]
--   , 104, 209, 315 -- second 'sumFrom', on second three items [104, 105, 106]
--   , 107, 215, 324 -- third 'sumFrom', on third three items [107, 108, 109]
--   , 110, 221, 333 -- final 'sumFrom', on fourth three items [110, 111, 112]
--   ]
--   </pre>
--   
--   Note that this combinator is inherently unserializable, so you are
--   going to lose all serialization capabilities if you use this. So sad,
--   I know! :( This fact is reflected in the underscore suffix, as per
--   convention.
--   
--   If you want to use switching <i>and</i> have serialization, you can
--   use the perfectly serialization-safe alternative, <a>switchFromF</a>,
--   which slightly less powerful in ways that are unlikely to be missed in
--   practical usage. That is, almost all non-contrived real life usages of
--   <a>switchFrom_</a> can be recovered using <a>switchFromF</a>.
switchFrom_ :: Monad m => Auto m a (b, Blip (Auto m a b)) -> Auto m a b

-- | You can think of this as a little box containing a single <a>Auto</a>
--   inside. Takes two input streams: an input stream of normal values, and
--   a blip stream containing <a>Auto</a>s. It feeds the input stream into
--   the contained <a>Auto</a>...but every time the input blip stream emits
--   with a new <a>Auto</a>, <i>replaces</i> the contained <a>Auto</a> with
--   the emitted one. Then starts the cycle all over, immediately giving
--   the new <a>Auto</a> the received input.
--   
--   Useful for being able to externally "swap out" <a>Auto</a>s for a
--   given situation by just emitting a new <a>Auto</a> in the blip stream.
--   
--   For example, here we push several <a>Auto</a>s one after the other
--   into the box: <tt><tt>sumFrom</tt> 0</tt>, <tt><tt>productFrom</tt>
--   1</tt>, and <tt>count</tt>. <tt><a>eachAt_</a> 4</tt> emits each
--   <a>Auto</a> in the given list every four steps, starting on the
--   fourth.
--   
--   <pre>
--   newAutos :: Auto' Int (Blip (Auto' Int Int))
--   newAutos = eachAt_ 4 [sumFrom 0, productFrom 1, count]
--   
--   a :: Auto' Int Int
--   a = proc i -&gt; do
--       blipAutos &lt;- newAutos -&lt; ()
--       switchOn_ (pure 0)    -&lt; (i, blipAutos)
--   
--   -- alternatively
--   a' = switchOn_ (pure 0) . (id &amp;&amp;&amp; newAutos)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' a [1..12]
--   [ 1,  3,   6           -- output from sumFrom 0
--   , 4, 20, 120           -- output from productFrom 1
--   , 0,  1,   2, 3, 4, 5] -- output from count
--   </pre>
--   
--   Like <a>switchFrom_</a>, this combinator is inherently unserializable.
--   So if you use it, you give up serialization for your <a>Auto</a>s.
--   This is reflected in the underscore suffix.
--   
--   If you wish to have the same switching devices but keep serialization,
--   you can use <a>switchOnF</a>, which is slightly less powerful, but
--   should be sufficient for all practical use cases.
switchOn_ :: Monad m => Auto m a b -> Auto m (a, Blip (Auto m a b)) b

-- | Essentially identical to <a>switchOn_</a>, except instead of taking in
--   a blip stream of new <a>Auto</a>s to put into the box, takes a blip
--   stream of <tt>c</tt> --- and <a>switchOnF</a> uses the <tt>c</tt> to
--   create the new <a>Auto</a> to put in the box.
--   
--   Here is the equivalent of the two examples from <a>switchOn_</a>,
--   implemented with <a>switchOnF</a>; see the documentatino for
--   <a>switchOn_</a> for a description of what they are to do.
--   
--   <pre>
--   newAuto :: Int -&gt; Auto' Int Int
--   newAuto 1 = sumFrom 0
--   newAuto 2 = productFrom 1
--   newAuto 3 = count
--   newAuto _ = error "Do you expect rigorous error handling from a toy example?"
--   
--   a :: Auto' Int Int
--   a = proc i -&gt; do
--       blipAutos &lt;- eachAt 4 [1,2,3] -&lt; ()
--       switchOnF_ newAuto (pure 0) -&lt; (i, blipAutos)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' a [1..12]
--   [ 1,  3,   6           -- output from sumFrom 0
--   , 4, 20, 120           -- output from productFrom 1
--   , 0,  1,   2, 3, 4, 5] -- output from count
--   </pre>
--   
--   Instead of sending in the "replacement <a>Auto</a>", sends in a
--   number, which corresponds to a specific replacement <a>Auto</a>.
--   
--   As you can see, all of the simple examples from <a>switchOn_</a> can
--   be implemented in <a>switchOnF</a>...and so can most real-life
--   examples. The advantage is that <a>switchOnF</a> is serializable, and
--   <a>switchOn_</a> is not.
switchOnF :: (Monad m, Serialize c) => (c -> Auto m a b) -> Auto m a b -> Auto m (a, Blip c) b

-- | The non-serializing/non-resuming version of <a>switchOnF</a>. You sort
--   of might as well use <a>switchOn_</a>; this version might give rise to
--   more "disciplined" code, however, by being more restricted in power.
switchOnF_ :: Monad m => (c -> Auto m a b) -> Auto m a b -> Auto m (a, Blip c) b

-- | Essentially identical to <a>switchFrom_</a>, except insead of the
--   <a>Auto</a> outputting a blip stream of new <a>Auto</a>s to replace
--   itself with, it emits a blip stream of <tt>c</tt> --- and
--   <a>switchFromF</a> uses the <tt>c</tt> to create the new <a>Auto</a>.
--   
--   Here is the equivalent of the two examples from <a>switchFrom_</a>,
--   implemented with <a>switchFromF</a>; see the documentation for
--   <a>switchFrom_</a> for a description of what they are to do.
--   
--   <pre>
--   a1 :: Auto' Int (Int, Blip Int)
--   a1 = proc x -&gt; do
--       sums       &lt;- sumFrom 0 -&lt; x
--       switchBlip &lt;- inB 4     -&lt; 100
--       id -&lt; (sums, switchBlip)
--   
--   -- alternatively
--   a1' = sumFrom 0 &amp;&amp;&amp; (tagBlips 100 . inB 4)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (switchFromF (\x -&gt; (x,) &lt;$&gt; never) a1) [1..10]
--   [1,3,6,10,100,100,100,100,100,100]
--   </pre>
--   
--   <pre>
--   a2 :: Auto' Int (Int, Blip ())
--   a2 = proc x -&gt; do
--       sums       &lt;- sumFrom 0 -&lt; x
--       switchBlip &lt;- inB 3     -&lt; ()
--       id -&lt; (sums, switchBlip)
--   
--   -- alternatively
--   a2' = sumFrom 0 &amp;&amp;&amp; (tagBlips () . inB 3)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (switchFromF (const a2) a2) [101..112]
--   [ 101, 203, 306  -- first 'sumFrom', on first three items [101, 102, 103]
--   , 104, 209, 315  -- second 'sumFrom', on second three items [104, 105, 106]
--   , 107, 215, 324  -- third 'sumFrom', on third three items [107, 108, 109]
--   , 110, 221, 333] -- final 'sumFrom', on fourth three items [110, 111, 112]
--   </pre>
--   
--   Or, if you're only ever going to use <tt>a2</tt> in switching form:
--   
--   <pre>
--   a2s :: Auto' Int Int
--   a2s = switchFromF (const a2s) $ proc x -&gt; do
--             sums       &lt;- sumFrom 0 -&lt; x
--             switchBlip &lt;- inB 3     -&lt; ()
--             id -&lt; (c, swichBlip)
--   
--   -- or
--   a2s' = switchFromF (const a2s')
--        $ sumFrom 0 &amp;&amp;&amp; (tagBlips () . inB 3)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' a2s [101..112]
--   [101, 203, 306, 104, 209, 315, 107, 215, 324, 110, 221, 333]
--   </pre>
--   
--   As you can see, all of the simple examples from <a>switchFrom_</a> can
--   be implemented in <a>switchFromF</a>...and so can most real-life
--   examples. The advantage is that <a>switchFromF</a> is serializable,
--   and <a>switchFrom_</a> is not.
--   
--   Note that for the examples above, instead of using <a>const</a>, we
--   could have actually used the input parameter to create a new
--   <a>Auto</a> based on what we outputted.
switchFromF :: (Monad m, Serialize c) => (c -> Auto m a (b, Blip c)) -> Auto m a (b, Blip c) -> Auto m a b

-- | The non-serializing/non-resuming version of <a>switchFromF</a>. You
--   sort of might as well use <a>switchFrom_</a>; this version might give
--   rise to more "disciplined" code, however, by being more restricted in
--   power.
switchFromF_ :: Monad m => (c -> Auto m a (b, Blip c)) -> Auto m a (b, Blip c) -> Auto m a b

-- | Takes an innocent <a>Auto</a> and wraps a "reset button" around it. It
--   behaves just like the original <a>Auto</a> at first, but when the
--   input blip stream emits, the internal <a>Auto</a> is reset back to the
--   beginning.
--   
--   Here we have <tt>sumFrom</tt> wrapped around a reset button, and we
--   send in a blip stream that emits every 4 steps; so every 4th step, the
--   whole summer resets.
--   
--   <pre>
--   &gt;&gt;&gt; let a = resetOn (sumFrom 0) . (id &amp;&amp;&amp; every 4)
--   
--   &gt;&gt;&gt; streamAuto' a [101..112]
--   [ 101, 203, 306
--   , 104, 209, 315  -- resetted!
--   , 107, 215, 324  -- resetted!
--   , 110, 221, 333] -- resetted!
--   </pre>
resetOn :: Monad m => Auto m a b -> Auto m (a, Blip c) b

-- | Gives an <a>Auto</a> the ability to "reset" itself on command
--   
--   Basically acts like <tt><a>fmap</a> <a>fst</a></tt>
--   
--   <pre>
--   fmap fst :: Monad m =&gt; Auto m a (b, Blip c) -&gt; Auto m a b
--   </pre>
--   
--   But...whenever the blip stream emits..."resets" the <a>Auto</a> back
--   to the original state, as if nothing ever happened.
--   
--   Note that this resetting happens on the step <i>after</i> the blip
--   stream emits.
--   
--   Here is a summer that sends out a signal to reset itself whenever the
--   cumulative sum reaches 10 or higher:
--   
--   <pre>
--   limitSummer :: Auto' Int (Int, Blip ())
--   limitSummer = (id &amp;&amp;&amp; became (&gt;= 10)) . sumFrom 0
--   </pre>
--   
--   And now we throw it into <a>resetFrom</a>:
--   
--   <pre>
--   resettingSummer :: Auto' Int Int
--   resettingSummer = resetFrom limitSummer
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' resettingSummer [1..10]
--   [ 1, 3, 6, 10    -- and...reset!
--   , 5, 11          -- and...reset!
--   , 7, 15          -- and...reset!
--   , 9, 19 ]
--   </pre>
resetFrom :: Monad m => Auto m a (b, Blip c) -> Auto m a b


-- | This module contains various <a>Auto</a> transformers for manipulating
--   the flow of time/stepping rate of an <a>Auto</a>.
--   
--   Many of these are <a>Auto</a> "transformers", meaning that they take
--   in an <a>Auto</a> and return a transformed <a>Auto</a>, with new
--   stepping behavior.
--   
--   For example, there is <a>accelerate</a>:
--   
--   <pre>
--   <a>accelerate</a> :: <a>Monad</a> m =&gt; <a>Int</a> -&gt; <a>Auto</a> m a b -&gt; <a>Auto</a> m a [b]
--   </pre>
--   
--   <tt><a>accelerate</a> n</tt> turns an <a>Auto</a> into an <a>Auto</a>
--   that "steps itself" <tt>n</tt> times for every single input/step. The
--   result is a list of the results of each single step.
--   
--   There are also various <a>Auto</a>s for observing the passage of time
--   (<a>count</a>) and actiong as a "delay" or a way to access the
--   previously stepped values of an <a>Auto</a>.
module Control.Auto.Time

-- | A simple <a>Auto</a> that ignores all input; its output stream counts
--   upwards from zero.
--   
--   <pre>
--   &gt;&gt;&gt; take 10 . streamAuto' count $ repeat ()
--   [0,1,2,3,4,5,6,7,8,9]
--   </pre>
count :: (Serialize b, Num b) => Auto m a b

-- | A non-resuming/non-serializing version of <a>count</a>.
count_ :: Num b => Auto m a b

-- | When first asked for output, "primes" the <a>Auto</a> first by
--   streaming it with all of the given inputs first before processing the
--   first input. Aterwards, behaves like normal.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (priming [1,2,3] (sumFrom 0)) [1..10]
--   [7,9,12,16,21,27,34,42,51,61]
--   </pre>
--   
--   The <a>Auto</a> behaves as if it had already "processed" the
--   <tt>[1,2,3]</tt>, resulting in an accumulator of 6, before it starts
--   taking in any input.
--   
--   Normally this would be silly with an <a>Auto'</a>, because the above
--   is the same as:
--   
--   <pre>
--   &gt;&gt;&gt; let (_, a) = overList' (sumFrom 0) [1,2,3]
--   
--   &gt;&gt;&gt; streamAuto' a [1..10]
--   [7,9,12,16,21,27,34,42,51,61]
--   </pre>
--   
--   This becomes somewhat more useful when you have "monadic"
--   <a>Auto</a>s, and want to defer the execution until during normal
--   stepping:
--   
--   <pre>
--   &gt;&gt;&gt; _ &lt;- streamAuto (priming [1,2,3] (arrM print)) [10,11,12]
--   1    -- IO effects
--   2
--   3
--   10
--   11
--   12
--   </pre>
priming :: Monad m => [a] -> Auto m a b -> Auto m a b

-- | An <a>Auto</a> that returns the last value received by it. Given an
--   "initial value" to output first.
--   
--   From the signal processing world, this is known as the "lag operator"
--   <i>L</i>.
--   
--   This is (potentially) a <b>very dangerous</b> <a>Auto</a>, because its
--   usage and its very existence opens the door to breaking
--   denotative/declarative style and devolving into imperative style
--   coding. However, when used where it is supposed to be used, it is more
--   or less invaluable, and will be an essential part of many programs.
--   
--   Its main usage is for dealing with recursive bindings. If you ever are
--   laying out recursive bindings in a high-level/denotative way, you need
--   to have at least one value be able to have a "initial output" without
--   depending on anything else. <a>lastVal</a> and <a>delay</a> allow you
--   to do this.
--   
--   See the <a>recursive</a> example for more information on the
--   appropriate usage of <a>lastVal</a> and <a>delay</a>.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (lastVal 100) [1..10]
--   [100,1,2,3,4,5,6,7,8,9]
--   </pre>
lastVal :: Serialize a => a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>lastVal</a>.
lastVal_ :: a -> Auto m a a

-- | Like <a>arr</a>, but applies the function to the <i>previous value</i>
--   of the input, instead of the current value. Used for the same purposes
--   as <a>lastVal</a>: to manage recursive bindings.
--   
--   Warning: Don't use this to do imperative programming!
--   
--   <pre>
--   arrD id == lastVal
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (arrD negate 100) [1..10]
--   [100,-1,-2,-3,-4,-5,-6,-7,-8,-9]
--   </pre>
arrD :: Serialize b => (a -> b) -> b -> Auto m a b

-- | The non-resuming/non-serializing version of <a>arrD</a>.
arrD_ :: Serialize b => (a -> b) -> b -> Auto m a b

-- | An alias for <a>lastVal</a>; used in contexts where "delay" is more a
--   meaningful description than "last value". All of the warnings for
--   <a>lastVal</a> still apply, so you should probably read it if you
--   haven't :)
delay :: Serialize a => a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>delay</a>.
delay_ :: a -> Auto m a a

-- | Like <a>delay</a>, except has as many "initial values" as the input
--   list. Outputs every item in the input list in order before returning
--   the first received value.
--   
--   <pre>
--   delayList [y0] = delay y0
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (delayList [3,5,7,11]) [1..10]
--   [3,5,7,11,1,2,3,4,5,6]
--   </pre>
delayList :: (Serialize a, Monad m) => [a] -> Auto m a a

-- | The non-resuming/non-serializing version of <a>delayList</a>.
delayList_ :: Monad m => [a] -> Auto m a a

-- | Like <a>delay</a>, except delays the desired number of steps with the
--   same initial output value.
--   
--   <pre>
--   delayN n x0 = delayList (replicate n x0)
--   </pre>
--   
--   <pre>
--   delayN 1 x0 = delay x0
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (delayN 3 0) [1..10]
--   [0,0,0,1,2,3,4,5,6,7]
--   </pre>
delayN :: (Serialize a, Monad m) => Int -> a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>delayN</a>
delayN_ :: Monad m => Int -> a -> Auto m a a

-- | "stretch" an <a>Auto</a> out, slowing time. <tt><a>stretch</a> n
--   a</tt> will take one input, repeat the same output <tt>n</tt> times
--   (ignoring input), and then take another. It ignores all inputs in
--   between.
--   
--   <pre>
--   &gt;&gt;&gt; let a = stretch 2 (sumFrom 0)
--   
--   &gt;&gt;&gt; streamAuto' a [1,8,5,4,3,7,2,0]
--      [1,1,6,6,9,9,11,11]
--   -- [1,_,5,_,3,_,2 ,_ ] &lt;-- the inputs
--   </pre>
stretch :: (Serialize b, Monad m) => Int -> Auto m a b -> Auto m a b

-- | The non-resuming/non-serializing version of <a>stretch</a>.
stretch_ :: Monad m => Int -> Auto m a b -> Auto m a b

-- | Like <a>stretch</a>, but instead of holding the the "stretched"
--   outputs, outputs a blip stream that emits every time the stretched
--   <a>Auto</a> "progresses" (every <tt>n</tt> ticks)
--   
--   See <a>stretch</a> for more information.
--   
--   <pre>
--   &gt;&gt;&gt; let a = stretchB 2 (accum (+) 0)
--   
--   &gt;&gt;&gt; streamAuto' a [1,8,5,4,3,7,2,0]
--   [Blip 1, NoBlip, Blip 6, NoBlip, Blip 9, NoBlip, Blip 11, NoBlip]
--   </pre>
stretchB :: Monad m => Int -> Auto m a b -> Auto m a (Blip b)

-- | A more general version of <a>stretch</a>; instead of just ignoring and
--   dropping the "stretched/skipped intervals", accumulate all of them up
--   with the given accumulating function and then "step" them all at once
--   on every <tt>n</tt>th tick. Also, stead of returning exactly the same
--   output every time over the stretched interval, output a function of
--   the original output during the stretched intervals.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (sumFrom 0) [1..10]
--   [1, 3, 6, 10, 15, 21, 28, 36, 45 ,55]
--   
--   &gt;&gt;&gt; streamAuto' (stretchAccumBy (+) negate 4 (sumFrom 0)) [1..10]
--   [1,-1,-1, -1, 15,-15,-15,-15, 45,-45]
--   </pre>
--   
--   Here, instead of feeding in a number every step, it "accumulates" all
--   of the inputs using <a>+</a> and "blasts them into"
--   <tt><tt>sumFrom</tt> 0</tt> every 4 steps. In between the blasts, it
--   outputs the negated last seen result.
--   
--   You can recover the behavior of <a>stretch</a> with
--   <tt><a>stretchAccumBy</a> (flip const) id</tt>.
stretchAccumBy :: (Serialize a, Serialize b, Monad m) => (a -> a -> a) -> (b -> b) -> Int -> Auto m a b -> Auto m a b

-- | The non-serialized/non-resuming version of <a>stretchAccumBy</a>.
stretchAccumBy_ :: Monad m => (a -> a -> a) -> (b -> b) -> Int -> Auto m a b -> Auto m a b

-- | <tt><a>accelerate</a> n a</tt> turns an <a>Auto</a> <tt>a</tt> into an
--   "accelerated" <a>Auto</a>, where every input is fed into the
--   <a>Auto</a> <tt>n</tt> times. All of the results are collected in the
--   output.
--   
--   The same input is fed repeatedly <tt>n</tt> times.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (accelerate 3 (sumFrom 0)) [2,3,4]
--   [[2,4,6],[9,12,15],[19,23,27]]
--   -- ^adding 2s  ^adding 3s ^adding 4s
--   </pre>
accelerate :: Monad m => Int -> Auto m a b -> Auto m a [b]

-- | <tt><a>accelerateWith</a> xd n a</tt> is like <tt><a>accelerate</a> n
--   a</tt>, except instead of feeding in the input <tt>n</tt> times, it
--   feeds the input in once and repeats the "filler" <tt>xd</tt> for the
--   rest of the accelerating period.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (accelerateWith (-1) 3 (sumFrom 0)) [1,10,100]
--   [[1,0,-1],[9,8,7],[107,106,105]]
--   -- ^ feed in 1 once and -1 twice
--   --          ^ feed in 10 once and -1 twice
--   --                  ^ feed in 100 once and -1 twice
--   </pre>
accelerateWith :: Monad m => a -> Int -> Auto m a b -> Auto m a [b]

-- | <a>Accelerates</a> the <a>Auto</a>, so instead of taking an <tt>a</tt>
--   and returning a <tt>b</tt>, it takes a list of <tt>a</tt>, "streams"
--   the <a>Auto</a> over each one, and returns a list of <tt>b</tt>
--   results.
--   
--   For example, if you normally feed <tt><tt>sumFrom</tt> 0</tt> a 1,
--   then a 2, then a 3, you'd get a 1, then a 3, then a 6. But if you feed
--   <tt><a>accelOverList</a> (<tt>sumFrom</tt> 0)</tt> a <tt>[1,2]</tt>,
--   you'd get a <tt>[1,3]</tt>, and if you fed it a <tt>[3]</tt> after,
--   you'd get a <tt>[6]</tt>.
--   
--   Turns a <tt>[a] -&gt; [b]</tt> into an <tt>[[a]] -&gt; [[b]]</tt>; if
--   you "chunk up" the input stream <tt>a</tt>s into chunks of input to
--   feed all at once, the outputs <tt>b</tt> will be chunked up the same
--   way.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (sumFrom 0) [1,2,3,4,5,6,7,8]
--   [1,3,6,10,15,21,28,36]
--   
--   &gt;&gt;&gt; streamAuto' (accelOverList (sumFrom 0)) [[1,2],[],[3,4,5],[6],[7,8]]
--   [[1,3],[],[6,10,15],[21],[28,36]]
--   </pre>
--   
--   Mostly useful if you want to feed an <a>Auto</a> multiple inputs in
--   the same step. Note that if you always feed in singleton lists (lists
--   with one item), you'll more or less get the same behavior as normal.
accelOverList :: Monad m => Auto m a b -> Auto m [a] [b]

-- | Takes an <a>Auto</a> that produces <tt>(b, <a>Blip</a> c)</tt>, and
--   turns it into an <a>Auto</a> that produces <tt>([b], c)</tt>.
--   
--   Basically, the new <a>Auto</a> "squishes together" the periods of
--   output between each time the blip stream emits. All outputs between
--   each emitted value are accumulated and returned in the resulting
--   <tt>[b]</tt>.
--   
--   It "does this" in the same manner as <a>accelerateWith</a> and
--   <a>fastForward</a>: first feed the input, then step repeatedly with
--   the default input value.
--   
--   <pre>
--   &gt;&gt;&gt; let a :: Auto' Int (Int, Blip String)
--           a = proc i -&gt; do
--                   sums &lt;- sumFrom 0 -&lt; i
--                   blp  &lt;- every 3   -&lt; i     -- emits every 3 ticks.
--                   id    -&lt; (sums, sums &lt;&amp; blp) -- replace emitted value
--                                                -- with the running sum
--   
--   &gt;&gt;&gt; let skipA :: Auto' Int ([Int], String)
--           skipA = skipTo (-1) a
--   
--   &gt;&gt;&gt; let (res1, skipA') = stepAuto' skipA 8
--   
--   &gt;&gt;&gt; res1
--   ([8,7,6], 6)     -- fed 8 first, then (-1) repeatedly
--   
--   &gt;&gt;&gt; let (res2, _     ) = evalAuto skipA' 5
--   
--   &gt;&gt;&gt; res2
--   ([11,10,9], 9)   -- fed 5 first, then (-1) repeatedly
--   </pre>
--   
--   If the blip stream never emits then stepping this and getting the
--   result or the next/updated <a>Auto</a> never terminates...so watch
--   out!
skipTo :: Monad m => a -> Auto m a (b, Blip c) -> Auto m a ([b], c)

-- | Turns an <tt><a>Interval</a> m a b</tt> into an <tt><a>Auto</a> m a
--   b</tt> --- that is, an <tt><a>Auto</a> m a (Maybe b)</tt> into an
--   <tt><a>Auto</a> m a b</tt>.
--   
--   It does this by "skipping over" all "off"/<a>Nothing</a> input. When
--   the result "should" be a <a>Nothing</a>, it re-runs the
--   <a>Interval</a> over and over again with the given default input until
--   the <a>Auto</a> turns back "on" again (outputs a <a>Just</a>).
--   
--   If the <a>Interval</a> reaches a point where it will never be "on"
--   again, stepping this and getting the result or the next/updated
--   <a>Auto</a> won't terminate...so watch out!
--   
--   <pre>
--   &gt;&gt;&gt; let a1 = offFor 3 . sumFrom 0
--   
--   &gt;&gt;&gt; streamAuto' a1 [1..10]
--   [Nothing, Nothing, Nothing, Just 10, Just 15, Just 21]
--   
--   &gt;&gt;&gt; streamAuto' (fastForward 0 a1) [1..6]
--   [1,3,6,10,15,21]
--   
--   &gt;&gt;&gt; streamAuto' (fastForward (-10) a1) [1..6]
--   [-29,-27,-24,-20,-15,-9]
--   </pre>
--   
--   In that last example, the first input is 1, then it inputs (-10) until
--   it is "on"/<a>Just</a> again (on the fourth step). Then continues
--   imputing 2, 3, 4 etc.
fastForward :: Monad m => a -> Interval m a b -> Auto m a b

-- | Same behavior as <a>fastForward</a>, except accumulates all of the
--   <tt><a>Left</a> c</tt> outputs in a list.
fastForwardEither :: Monad m => a -> Auto m a (Either c b) -> Auto m a (b, [c])


-- | The <a>Auto</a>s in this module are all dedicated to managing and
--   working with (possibly dynamic) "collections" of <a>Auto</a>s: an
--   <a>Auto</a> where the output stream is typically <i>many</i> output
--   streams collected from running many input streams through many
--   internal <a>Auto</a>s.
--   
--   Particularly useful because a lot of these allow you to add or take
--   away these "channels of inputs" (or "internal <a>Auto</a>s")
--   dynamically; so, useful for collections that can be added to or
--   deleted from, like monsters on a map.
--   
--   These multiplex, merge, or collect input streams through many
--   <a>Auto</a>s and output the multiplexed, merged, or collected output
--   streams.
--   
--   A lot of these <a>Auto</a>s take advantaage <i>Interval</i> semantics
--   (<a>Maybe</a> for continuous on/off periods) to signal when they want
--   to be removed or turned off.
--   
--   For these, the best way to learn them is probably by seeing examples.
--   
--   If there is a time when you might want collections of things that can
--   be added to or removed from dynamically, this might be what you are
--   looking for.
--   
--   These collections are indispensible for coding real applications; many
--   examples of them in use are available in the <a>auto-examples</a>
--   project! See those projects for "real-world" guides.
module Control.Auto.Collection

-- | Give a list of <tt><a>Auto</a> m a b</tt> and get back an
--   <tt><a>Auto</a> m [a] [b]</tt> --- take a list of <tt>a</tt>'s and
--   feed them to each of the <a>Auto</a>s, and collects their output
--   <tt>b</tt>'s.
--   
--   If the input list doesn't have enough items to give to all of the
--   <a>Auto</a>s wrapped, then use the given default value. Any extra
--   items in the input list are ignored.
--   
--   For an example, we're going to make a list of <a>Auto</a>s that output
--   a running sum of all of their inputs, but each starting at a different
--   beginning value:
--   
--   <pre>
--   summerList :: [Auto' Int Int]
--   summerList = [sumFrom 0, sumFrom 10, sumFrom 20, sumFrom 30]
--   </pre>
--   
--   Then, let's throw it into <a>zipAuto</a> with a sensible default
--   value, 0:
--   
--   <pre>
--   summings0 :: Auto' [Int] [Int]
--   summings0 = zipAuto 0 summerList
--   </pre>
--   
--   Now let's try it out!
--   
--   <pre>
--   &gt;&gt;&gt; let (r1, summings1) = stepAuto' summings0 [1,2,3,4]
--   
--   &gt;&gt;&gt; r1
--   [ 1, 12, 23, 34]
--   
--   &gt;&gt;&gt; let (r2, summings2) = stepAuto' summings1 [5,5]
--   
--   &gt;&gt;&gt; r2
--   [ 6, 17, 23, 34]
--   
--   &gt;&gt;&gt; let (r3, _        ) = stepAuto' summings2 [10,1,10,1,10000]
--   
--   &gt;&gt;&gt; r3
--   [16, 18, 33, 35]
--   </pre>
zipAuto :: Monad m => a -> [Auto m a b] -> Auto m [a] [b]

-- | Like <a>zipAuto</a>, but delay the input by one step. The first input
--   to all of them is the "default" value, and after that, feeds in the
--   input streams delayed by one.
--   
--   Let's try the example from <a>zipAuto</a>, except with <a>dZipAuto</a>
--   instead:
--   
--   <pre>
--   summerList :: [Auto' Int Int]
--   summerList = map sumFrom [0, 10, 20, 30]
--   
--   summings0 :: Auto' [Int] [Int]
--   summings0 = dZipAuto 0 summerList
--   </pre>
--   
--   Trying it out:
--   
--   <pre>
--   &gt;&gt;&gt; let (r1, summings1) = stepAuto' summings0 [1,2,3,4]
--   
--   &gt;&gt;&gt; r1
--   [ 0, 10, 20, 30]
--   
--   &gt;&gt;&gt; let (r2, summings2) = stepAuto' summings1 [5,5]
--   
--   &gt;&gt;&gt; r2
--   [ 1, 12, 23, 34]
--   
--   &gt;&gt;&gt; let (r3, summings3) = stepAuto' summings2 [10,1,10,1,10000]
--   
--   &gt;&gt;&gt; r3
--   [ 6, 17, 23, 34]
--   
--   &gt;&gt;&gt; let (r4, _        ) = stepAuto' summings3 [100,100,100,100]
--   
--   &gt;&gt;&gt; r4
--   [16, 18, 33, 35]
--   </pre>
dZipAuto :: (Serialize a, Monad m) => a -> [Auto m a b] -> Auto m [a] [b]

-- | The non-serializing/non-resuming version of <a>dZipAuto</a>.
dZipAuto_ :: Monad m => a -> [Auto m a b] -> Auto m [a] [b]

-- | Takes a bunch of <a>Auto</a>s that take streams streams, and turns
--   them into one <a>Auto</a> that takes a bunch of blip streams and feeds
--   them into each of the original <a>Auto</a>s, in order.
--   
--   It's basically like <a>zipAuto</a>, except instead of taking in normal
--   streams of values, it takes in blip streams of values.
--   
--   If the input streams ever number less than the number of <a>Auto</a>s
--   zipped, the other <a>Auto</a>s are stepped assuming no emitted value.
zipAutoB :: Monad m => [Auto m (Blip a) b] -> Auto m [Blip a] [b]

-- | A delayed version of <a>zipAutoB</a>
dZipAutoB :: (Serialize a, Monad m) => [Auto m (Blip a) b] -> Auto m [Blip a] [b]

-- | The non-serializing/non-resuming version of <a>dZipAutoB</a>.
dZipAutoB_ :: Monad m => [Auto m (Blip a) b] -> Auto m [Blip a] [b]

-- | A dynamic box of <a>Interval</a>s. Takes a list of inputs to feed to
--   each one, in the order that they were added. Also takes a blip stream,
--   which emits with new <a>Interval</a>s to add to the box.
--   
--   Add new <a>Interval</a>s to the box however you want with the blip
--   stream.
--   
--   As soon as an <a>Interval</a> turns "off", the <a>Interval</a> is
--   removed from the box, and its output is silenced.
--   
--   The adding/removing aside, the routing of the inputs (the first field
--   of the tuple) to the internal <a>Auto</a>s and the outputs behaves the
--   same as with <a>zipAuto</a>.
--   
--   This will be a pretty powerful collection if you ever imagine adding
--   and destroying behaviors dynamically...like spawning new enemies, or
--   something like that.
--   
--   Let's see an example...here we are going to be throwing a bunch of
--   <a>Auto</a>s that count to five and then die into our
--   <a>dynZip_</a>...once every other step.
--   
--   <pre>
--   -- count upwards, then die when you reach 5
--   countThenDie :: <a>Interval'</a> () Int
--   countThenDie = onFor 5 . iterator (+1) 1
--   
--   -- emit a new <tt>countThenDie</tt> every two steps
--   throwCounters :: Auto' () (<a>Blip</a> [<a>Interval'</a> () Int])
--   throwCounters = tagBlips [countThenDie] . every 2
--   
--   a :: Auto' () [Int]
--   a = proc _ -&gt; do
--           newCounter &lt;- throwCounters -&lt; ()
--           dynZip_ ()  -&lt; (repeat (), newCounter)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let (res, _) = stepAutoN' 15 a ()
--   
--   &gt;&gt;&gt; res
--   [[], [1            ]
--      , [2,           ]
--      , [3, 1         ]
--      , [4, 2         ]
--      , [5, 3, 1      ]
--      , [   4, 2      ]
--      , [   5, 3, 1   ]
--      , [      4, 2   ]
--      , [      5, 3, 1]
--   ]
--   </pre>
--   
--   This is a little unweildy, because <a>Auto</a>s maybe disappearing out
--   of the thing while you are trying to feed inputs into it. You might be
--   feeding an input to an <a>Auto</a>...but one of the <a>Auto</a>s
--   before it on the list has disappeared, so it accidentally goes to the
--   wrong one.
--   
--   Because of this, it is suggested that you use <a>dynMap_</a>, which
--   allows you to "target" labeled <a>Auto</a>s with your inputs.
--   
--   This <a>Auto</a> is inherently unserializable, but you can use
--   <a>dynZipF</a> for more or less the same functionality, with
--   serialization possible. It's only slightly less powerful...for all
--   intents and purposes, you should be able to use both in the same
--   situations. All of the examples here can be also done with
--   <a>dynZipF</a>.
dynZip_ :: Monad m => a -> Auto m ([a], Blip [Interval m a b]) [b]

-- | Like <a>dynZip_</a>, but instead of taking in a blip stream of
--   <a>Interval</a>s directly, takes in a blip stream of <tt>k</tt>s to
--   trigger adding more <a>Interval</a>s to the "box", using the given
--   <tt>k -&gt; <a>Interval</a> m a b</tt> function to make the new
--   <a>Interval</a> to add.
--   
--   Pretty much all of the power of <a>dynZip_</a>, but with
--   serialization.
--   
--   See <a>dynZip_</a> for examples and caveats.
--   
--   You could theoretically recover the behavior of <a>dynZip_</a> with
--   <tt><a>dynZipF</a> id</tt>, if there wasn't a <a>Serialize</a>
--   constraint on the <tt>k</tt>.
dynZipF :: (Serialize k, Monad m) => (k -> Interval m a b) -> a -> Auto m ([a], Blip [k]) [b]

-- | The non-serializing/non-resuming version of <a>dynZipF</a>. Well, you
--   really might as well use <a>dynZip_</a>, which is more powerful...but
--   maybe using this can inspire more disciplined usage. Also works as a
--   drop-in replacement for <a>dynZipF</a>.
dynZipF_ :: Monad m => (k -> Interval m a b) -> a -> Auto m ([a], Blip [k]) [b]

-- | A dynamic box of <a>Auto</a>s, indexed by an <a>Int</a>. Takes an
--   <a>IntMap</a> of inputs to feed into their corresponding <a>Auto</a>s,
--   and collect all of the outputs into an output <a>IntMap</a>.
--   
--   Whenever any of the internal <a>Auto</a>s return <a>Nothing</a>, they
--   are removed from the collection.
--   
--   <pre>
--   &gt;&gt;&gt; import qualified Data.IntMap as IM
--   
--   &gt;&gt;&gt; let dm0 :: Auto' (IM.IntMap Int) (IM.IntMap Int)
--           dm0 = proc x -&gt; do
--                     initials &lt;- immediately -&lt; [ Just &lt;$&gt; sumFrom 0
--                                                , Just &lt;$&gt; sumFrom 10 ]
--                     newIs    &lt;- every 3     -&lt; [ Just &lt;$&gt; sumFrom 0  ]
--                     dynMap_ (-1) -&lt; (x, initials `mergeL` newIs)
--   
--   &gt;&gt;&gt; let (res1, dm1) = stepAuto' dm0 mempty
--   
--   &gt;&gt;&gt; res1
--   fromList [(0, -1), (1, 9)]
--   
--   &gt;&gt;&gt; let (res2, dm2) = stepAuto' dm1 (IM.fromList [(0,100),(1,50)])
--   
--   &gt;&gt;&gt; res2
--   fromList [(0, 99), (1, 59)]
--   
--   &gt;&gt;&gt; let (res3, dm3) = stepAuto' dm2 (IM.fromList [(0,10),(1,5)])
--   
--   &gt;&gt;&gt; res3
--   fromList [(0, 109), (1, 64), (2, -1)]
--   
--   &gt;&gt;&gt; let (res4, _  ) = stepAuto' dm3 (IM.fromList [(1,5),(2,5)])
--   
--   &gt;&gt;&gt; res4
--   fromList [(0, 108), (1, 69), (2, 4)]
--   </pre>
--   
--   One quirk is that every internal <a>Auto</a> is "stepped" at every
--   step with the default input; <a>gatherMany</a> is a version of this
--   where <a>Auto</a>s that do not have a corresponding "input" are left
--   unstepped, and their last output preserved in the aggregate output. As
--   such, <a>gatherMany</a> might be seen more often.
--   
--   This <a>Auto</a> is inherently unserializable, but you can use
--   <a>dynMapF</a> for more or less the same functionality, with
--   serialization possible. It's only slightly less powerful...for all
--   intents and purposes, you should be able to use both in the same
--   situations. All of the examples here can be also done with
--   <a>dynMapF</a>.
dynMap_ :: Monad m => a -> Auto m (IntMap a, Blip [Interval m a b]) (IntMap b)

-- | Like <a>dynMap_</a>, but instead of taking in a blip stream of
--   <a>Interval</a>s directly, takes in a blip stream of <tt>k</tt>s to
--   trigger adding more <a>Interval</a>s to the "box", using the given
--   <tt>k -&gt; <a>Interval</a> m a b</tt> function to make the new
--   <a>Interval</a> to add.
--   
--   Pretty much all of the power of <a>dynMap_</a>, but with
--   serialization.
--   
--   See <a>dynMap_</a> for examples and use cases.
--   
--   You could theoretically recover the behavior of <a>dynMap_</a> with
--   <tt><a>dynMapF</a> id</tt>, if there wasn't a <a>Serialize</a>
--   constraint on the <tt>k</tt>.
dynMapF :: (Serialize k, Monad m) => (k -> Interval m a b) -> a -> Auto m (IntMap a, Blip [k]) (IntMap b)

-- | The non-serializing/non-resuming version of <a>dynMapF</a>. Well, you
--   really might as well use <a>dynMap_</a>, which is more powerful...but
--   maybe using this can inspire more disciplined usage. Also works as a
--   drop-in replacement for <a>dynMapF</a>.
dynMapF_ :: Monad m => (k -> Interval m a b) -> a -> Auto m (IntMap a, Blip [k]) (IntMap b)

-- | <a>Auto</a> multiplexer. Stores a bunch of internal <a>Auto</a>s
--   indexed by a key. At every step, takes a key-input pair, feeds the
--   input to the <a>Auto</a> stored at that key and outputs the output.
--   
--   If the key given does not yet have an <a>Auto</a> stored at that key,
--   initializes a new <a>Auto</a> at that key by using the supplied
--   function.
--   
--   Once initialized, these <a>Auto</a>s are stored there forever.
--   
--   You can play around with some combinators from
--   <a>Control.Auto.Switch</a>; for example, with <tt>resetOn</tt>, you
--   can make <a>Auto</a>s that "reset" themselves when given a certain
--   input. <tt>switchOnF</tt> could be put to use here too in neat ways.
--   
--   <pre>
--   &gt;&gt;&gt; let mx0 = mux (\_ -&gt; sumFrom 0)
--   
--   &gt;&gt;&gt; let (res1, mx1) = stepAuto' mx0 ("hello", 5)
--   
--   &gt;&gt;&gt; res1
--   5
--   
--   &gt;&gt;&gt; let (res2, mx2) = stepAuto' mx1 ("world", 3)
--   
--   &gt;&gt;&gt; res2
--   3
--   
--   &gt;&gt;&gt; let (res3, mx3) = stepAuto' mx2 ("hello", 4)
--   
--   &gt;&gt;&gt; res3
--   9
--   
--   &gt;&gt;&gt; streamAuto' mx3 [("world", 2), ("foo", 6), ("foo", 1), ("hello", 2)]
--   [5, 6, 7, 11]
--   </pre>
mux :: (Serialize k, Ord k, Monad m) => (k -> Auto m a b) -> Auto m (k, a) b

-- | The non-serializing/non-resuming version of <a>mux</a>.
mux_ :: (Ord k, Monad m) => (k -> Auto m a b) -> Auto m (k, a) b

-- | Like <a>muxI</a>, but holds <a>Interval</a>s instead. When any given
--   <a>Interval</a> turns "off", it's removed from the collection. If its
--   key is fed in again, it'll be restarted with the initializing
--   function. On the actual step when it turns "off", <a>Nothing</a> will
--   be returned.
muxI :: (Serialize k, Ord k, Monad m) => (k -> Interval m a b) -> Auto m (k, a) (Maybe b)

-- | The non-serializing/non-resuming version of <a>muxI</a>.
muxI_ :: (Ord k, Monad m) => (k -> Interval m a b) -> Auto m (k, a) (Maybe b)

-- | <a>Auto</a> multiplexer, like <a>mux</a>, except allows update/access
--   of many <a>Auto</a>s at a time. Instead of taking in a single
--   key-value pair and outputting a single result, takes in an entire
--   <a>Map</a> of key-value pairs and outputs a <a>Map</a> of key-result
--   pairs.
--   
--   <pre>
--   &gt;&gt;&gt; import qualified Data.Map as M
--   
--   &gt;&gt;&gt; let mx0 = mux (\_ -&gt; sumFrom 0)
--   
--   &gt;&gt;&gt; let (res1, mx1) = stepAuto' mx0 (M.fromList [ ("hello", 5)
--                                                   , ("world", 3) ])
--   
--   &gt;&gt;&gt; res1
--   fromList [("hello", 5), ("world", 3)]
--   
--   &gt;&gt;&gt; let (res2, mx2) = stepAuto' mx1 (M.fromList [ ("hello", 4)
--                                                   , ("foo"  , 7) ])
--   
--   &gt;&gt;&gt; res2
--   fromList [("foo", 7), ("hello", 9)]
--   
--   &gt;&gt;&gt; let (res3, _  ) = mx2 (M.fromList [("world", 3), ("foo", 1)])
--   
--   &gt;&gt;&gt; res3
--   fromList [("foo", 8), ("world", 6)]
--   </pre>
--   
--   See <a>mux</a> for more notes.
muxMany :: (Serialize k, Ord k, Monad m) => (k -> Auto m a b) -> Auto m (Map k a) (Map k b)

-- | The non-serializing/non-resuming version of <a>muxMany</a>.
muxMany_ :: (Ord k, Monad m) => (k -> Auto m a b) -> Auto m (Map k a) (Map k b)

-- | Like <a>muxManyI</a>, but holds <a>Interval</a>s instead. When any
--   given <a>Interval</a> turns "off", it's removed from the collection.
--   Only <a>Interval</a>s that are "on" after the step will be present in
--   the output <a>Map</a>.
muxManyI :: (Serialize k, Ord k, Monad m) => (k -> Interval m a b) -> Auto m (Map k a) (Map k b)

-- | The non-serializing/non-resuming version of <a>muxManyI</a>.
muxManyI_ :: (Ord k, Monad m) => (k -> Interval m a b) -> Auto m (Map k a) (Map k b)

-- | Keeps an internal <a>Map</a> of <a>Interval</a>s and, at every step,
--   the output is the last seen output of every <a>Interval</a>, indexed
--   under the proper key.
--   
--   At every step, the input is a key-value pair; <a>gather</a> will feed
--   that input value to the <a>Interval</a> under the proper key and
--   update the output map with that new result.
--   
--   If the key offered the input is not yet a part of the collection,
--   initializes it with the given function.
--   
--   Any <a>Interval</a> that turns "off" (outputs <a>Nothing</a>) from
--   this will be immediately removed from the collection. If something for
--   that key is received again, it will re-initialize it.
--   
--   <pre>
--   &gt;&gt;&gt; let sumUntil :: Interval' Int Int
--           sumUntil = proc x -&gt; do
--                          sums &lt;- sumFrom 0     -&lt; x
--                          stop &lt;- became (&gt; 10) -&lt; sums
--                          before -&lt; (sums, stop)
--       -- (a running sum, "on" until the sum is greater than 10)
--   
--   &gt;&gt;&gt; let gt0 = gather (\_ -&gt; sumUntil)
--   
--   &gt;&gt;&gt; let (res1, gt1) = stepAuto' gt0 ("hello", 5)
--   
--   &gt;&gt;&gt; res1
--   fromList [("hello", 5)]
--   
--   &gt;&gt;&gt; let (res2, gt2) = stepAuto' gt1 ("world", 7)
--   
--   &gt;&gt;&gt; res2
--   fromList [("hello", 5), ("world", 7)]
--   
--   &gt;&gt;&gt; let (res3, gt3) = stepAuto' gt2 ("foo", 4)
--   
--   &gt;&gt;&gt; res3
--   fromList [("foo", 4), ("hello", 5), ("world", 7)]
--   
--   &gt;&gt;&gt; let (res4, gt4) = stepAuto' gt3 ("world", 8)
--   
--   &gt;&gt;&gt; res4
--   fromList [("foo", 4), ("hello", 5)]
--   
--   &gt;&gt;&gt; streamAuto' gt4 [("world", 2),("bar", 9),("world", 6),("hello", 11)]
--   [ fromList [("foo", 4), ("hello", 5), ("world", 2)]
--   , fromList [("bar", 9), ("foo", 4), ("hello", 5), ("world", 2)]
--   , fromList [("bar", 9), ("foo", 4), ("hello", 5), ("world", 8)]
--   , fromList [("bar", 9), ("foo", 4), ("world", 8)]
--   ]
--   </pre>
--   
--   In practice this ends up being a very common collection; see the
--   <a>auto-examples</a> project for many examples!
--   
--   Because everything needs a <tt>key</tt>, you don't have the fancy
--   "auto-generate new keys" feature of <tt>dynMap</tt>...however, you
--   could always pull a new key from <tt><tt>perBlip</tt>
--   <tt>enumFromA</tt></tt> or something.
--   
--   Like with <a>mux</a>, combinators from <a>Control.Auto.Switch</a> like
--   <tt>resetOn</tt> and <tt>switchOnF</tt> are very useful here!
gather :: (Ord k, Monad m, Serialize k, Serialize b) => (k -> Interval m a b) -> Auto m (k, a) (Map k b)

-- | The non-serializing/non-resuming version of <a>gather</a>:
--   
--   <b>Does</b> serialize the actual <b><a>Auto</a>s</b> themselves; the
--   <a>Auto</a>s are all serialized and re-loaded/resumed when 'gather_ f'
--   is resumed.
--   
--   Does <b>not</b> serialize the "last outputs", so resumed <a>Auto</a>s
--   that have not yet been re-run/accessed to get a fresh output are not
--   represented in the output map at first.
gather_ :: (Ord k, Monad m, Serialize k) => (k -> Interval m a b) -> Auto m (k, a) (Map k b)

-- | The non-serializing/non-resuming vervsion of <a>gather</a>:
--   
--   Serializes neither the <a>Auto</a>s themselves nor the "last outputs"
--   --- essentially, serializes/resumes nothing.
gather__ :: (Ord k, Monad m) => (k -> Interval m a b) -> Auto m (k, a) (Map k b)

-- | Much like <a>gather</a>, except allows you to pass in multiple
--   key-value pairs every step, to update multiple internal <a>Auto</a>s.
--   
--   <pre>
--   &gt;&gt;&gt; import qualified Data.Map as M
--   
--   &gt;&gt;&gt; let sumUntil :: Interval' Int Int
--           sumUntil = proc x -&gt; do
--                          sums &lt;- sumFrom 0     -&lt; x
--                          stop &lt;- became (&gt; 10) -&lt; sums
--                          before -&lt; (sums, stop)
--       -- (a running sum, "on" until the sum is greater than 10)
--   
--   &gt;&gt;&gt; let gm0 = gatherMany (\_ -&gt; sumUntil)
--   
--   &gt;&gt;&gt; let (res1, gm1) = stepAuto' gm0 (M.fromList [ ("hello", 5)
--                                                   , ("world", 7)
--                                                   ])
--   
--   &gt;&gt;&gt; res1
--   fromList [("hello", 5), ("world", 7)]
--   
--   &gt;&gt;&gt; let (res2, gm2) = stepAuto' gm1 (M.fromList [ ("foo", 4)
--                                                   , ("hello", 3)
--                                                   ])
--   
--   &gt;&gt;&gt; res2
--   fromList [("foo", 4), ("hello", 8), ("world", 7)]
--   
--   &gt;&gt;&gt; let (res3, gm3) = stepAuto' gm2 (M.fromList [ ("world", 8)
--                                                   , ("bar", 9)
--                                                   ])
--   
--   &gt;&gt;&gt; res3
--   fromList [("bar", 9), ("foo", 4), ("hello", 8)]
--   
--   &gt;&gt;&gt; let (res4, _  ) = stepAuto' gm3 (M.fromList [ ("world", 2)
--                                                   , ("bar", 10)
--                                                   ])
--   
--   &gt;&gt;&gt; res4
--   fromList [("foo", 4), ("hello", 8), ("world", 2)]
--   </pre>
--   
--   See <a>gather</a> for more notes.
gatherMany :: forall k a m b. (Ord k, Monad m, Serialize k, Serialize b) => (k -> Interval m a b) -> Auto m (Map k a) (Map k b)

-- | The non-serializing/non-resuming version of <a>gatherMany</a>:
--   
--   <b>Does</b> serialize the actual <b><a>Auto</a>s</b> themselves; the
--   <a>Auto</a>s are all serialized and re-loaded/resumed when
--   'gatherMany_ f' is resumed.
--   
--   Does <b>not</b> serialize the "last outputs", so resumed <a>Auto</a>s
--   that have not yet been re-run/accessed to get a fresh output are not
--   represented in the output map at first.
gatherMany_ :: forall k a m b. (Ord k, Monad m, Serialize k) => (k -> Interval m a b) -> Auto m (Map k a) (Map k b)

-- | The non-serializing/non-resuming vervsion of <a>gatherMany</a>:
--   
--   Serializes neither the <a>Auto</a>s themselves nor the "last outputs"
--   --- essentially, serializes/resumes nothing.
gatherMany__ :: forall k a m b. (Ord k, Monad m) => (k -> Interval m a b) -> Auto m (Map k a) (Map k b)


-- | This module serves as the main entry point for the library; these are
--   all basically re-exports. The re-exports are chosen so you can start
--   doing "normal things" off the bat, including all of the types used in
--   this library.
--   
--   Conspicuously missing are the most of the tools for working with
--   <a>Interval</a>, <a>Blip</a> streams, switches, and the "collection"
--   autos; those are all pretty heavy, and if you do end up working with
--   any of those tools, simply importing the appropriate module should
--   give you all you need.
--   
--   See the <a>tutorial</a> if you need help getting started!
module Control.Auto

-- | The <a>Auto</a> type. For this library, an <a>Auto</a> semantically
--   represents<i>denotes a </i>a relationship/ between an input and an
--   output that is preserved over multiple steps, where that relationship
--   is (optionally) maintained within the context of a monad.
--   
--   A lot of fancy words, I know...but you can think of an <a>Auto</a> as
--   nothing more than a "stream transformer" of value streams. A stream of
--   sequential input values come in one at a time, and a stream of outputs
--   pop out one at a time, as well.
--   
--   Using the <tt>streamAuto</tt> function, you can "unwrap" the inner
--   value stream transformer from any <a>Auto</a>: if <tt>a :: <a>Auto</a>
--   m a b</tt>, <tt>streamAuto</tt> lets you turn it into an <tt>[a] -&gt;
--   m [b]</tt>. "Give me a stream of <tt>a</tt>s, one at a time, and I'll
--   give you a list of <tt>b</tt>s, matching a relationship to your stream
--   of <tt>a</tt>s."
--   
--   <pre>
--   -- unwrap your inner [a] -&gt; m [b]!
--   <tt>streamAuto</tt> :: Monad m =&gt; <a>Auto</a> m a b -&gt; ([a] -&gt; m [b])
--   </pre>
--   
--   You can also turn an <tt><a>Auto</a> m a b</tt> into an <i>effects
--   stream</i> that executes effects sequentially with
--   <tt>toEffectStream</tt> and <tt>streamAutoEffects</tt>, so you can run
--   it with a ListT-compatible library like <i>pipes</i>.
--   
--   There's a handy type synonym <a>Auto'</a> for relationships that don't
--   really need a monadic context; the <tt>m</tt> is just <a>Identity</a>:
--   
--   <pre>
--   type Auto' = Auto Identity
--   </pre>
--   
--   So if you had an <tt>a :: <a>Auto'</a> a b</tt>, you can use
--   <tt>streamAuto'</tt> to "unwrap" the inner stream transformer, <tt>[a]
--   -&gt; [b]</tt>.
--   
--   <pre>
--   -- unwrap your inner [a] -&gt; [b]!
--   <tt>streamAuto'</tt> :: <a>Auto'</a> a b -&gt; ([a] -&gt; [b])
--   </pre>
--   
--   All of the <a>Auto</a>s given in this library maintain some sort of
--   semantic relationship between streams --- for some, the outputs might
--   be the inputs with a function applied; for others, the outputs might
--   be the cumulative sum of the inputs.
--   
--   See the <a>tutorial</a> for more information!
--   
--   Operationally, an <tt><a>Auto</a> m a b</tt> is implemented as a
--   "stateful function". A function from an <tt>a</tt> where, every time
--   you "apply" it, you get a <tt>b</tt> and an "updated
--   <a>Auto</a>"/function with updated state.
--   
--   You can get this function using <a>stepAuto</a>:
--   
--   <pre>
--   <a>stepAuto</a> :: <a>Auto</a> m a b -&gt; (a -&gt; m (b, <a>Auto</a> m a b))
--   </pre>
--   
--   Or, for <a>Auto'</a>, <a>stepAuto'</a>:
--   
--   <pre>
--   <a>stepAuto'</a> :: <a>Auto'</a> a b -&gt; (a -&gt; (b, <a>Auto'</a> a b))
--   </pre>
--   
--   "Give me an <tt>a</tt> and I'll give you a <tt>b</tt> and your
--   "updated" <a>Auto</a>".
--   
--   <a>Auto</a>s really are mostly useful because they can be composed,
--   chained, and modified using their various typeclass instances, like
--   <a>Category</a>, <a>Applicative</a>, <a>Functor</a>, <a>Arrow</a>,
--   etc., and also with the combinators in this library. You can build
--   complex programs as a complex <a>Auto</a> by building up smaller and
--   smaller components. See the tutorial for more information on this.
--   
--   This type also contains information on its own serialization, so you
--   can serialize and re-load the internal state to binary or disk. See
--   the "serialization" section in the documentation for
--   <a>Control.Auto.Core</a>, or the documentation for <a>mkAutoM</a> for
--   more details.
data Auto m a b

-- | Special case of <a>Auto</a> where the underlying <a>Monad</a> is
--   <a>Identity</a>.
--   
--   Instead of "wrapping" an <tt>[a] -&gt; m [b]</tt>, it "wraps" an
--   <tt>[a] -&gt; [b]</tt>.
type Auto' = Auto Identity

-- | When used in the context of an input or output of an <tt>Auto</tt>, a
--   <tt><a>Blip</a> a</tt> represents a stream that occasionally, at
--   "independent" or "discrete" points, emits a value of type <tt>a</tt>.
--   
--   Contrast this to <tt>Interval</tt>, where things are meant to be "on"
--   or "off" for contiguous chunks at a time; blip streams are "blippy",
--   and <tt>Interval</tt>s are "chunky".
--   
--   It's here mainly because it's a pretty useful abstraction in the
--   context of the many combinators found in various modules of this
--   library. If you think of an <tt><tt>Auto</tt> m a (<a>Blip</a> b)</tt>
--   as producing a "blip stream", then there are various combinators and
--   functions that are specifically designed to manipulate blip streams.
--   
--   For the purposes of the semantics of what <a>Blip</a> is supposed to
--   represent, its constructors are hidden. (Almost) all of the various
--   <a>Blip</a> combinators (and its very useful <a>Functor</a> instance)
--   "preserve <a>Blip</a>ness" --- one-at-a-time occurrences remain
--   one-at-a-time under all of these combinators, and you should have
--   enough so that direct access to the constructor is not needed.
--   
--   If you are creating a framework, library, or backend, you might want
--   to manually create blip stream-producing <tt>Auto</tt>s for your users
--   to access. In this case, you can import the constructors and useful
--   internal (and, of course, semantically unsafe) functions from
--   <a>Control.Auto.Blip.Internal</a>.
data Blip a

-- | Represents a relationship between an input and an output, where the
--   output can be "on" or "off" (using <a>Just</a> and <a>Nothing</a>) for
--   contiguous chunks of time.
--   
--   "Just" a type alias for <tt><a>Auto</a> m a (<a>Maybe</a> b)</tt>. If
--   you ended up here with a link...no worries! If you see
--   <tt><a>Interval</a> m a b</tt>, just think <tt><a>Auto</a> m a
--   (<a>Maybe</a> b)</tt> for type inference/type checking purposes.
--   
--   If you see something of type <a>Interval</a>, you can rest assured
--   that it has "interval semantics" --- it is on and off for meaningfully
--   contiguous chunks of time, instead of just on and off willy nilly. If
--   you have a function that expects an <a>Interval</a>, then the function
--   expects its argument to behave in this way.
type Interval m a b = Auto m a (Maybe b)

-- | <a>Interval</a>, specialized with <tt>Identity</tt> as its underlying
--   <a>Monad</a>. Analogous to <a>Auto'</a> for <a>Auto</a>.
type Interval' a b = Auto' a (Maybe b)

-- | <a>Runs</a> the <a>Auto</a> through one step.
--   
--   That is, given an <tt><a>Auto</a> m a b</tt>, returns a function that
--   takes an <tt>a</tt> and returns a <tt>b</tt> and an "updated"/"next"
--   <a>Auto</a>; an <tt>a -&gt; m (b, <a>Auto</a> m a b)</tt>.
--   
--   This is the main way of running an <a>Auto</a> "step by step", so if
--   you have some sort of game loop that updates everything every "tick",
--   this is what you're looking for. At every loop, gather input
--   <tt>a</tt>, feed it into the <a>Auto</a>, "render" the result
--   <tt>b</tt>, and get your new <a>Auto</a> to run the next time.
--   
--   Here is an example with <tt><tt>sumFrom</tt> 0</tt>, the <a>Auto</a>
--   whose output is the cumulative sum of the inputs, and an underying
--   monad of <tt>Identity</tt>. Here,
--   
--   <pre>
--   stepAuto :: Auto Identity Int Int
--            -&gt; (Int -&gt; Identity (Int, Auto Identity Int Int))
--   </pre>
--   
--   Every time you "step", you give it an <a>Int</a> and get a resulting
--   <a>Int</a> (the cumulative sum) and the "updated <a>Auto</a>", with
--   the updated accumulator.
--   
--   <pre>
--   &gt;&gt;&gt; let a0 :: Auto Identity Int Int
--           a0 = sumFrom 0
--   
--   &gt;&gt;&gt; let Identity (res1, a1) = stepAuto a0 4      -- run with 4
--   
--   &gt;&gt;&gt; res1
--   4                -- the cumulative sum, 4
--   
--   &gt;&gt;&gt; let Identity (res2, a2) = stepAuto a1 5      -- run with 5
--   
--   &gt;&gt;&gt; res2
--   9                -- the cumulative sum, 4 + 5
--   
--   &gt;&gt;&gt; let Identity (res3, _ ) = stepAuto a2 3      -- run with 3
--   
--   &gt;&gt;&gt; res3
--   12               -- the cumulative sum, 4 + 5 + 3
--   </pre>
--   
--   By the way, for the case where your <a>Auto</a> is under
--   <a>Identity</a>, we have a type synomym <a>Auto'</a>...and a
--   convenience function to make "running" it more streamlined:
--   
--   <pre>
--   &gt;&gt;&gt; let a0 :: Auto' Int Int
--           a0 = sumFrom 0
--   
--   &gt;&gt;&gt; let (res1, a1) = stepAuto' a0 4          -- run with 4
--   
--   &gt;&gt;&gt; res1
--   4                -- the cumulative sum, 4
--   
--   &gt;&gt;&gt; let (res2, a2) = stepAuto' a1 5          -- run with 5
--   
--   &gt;&gt;&gt; res2
--   9                -- the cumulative sum, 4 + 5
--   
--   &gt;&gt;&gt; let (res3, _ ) = stepAuto' a2 3          -- run with 3
--   
--   &gt;&gt;&gt; res3
--   12               -- the cumulative sum, 4 + 5 + 3
--   </pre>
--   
--   But, if your <a>Auto</a> actaully has effects when being stepped,
--   <a>stepAuto</a> will execute them:
--   
--   <pre>
--   &gt;&gt;&gt; let a0 :: Auto IO Int Int
--           a0 = effect (putStrLn "hey!") *&gt; sumFrom 0
--   
--   &gt;&gt;&gt; (res1, a1) &lt;- stepAuto a0 4              -- run with 4
--   hey!         -- IO effect
--   
--   &gt;&gt;&gt; res1
--   4                -- the cumulative sum, 4
--   
--   &gt;&gt;&gt; (res2, a2) &lt;- stepAuto a1 5              -- run with 5
--   hey!         -- IO effect
--   
--   &gt;&gt;&gt; res2
--   9                -- the cumulative sum, 4 + 5
--   
--   &gt;&gt;&gt; (res3, _ ) &lt;- stepAuto a2 3              -- run with 3
--   hey!         -- IO effect
--   
--   &gt;&gt;&gt; res3
--   12               -- the cumulative sum, 4 + 5 + 3
--   </pre>
--   
--   (Here, <tt><tt>effect</tt> (<a>putStrLn</a> "hey")</tt> is an
--   <tt><a>Auto</a> IO Int ()</tt>, which ignores its input and just
--   executes <tt><a>putStrLn</a> "hey"</tt> every time it is run. When we
--   use <a>*&gt;</a> from <a>Control.Applicative</a>, we "combine" the two
--   <a>Auto</a>s together and run them <i>both</i> on each input (4, 5,
--   3...)...but for the "final" output at the end, we only return the
--   output of the second one, <tt><tt>sumFrom</tt> 0</tt> (5, 9, 12...))
--   
--   If you think of an <tt><a>Auto</a> m a b</tt> as a "stateful function"
--   <tt>a -&gt; m b</tt>, then <a>stepAuto</a> lets you "run" it.
--   
--   In order to directly run an <a>Auto</a> on a stream, an <tt>[a]</tt>,
--   use <tt>streamAuto</tt>. That gives you an <tt>[a] -&gt; m [b]</tt>.
stepAuto :: Monad m => Auto m a b -> a -> m (b, Auto m a b)

-- | <a>Runs</a> an <a>Auto'</a> through one step.
--   
--   That is, given an <tt><a>Auto'</a> a b</tt>, returns a function that
--   takes an <tt>a</tt> and returns a <tt>b</tt> and an "updated"/"next"
--   <a>Auto'</a>; an <tt>a -&gt; (b, <a>Auto'</a> a b)</tt>.
--   
--   See <a>stepAuto</a> documentation for motivations, use cases, and more
--   details. You can use this instead of <a>stepAuto</a> when your
--   underyling monad is <a>Identity</a>, and your <a>Auto</a> doesn't
--   produce any effects.
--   
--   Here is an example with <tt><tt>sumFrom</tt> 0</tt>, the <a>Auto'</a>
--   whose output is the cumulative sum of the inputs
--   
--   <pre>
--   stepAuto' :: Auto' Int Int
--             -&gt; (Int -&gt; (Int, Auto' Int Int))
--   </pre>
--   
--   Every time you "step", you give it an <a>Int</a> and get a resulting
--   <a>Int</a> (the cumulative sum) and the "updated <a>Auto'</a>", with
--   the updated accumulator.
--   
--   <pre>
--   &gt;&gt;&gt; let a0 :: Auto' Int Int
--           a0 = sumFrom 0
--   
--   &gt;&gt;&gt; let (res1, a1) = stepAuto' a0 4          -- run with 4
--   
--   &gt;&gt;&gt; res1
--   4                -- the cumulative sum, 4
--   
--   &gt;&gt;&gt; let (res2, a2) = stepAuto' a1 5          -- run with 5
--   
--   &gt;&gt;&gt; res2
--   9                -- the cumulative sum, 4 + 5
--   
--   &gt;&gt;&gt; let (res3, _ ) = stepAuto' a2 3          -- run with 3
--   
--   &gt;&gt;&gt; res3
--   12               -- the cumulative sum, 4 + 5 + 3
--   </pre>
--   
--   If you think of an <tt><a>Auto'</a> a b</tt> as a "stateful function"
--   <tt>a -&gt; b</tt>, then <a>stepAuto'</a> lets you "run" it.
--   
--   In order to directly run an <a>Auto'</a> on a stream, an <tt>[a]</tt>,
--   use <tt>streamAuto'</tt>. That gives you an <tt>[a] -&gt; [b]</tt>.
stepAuto' :: Auto' a b -> a -> (b, Auto' a b)

-- | Like <a>stepAuto</a>, but drops the "next <a>Auto</a>" and just gives
--   the result.
evalAuto :: Monad m => Auto m a b -> a -> m b

-- | Like <a>stepAuto'</a>, but drops the "next <a>Auto'</a>" and just
--   gives the result. <a>evalAuto</a> for <a>Auto'</a>.
evalAuto' :: Auto' a b -> a -> b

-- | Stream an <a>Auto</a> over a list, returning the list of results. Does
--   this "lazily" (over the Monad), so with most Monads, this should work
--   fine with infinite lists. (That is, <tt><a>streamAuto</a>
--   (<tt>arrM</tt> f)</tt> behaves exactly like <tt><a>mapM</a> f</tt>,
--   and you can reason with <a>Auto</a>s as if you'd reason with
--   <tt>mapM</tt> on an infinite list)
--   
--   Note that, conceptually, this turns an <tt><a>Auto</a> m a b</tt> into
--   an <tt>[a] -&gt; m [b]</tt>.
--   
--   See <a>streamAuto'</a> for a simpler example; here is one taking
--   advantage of monadic effects:
--   
--   <pre>
--   &gt;&gt;&gt; let a = arrM print *&gt; sumFrom 0 :: Auto IO Int Int
--   
--   &gt;&gt;&gt; ys &lt;- streamAuto a [1..5]
--   1                -- IO effects
--   2
--   3
--   4
--   5
--   
--   &gt;&gt;&gt; ys
--   [1,3,6,10,15]    -- the result
--   </pre>
--   
--   <tt>a</tt> here is like <tt><tt>sumFrom</tt> 0</tt>, except at every
--   step, prints the input item to stdout as a side-effect.
--   
--   Note that we use "stream" here slightly differently than in libraries
--   like <i>pipes</i> or <i>conduit</i>. We don't stream over the
--   <tt>m</tt> Monad (like <tt>IO</tt>)...we stream over the <b>input
--   elements</b>. Using <a>streamAuto</a> on an infinite list allows you
--   to "stop", for example, to find the result...but it will still
--   sequence all the *effects*.
--   
--   For example:
--   
--   <pre>
--   &gt;&gt;&gt; take 10 &lt;$&gt; streamAuto (arrM print *&gt; id) [1..]
--   </pre>
--   
--   Will execute <a>print</a> on every element before "returning" with
--   [1..10].
--   
--   <pre>
--   &gt;&gt;&gt; flip runState 0 $ take 10 &lt;$&gt; streamAuto (arrM (modify . (+)) *&gt; id) [1..]
--   ([1,2,3,4,5,6,7,8,9,10], .... (never terminates)
--   </pre>
--   
--   This will immediately return the "result", and you can bind to the
--   result with `(&gt;&gt;=)`, but it'll never return a "final state",
--   because the final state involves executing all of the <a>modify</a>s.
--   
--   In other words, we stream <i>values</i>, not <i>effects</i>. You would
--   analyze this behavior the same way you would look at something like
--   <a>mapM</a>.
--   
--   If you want to stream effects, you can use <a>streamAutoEffects</a> or
--   <a>toEffectStream</a>, and use an effects streaming library like
--   <i>pipes</i> (or anything with <i>ListT</i>)...this will give the
--   proper streaming of effects with resource handling, handling infinite
--   streams in finite space with finite effects, etc.
streamAuto :: Monad m => Auto m a b -> [a] -> m [b]

-- | Stream an <a>Auto'</a> over a list, returning the list of results.
--   Does this lazily, so this should work fine with (and is actually
--   somewhat designed for) infinite lists.
--   
--   Note that conceptually this turns an <tt><a>Auto'</a> a b</tt> into an
--   <tt>[a] -&gt; [b]</tt>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (arr (+3)) [1..10]
--   [4,5,6,7,8,9,10,11,12,13]
--   
--   &gt;&gt;&gt; streamAuto' (sumFrom 0) [1..5]
--   [1,3,6,10,15]
--   
--   &gt;&gt;&gt; streamAuto' (productFrom 1) . streamAuto' (sumFrom 0) $ [1..5]
--   [1,3,18,180,2700]
--   
--   &gt;&gt;&gt; streamAuto' (productFrom 1 . sumFrom 0) $ [1..5]
--   [1,3,18,180,2700]
--   
--   &gt;&gt;&gt; streamAuto' id [1..5]
--   [1,2,3,4,5]
--   </pre>
streamAuto' :: Auto' a b -> [a] -> [b]

-- | Streams (in the context of the underlying monad) the given <a>Auto</a>
--   with a stream of constant values as input, a given number of times.
--   After the given number of inputs, returns the list of results and the
--   next/updated <a>Auto</a>, in the context of the underlying monad.
--   
--   <pre>
--   stepAutoN n a0 x = overList a0 (replicate n x)
--   </pre>
--   
--   See <a>stepAutoN'</a> for a simpler example; here is one taking
--   advantage of monadic effects:
--   
--   <pre>
--   &gt;&gt;&gt; let a = arrM print *&gt; sumFrom 0 :: Auto IO Int Int
--   
--   &gt;&gt;&gt; (ys, a') &lt;- stepAutoN 5 a 3
--   3                -- IO effects
--   3
--   3
--   3
--   3
--   
--   &gt;&gt;&gt; ys
--   [3,6,9,12,15]    -- the result
--   
--   &gt;&gt;&gt; (ys'', _) &lt;- stepAutoN 5 a' 5
--   5                -- IO effects
--   5
--   5
--   5
--   5
--   
--   &gt;&gt;&gt; ys''
--   [20,25,30,35,50] -- the result
--   </pre>
--   
--   <tt>a</tt> here is like <tt><tt>sumFrom</tt> 0</tt>, except at every
--   step, prints the input item to stdout as a side-effect.
stepAutoN :: Monad m => Int -> Auto m a b -> a -> m ([b], Auto m a b)

-- | Streams the given <a>Auto'</a> with a stream of constant values as
--   input, a given number of times. After the given number of inputs,
--   returns the list of results and the next/updated <a>Auto</a>.
--   
--   <pre>
--   stepAutoN' n a0 x = overList' a0 (replicate n x)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let (ys, a') = stepAutoN' 5 (sumFrom 0) 3
--   
--   &gt;&gt;&gt; ys
--   [3,6,9,12,15]
--   
--   &gt;&gt;&gt; let (ys', _) = stepAutoN' 5 a' 5
--   
--   &gt;&gt;&gt; ys'
--   [20,25,30,35,40]
--   </pre>
stepAutoN' :: Int -> Auto' a b -> a -> ([b], Auto' a b)

-- | Encode an <a>Auto</a> and its internal state into a <a>ByteString</a>.
encodeAuto :: Auto m a b -> ByteString

-- | <a>Resume</a> an <a>Auto</a> from its <a>ByteString</a> serialization,
--   giving a <a>Left</a> if the deserialization is not possible.
decodeAuto :: Auto m a b -> ByteString -> Either String (Auto m a b)

-- | Give a <a>FilePath</a> and an <a>Auto</a>, and <a>readAuto</a> will
--   attempt to resume the saved state of the <a>Auto</a> from disk,
--   reading from the given <a>FilePath</a>. Will return <a>Left</a> upon a
--   decoding error, with the error, and <a>Right</a> if the decoding is
--   succesful.
readAuto :: FilePath -> Auto m a b -> IO (Either String (Auto m a b))

-- | Given a <a>FilePath</a> and an <a>Auto</a>, serialize and freeze the
--   state of the <a>Auto</a> as binary to that <a>FilePath</a>.
writeAuto :: FilePath -> Auto m a b -> IO ()

-- | Takes an <a>Auto</a> that is serializable/resumable and returns an
--   <a>Auto</a> that is not. That is, when it is "saved", saves no data,
--   and when it is "resumed", resets itself back to the initial
--   configuration every time; in other words, <tt><a>decodeAuto</a>
--   (unserialize a) bs = Right (unserialize a)</tt>. Trying to "resume" it
--   will just always give itself, unchanged.
unserialize :: Monad m => Auto m a b -> Auto m a b

-- | A special <a>Auto</a> that acts like the <a>id</a> <a>Auto</a>, but
--   forces results as they come through to be fully evaluated, when
--   composed with other <a>Auto</a>s.
--   
--   TODO: Test if this really works
forcer :: NFData a => Auto m a a

-- | A special <a>Auto</a> that acts like the <a>id</a> <a>Auto</a>, but
--   forces results as they come through to be evaluated to Weak Head
--   Normal Form, with <a>seq</a>, when composed with other <a>Auto</a>s.
--   
--   TODO: Test if this really works
seqer :: Auto m a a

-- | Swaps out the underlying <a>Monad</a> of an <a>Auto</a> using the
--   given monad morphism "transforming function", a natural
--   transformation.
--   
--   Basically, given a function to "swap out" any <tt>m a</tt> with an
--   <tt>m' a</tt>, it swaps out the underlying monad of the <a>Auto</a>.
--   
--   This forms a functor, so you rest assured in things like this:
--   
--   <pre>
--   hoistA id == id
--   hoistA f a1 . hoistA f a2 == hoistA f (a1 . a2)
--   </pre>
hoistA :: (Monad m, Monad m') => (forall c. m c -> m' c) -> Auto m a b -> Auto m' a b

-- | Generalizes an <tt><a>Auto'</a> a b</tt> to an <tt><a>Auto</a> m a
--   b'</tt> for any <a>Monad</a> <tt>m</tt>, using <tt>hoist</tt>.
--   
--   You generally should be able to avoid using this if you never directly
--   write any <a>Auto'</a>s and always write 'Auto m' parameterized over
--   all <a>Monad</a>s, but...in case you import one from a library or
--   something, you can use this.
generalizeA :: Monad m => Auto' a b -> Auto m a b

-- | Applies the given "monadic function" (function returning a monadic
--   action) to every incoming item; the result is the result of executing
--   the action returned.
--   
--   Note that this essentially lifts a "Kleisli arrow"; it's like
--   <tt>arr</tt>, but for "monadic functions" instead of normal functions:
--   
--   <pre>
--   arr  :: (a -&gt; b)   -&gt; Auto m a b
--   arrM :: (a -&gt; m b) -&gt; Auto m a b
--   </pre>
--   
--   <pre>
--   arrM f . arrM g == arrM (f &lt;=&lt; g)
--   </pre>
--   
--   One neat trick you can do is that you can "tag on effects" to a normal
--   <a>Auto</a> by using <a>*&gt;</a> from <a>Control.Applicative</a>. For
--   example:
--   
--   <pre>
--   &gt;&gt;&gt; let a = arrM print *&gt; sumFrom 0
--   
--   &gt;&gt;&gt; ys &lt;- streamAuto a [1..5]
--   1                -- IO output
--   2
--   3
--   4
--   5
--   
--   &gt;&gt;&gt; ys
--   [1,3,6,10,15]    -- the result
--   </pre>
--   
--   Here, <tt>a</tt> behaves "just like" <tt><tt>sumFrom</tt>
--   0</tt>...except, when you step it, it prints out to stdout as a
--   side-effect. We just gave automatic stdout logging behavior!
arrM :: (a -> m b) -> Auto m a b

-- | Like <a>arr</a>, but applies the function to the <i>previous value</i>
--   of the input, instead of the current value. Used for the same purposes
--   as <a>lastVal</a>: to manage recursive bindings.
--   
--   Warning: Don't use this to do imperative programming!
--   
--   <pre>
--   arrD id == lastVal
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (arrD negate 100) [1..10]
--   [100,-1,-2,-3,-4,-5,-6,-7,-8,-9]
--   </pre>
arrD :: Serialize b => (a -> b) -> b -> Auto m a b

-- | Construct an <a>Auto</a> from a "folding" function: <tt>b -&gt; a
--   -&gt; b</tt> yields an <tt><a>Auto</a> m a b</tt>. Basically acts like
--   a <a>foldl</a> or a <a>scanl</a>. There is an internal accumulator
--   that is "updated" with an <tt>a</tt> at every step. Must be given an
--   initial accumulator.
--   
--   Example: an <a>Auto</a> that sums up all of its input.
--   
--   <pre>
--   &gt;&gt;&gt; let summer = accum (+) 0
--   
--   &gt;&gt;&gt; let (sum1, summer')  = stepAuto' summer 3
--   
--   &gt;&gt;&gt; sum1
--   3
--   
--   &gt;&gt;&gt; let (sum2, summer'') = stepAuto' summer' 10
--   
--   &gt;&gt;&gt; sum2
--   13
--   
--   &gt;&gt;&gt; streamAuto'  summer'' [1..10]
--   [14,16,19,23,28,34,41,49,58,68]
--   </pre>
--   
--   If your accumulator <tt>b</tt> does not have a <a>Serialize</a>
--   instance, then you should either write a meaningful one, or throw away
--   serializability and use <a>accum_</a>.
accum :: Serialize b => (b -> a -> b) -> b -> Auto m a b

-- | A version of <a>accum</a>, where the internal accumulator isn't
--   serialized. It can be "saved" and "loaded", but the state is lost in
--   the process.
--   
--   See <a>accum</a> for more details.
--   
--   Useful if your accumulator <tt>b</tt> cannot have a meaningful
--   <a>Serialize</a> instance.
accum_ :: (b -> a -> b) -> b -> Auto m a b

-- | Construct an <a>Auto</a> from a "monadic" "folding" function: <tt>b
--   -&gt; a -&gt; m b</tt> yields an <tt><a>Auto</a> m a b</tt>. Basically
--   acts like a <a>foldM</a> or <tt>scanM</tt> (if it existed). here is an
--   internal accumulator that is "updated" with an input <tt>a</tt> with
--   the result of the executed <tt>m b</tt> at every step. Must be given
--   an initial accumulator.
--   
--   See <a>accum</a> for more details.
--   
--   If your accumulator <tt>b</tt> does not have a <a>Serialize</a>
--   instance, then you should either write a meaningful one, or throw away
--   serializability and use <a>accumM_</a>.
accumM :: (Serialize b, Monad m) => (b -> a -> m b) -> b -> Auto m a b

-- | A version of 'accumM_, where the internal accumulator isn't
--   serialized. It can be "saved" and "loaded", but the state is lost in
--   the process.
--   
--   See <a>accumM</a> for more details.
--   
--   Useful if your accumulator <tt>b</tt> cannot have a meaningful
--   <a>Serialize</a> instance.
accumM_ :: Monad m => (b -> a -> m b) -> b -> Auto m a b

-- | A "delayed" version of <a>accum</a>, where the first output is the
--   initial state of the accumulator, before applying the folding
--   function. Useful in recursive bindings.
--   
--   <pre>
--   &gt;&gt;&gt; let summerD = accumD (+) 0
--   
--   &gt;&gt;&gt; let (sum1, summerD')  = stepAuto' summerD 3
--   
--   &gt;&gt;&gt; sum1
--   0
--   
--   &gt;&gt;&gt; let (sum2, summerD'') = stepAuto' summerD' 10
--   
--   &gt;&gt;&gt; sum2
--   3
--   
--   &gt;&gt;&gt; streamAuto'  summerD'' [1..10]
--   [13,14,16,19,23,28,34,41,49,58]
--   </pre>
--   
--   (Compare with the example in <a>accum</a>)
--   
--   Note that this is more or less an encoding of <a>scanl</a>, that can
--   be "decoded" with <tt>streamAuto'</tt>:
--   
--   <pre>
--   &gt;&gt;&gt; let myScanl f z = streamAuto' (accumD f z)
--   
--   &gt;&gt;&gt; scanl (+) 0 [1..10]
--   [0,3,6,10,15,21,28,36,45,55]
--   
--   &gt;&gt;&gt; myScanl (+) 0 [1..10]
--   [0,3,6,10,15,21,28,36,45]
--   </pre>
--   
--   The only difference is that you don't get the last element. (You could
--   force it out, if you wanted, by feeding any nonsense value in --- even
--   <a>undefined</a>! --- and getting the result)
accumD :: Serialize b => (b -> a -> b) -> b -> Auto m a b

-- | The non-resuming/non-serializing version of <a>accumD</a>.
accumD_ :: (b -> a -> b) -> b -> Auto m a b

-- | A "delayed" version of <a>accumM</a>, where the first output is the
--   initial state of the accumulator, before applying the folding
--   function. Useful in recursive bindings.
accumMD :: (Serialize b, Monad m) => (b -> a -> m b) -> b -> Auto m a b

-- | The non-resuming/non-serializing version of <a>accumMD</a>.
accumMD_ :: Monad m => (b -> a -> m b) -> b -> Auto m a b

-- | Construct an <a>Auto</a> from a state transformer: an <tt>a -&gt; s
--   -&gt; (b, s)</tt> gives you an <tt><a>Auto</a> m a b</tt>, for any
--   <a>Monad</a> <tt>m</tt>. At every step, it takes in the <tt>a</tt>
--   input, runs the function with the stored internal state, returns the
--   <tt>b</tt> result, and now contains the new resulting state. You have
--   to intialize it with an initial state, of course.
--   
--   From the "stream transformer" point of view, this is rougly equivalent
--   to <a>mapAccumL</a> from <a>Data.List</a>, with the function's
--   arguments and results in the backwards order.
--   
--   <pre>
--   streamAuto' (mkState f s0) = snd . mapAccumL (\s x -&gt; swap (f x s))
--   </pre>
--   
--   Try not to use this if it's ever avoidable, unless you're a framework
--   developer or something. Try make something by combining/composing the
--   various <a>Auto</a> combinators.
--   
--   If your state <tt>s</tt> does not have a <a>Serialize</a> instance,
--   then you should either write a meaningful one, provide the
--   serialization methods manually with <a>mkState'</a>, or throw away
--   serializability and use <a>mkState_</a>.
mkState :: Serialize s => (a -> s -> (b, s)) -> s -> Auto m a b

-- | Construct an <a>Auto</a> from a "monadic" state transformer: <tt>a
--   -&gt; s -&gt; m (b, s)</tt> gives you an <tt><a>Auto</a> m a b</tt>.
--   At every step, it takes in the <tt>a</tt> input, runs the function
--   with the stored internal state and "executes" the <tt>m (b, s)</tt> to
--   get the <tt>b</tt> output, and stores the <tt>s</tt> as the new,
--   updated state. Must be initialized with an initial state.
--   
--   Try not to use this if it's ever avoidable, unless you're a framework
--   developer or something. Try make something by combining/composing the
--   various <a>Auto</a> combinators.
--   
--   This version is a wrapper around <a>mkAuto</a>, that keeps track of
--   the serialization and re-loading of the internal state for you, so you
--   don't have to deal with it explicitly.
--   
--   If your state <tt>s</tt> does not have a <a>Serialize</a> instance,
--   then you should either write a meaningful one, provide the
--   serialization methods manually with <a>mkStateM'</a>, or throw away
--   serializability and use <a>mkStateM_</a>.
mkStateM :: Serialize s => (a -> s -> m (b, s)) -> s -> Auto m a b

-- | A version of <a>mkState</a>, where the internal state isn't
--   serialized. It can be "saved" and "loaded", but the state is lost in
--   the process.
--   
--   See <a>mkState</a> for more details.
--   
--   Useful if your state <tt>s</tt> cannot have a meaningful
--   <a>Serialize</a> instance.
mkState_ :: (a -> s -> (b, s)) -> s -> Auto m a b

-- | A version of <a>mkStateM</a>, where the internal state isn't
--   serialized. It can be "saved" and "loaded", but the state is lost in
--   the process.
--   
--   See <a>mkStateM</a> for more details.
--   
--   Useful if your state <tt>s</tt> cannot have a meaningful
--   <a>Serialize</a> instance.
mkStateM_ :: (a -> s -> m (b, s)) -> s -> Auto m a b

-- | To get every output, executes the monadic action and returns the
--   result as the output. Always ignores input.
--   
--   This is basically like an "effectful" <a>pure</a>:
--   
--   <pre>
--   <a>pure</a>   :: b   -&gt; <a>Auto</a> m a b
--   <a>effect</a> :: m b -&gt; <a>Auto</a> m a b
--   </pre>
--   
--   The output of <a>pure</a> is always the same, and the output of
--   <a>effect</a> is always the result of the same monadic action. Both
--   ignore their inputs.
--   
--   Fun times when the underling <a>Monad</a> is, for instance,
--   <tt>Reader</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; let a = effect ask    :: Auto (Reader b) a b
--   
--   &gt;&gt;&gt; let r = evalAuto a () :: Reader b b
--   
--   &gt;&gt;&gt; runReader r "hello"
--   "hello"
--   
--   &gt;&gt;&gt; runReader r 100
--   100
--   </pre>
--   
--   If your underling monad has effects (<a>IO</a>, <tt>State</tt>,
--   <a>Maybe</a>, <tt>Writer</tt>, etc.), then it might be fun to take
--   advantage of <a>*&gt;</a> from <a>Control.Applicative</a> to "tack on"
--   an effect to a normal <a>Auto</a>:
--   
--   <pre>
--   &gt;&gt;&gt; let a = effect (modify (+1)) *&gt; sumFrom 0 :: Auto (State Int) Int Int
--   
--   &gt;&gt;&gt; let st = streamAuto a [1..10]
--   
--   &gt;&gt;&gt; let (ys, s') = runState st 0
--   
--   &gt;&gt;&gt; ys
--   [1,3,6,10,15,21,28,36,45,55]
--   
--   &gt;&gt;&gt; s'
--   10
--   </pre>
--   
--   Our <a>Auto</a> <tt>a</tt> behaves exactly like <tt><tt>sumFrom</tt>
--   0</tt>, except at each step, it also increments the underlying/global
--   state by one. It is <tt><tt>sumFrom</tt> 0</tt> with an "attached
--   effect".
effect :: m b -> Auto m a b

-- | Analogous to <a>iterate</a> from <a>Prelude</a>. Keeps accumulator
--   value and continually applies the function to the accumulator at every
--   step, outputting the result.
--   
--   The first result is the initial accumulator value.
--   
--   <pre>
--   &gt;&gt;&gt; take 10 . streamAuto' (iterator (*2) 1) $ repeat ()
--   [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
--   </pre>
iterator :: Serialize b => (b -> b) -> b -> Auto m a b

-- | The non-resuming/non-serializing version of <a>iterator</a>.
iterator_ :: (b -> b) -> b -> Auto m a b

-- | Like <a>iterator</a>, but with a monadic function.
iteratorM :: (Serialize b, Monad m) => (b -> m b) -> b -> Auto m a b

-- | The non-resuming/non-serializing version of <a>iteratorM</a>.
iteratorM_ :: Monad m => (b -> m b) -> b -> Auto m a b

-- | The stream of outputs is the cumulative/running sum of the inputs so
--   far, starting with an initial count.
--   
--   The first output takes into account the first input. See
--   <a>sumFromD</a> for a version where the first output is the initial
--   count itself.
--   
--   <pre>
--   sumFrom x0 = accum (+) x0
--   </pre>
sumFrom :: (Serialize a, Num a) => a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>sumFrom</a>.
sumFrom_ :: Num a => a -> Auto m a a

-- | Like <a>sumFrom</a>, except the first output is the starting count.
--   
--   <pre>
--   &gt;&gt;&gt; let a = sumFromD 5
--   
--   &gt;&gt;&gt; let (y1, a') = stepAuto' a 10
--   
--   &gt;&gt;&gt; y1
--   5
--   
--   &gt;&gt;&gt; let (y2, _ ) = stepAuto' a' 3
--   
--   &gt;&gt;&gt; y2
--   10
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (sumFrom 0) [1..10]
--   [1,3,6,10,15,21,28,36,45,55]
--   
--   &gt;&gt;&gt; streamAuto' (sumFromD 0) [1..10]
--   [0,1,3,6,10,15,21,28,36,45]
--   </pre>
--   
--   It's <a>sumFrom</a>, but "delayed".
--   
--   Useful for recursive bindings, where you need at least one value to be
--   able to produce its "first output" without depending on anything else.
--   
--   <pre>
--   sumFromD x0 = sumFrom x0 . delay 0
--   </pre>
--   
--   <pre>
--   sumFromD x0 = delay x0 . sumFrom x0
--   </pre>
sumFromD :: (Serialize a, Num a) => a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>sumFromD</a>.
sumFromD_ :: Num a => a -> Auto m a a

-- | The output is the running/cumulative product of all of the inputs so
--   far, starting from an initial product.
--   
--   <pre>
--   productFrom x0 = accum (*) x0
--   </pre>
productFrom :: (Serialize a, Num a) => a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>productFrom</a>.
productFrom_ :: Num a => a -> Auto m a a

-- | The output is the running/cumulative <a>mconcat</a> of all of the
--   input seen so far, starting with <a>mempty</a>.
--   
--   <pre>
--   &gt;&gt;&gt; streamauto' mappender . map Last $ [Just 4, Nothing, Just 2, Just 3]
--   [Last (Just 4), Last (Just 4), Last (Just 2), Last (Just 3)]
--   
--   &gt;&gt;&gt; streamAuto' mappender ["hello","world","good","bye"]
--   ["hello","helloworld","helloworldgood","helloworldgoodbye"]
--   </pre>
--   
--   <pre>
--   mappender = accum mappend mempty
--   </pre>
mappender :: (Serialize a, Monoid a) => Auto m a a

-- | The non-resuming/non-serializing version of <a>mappender</a>.
mappender_ :: Monoid a => Auto m a a

-- | The output is the running <a>&lt;&gt;</a>-sum (<a>mappend</a> for
--   <a>Semigroup</a>) of all of the input values so far, starting with a
--   given starting value. Basically like <a>mappender</a>, but with a
--   starting value.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (mappendFrom (Max 0)) [Max 4, Max (-2), Max 3, Max 10]
--   [Max 4, Max 4, Max 4, Max 10]
--   </pre>
--   
--   <pre>
--   mappendFrom m0 = accum (&lt;&gt;) m0
--   </pre>
mappendFrom :: (Serialize a, Semigroup a) => a -> Auto m a a

-- | An <a>Auto</a> that returns the last value received by it. Given an
--   "initial value" to output first.
--   
--   From the signal processing world, this is known as the "lag operator"
--   <i>L</i>.
--   
--   This is (potentially) a <b>very dangerous</b> <a>Auto</a>, because its
--   usage and its very existence opens the door to breaking
--   denotative/declarative style and devolving into imperative style
--   coding. However, when used where it is supposed to be used, it is more
--   or less invaluable, and will be an essential part of many programs.
--   
--   Its main usage is for dealing with recursive bindings. If you ever are
--   laying out recursive bindings in a high-level/denotative way, you need
--   to have at least one value be able to have a "initial output" without
--   depending on anything else. <a>lastVal</a> and <a>delay</a> allow you
--   to do this.
--   
--   See the <a>recursive</a> example for more information on the
--   appropriate usage of <a>lastVal</a> and <a>delay</a>.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (lastVal 100) [1..10]
--   [100,1,2,3,4,5,6,7,8,9]
--   </pre>
lastVal :: Serialize a => a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>lastVal</a>.
lastVal_ :: a -> Auto m a a

-- | An alias for <a>lastVal</a>; used in contexts where "delay" is more a
--   meaningful description than "last value". All of the warnings for
--   <a>lastVal</a> still apply, so you should probably read it if you
--   haven't :)
delay :: Serialize a => a -> Auto m a a

-- | The non-resuming/non-serializing version of <a>delay</a>.
delay_ :: a -> Auto m a a

-- | A simple <a>Auto</a> that ignores all input; its output stream counts
--   upwards from zero.
--   
--   <pre>
--   &gt;&gt;&gt; take 10 . streamAuto' count $ repeat ()
--   [0,1,2,3,4,5,6,7,8,9]
--   </pre>
count :: (Serialize b, Num b) => Auto m a b

-- | "This, then that". Behave like the first <a>Interval</a> (and run its
--   effects) as long as it is "on" (outputting <a>Just</a>). As soon as it
--   turns off (is <a>Nothing</a>), it'll "switch over" and begin behaving
--   like the second <a>Auto</a> forever, running the effects of the second
--   <a>Auto</a>, too. Works well if the <a>Auto</a>s follow interval
--   semantics from <a>Control.Auto.Interval</a>.
--   
--   <pre>
--   &gt;&gt;&gt; let a1 = whenI (&lt;= 4) --&gt; pure 0
--   
--   &gt;&gt;&gt; streamAuto' a1 [1..10]
--   [1, 2, 3, 4, 0, 0, 0, 0, 0, 0]
--   </pre>
--   
--   (<a>whenI</a> only lets items satisfying the predicate pass through as
--   "on", and is "off" otherwise; <a>pure</a> is the <a>Auto</a> that
--   always produces the same output)
--   
--   Association works in a way that you can "chain" <a>--&gt;</a>s, as
--   long as you have an appropriate <a>Auto</a> (and not <a>Interval</a>)
--   at the end:
--   
--   <pre>
--   &gt;&gt;&gt; let a2 = onFor 3 . sumFrom 0
--            --&gt; onFor 3 . sumFrom 100
--            --&gt; pure 0
--   
--   &gt;&gt;&gt; streamAuto' a2 [1..10]
--   [1,3,6,104,109,115,0,0,0,0]
--   </pre>
--   
--   <tt>a --&gt; b --&gt; c</tt> associates as <tt>a --&gt; (b --&gt;
--   c)</tt>
--   
--   This is pretty invaluable for having <a>Auto</a>s "step" through a
--   series of different <a>Auto</a>s, progressing their state from one
--   stage to the next. <a>Auto</a>s can control when they want to be
--   "moved on" from by turning "off" (outputting <a>Nothing</a>).
--   
--   Note that recursive bindings work just fine, so:
--   
--   <pre>
--   &gt;&gt;&gt; let a3 = onFor 2 . pure "hello"
--            --&gt; onFor 2 . pure "world"
--            --&gt; a3
--   
--   &gt;&gt;&gt; let (res3, _) = stepAutoN' 8 a3 ()
--   
--   &gt;&gt;&gt; res3
--   ["hello", "hello", "world", "world", "hello", "hello", "world", "world"]
--   </pre>
--   
--   the above represents an infinite loop between outputting "hello" and
--   outputting "world".
--   
--   For serialization, an extra byte cost is incurred per invocation of
--   <a>--&gt;</a>. For cyclic switches like <tt>a3</tt>, every time the
--   cycle "completes", it adds another layer of <a>--&gt;</a> byte costs.
--   For example, initially, saving <tt>a3</tt> incurs a cost for the two
--   <a>--&gt;</a>s. After <tt>a3</tt> loops once, it incurs a cost for
--   another two <a>--&gt;</a>s, so it costs four <a>--&gt;</a>s. After
--   <tt>a3</tt> loops another time, it is like a cost of six
--   <a>--&gt;</a>s. So be aware that for cyclic bindings like <tt>a3</tt>,
--   space for serialization grows at O(n).
--   
--   By the way, it might be worth contrasting this with <a>&lt;|!&gt;</a>
--   and <a>&lt;|?&gt;</a> from <a>Control.Auto.Interval</a>, which have
--   the same type signatures. Those alternative-y operators always <i>feed
--   the input to both sides</i>, <i>run both sides</i>, and output the
--   first <a>Just</a>. With <a>&lt;|!&gt;</a>, you can "switch back and
--   forth" to the first <a>Auto</a> as soon as the first <a>Auto</a> is
--   "on" (<a>Just</a>) again.
--   
--   <a>--&gt;</a>, in contrast, runs <i>only</i> the first <a>Auto</a>
--   until it is off (<a>Nothing</a>)...then runs <i>only</i> the second
--   <a>Auto</a>. This transition is one-way, as well.
(-->) :: Monad m => Interval m a b -> Auto m a b -> Auto m a b
infixr 1 -->

-- | A variation of <a>--&gt;</a>, where the right hand side can also be an
--   <a>Interval</a> / <a>Maybe</a>. The entire result is, then, a
--   <a>Maybe</a>. Probably less useful than <a>--&gt;</a> in most
--   situations.
(-?>) :: Monad m => Interval m a b -> Interval m a b -> Interval m a b
infixr 1 -?>

-- | An <a>Auto</a> that runs every input through a <tt>a -&gt;
--   <a>Maybe</a> b</tt> test and produces a blip stream that emits the
--   value inside every <a>Just</a> result.
--   
--   Particularly useful with prisms from the <i>lens</i> package, where
--   things like <tt>emitJusts (preview _Right)</tt> will emit the
--   <tt>b</tt> whenever the input <tt>Either a b</tt> stream is a
--   <tt>Right</tt>.
--   
--   Warning! Carries all of the same dangers of <a>emitOn</a>. You can
--   easily break blip semantics with this if you aren't sure what you are
--   doing. Remember to only emit at discrete, separate occurences, and not
--   for interval-like (on and off for chunks at a time) things. For
--   interval semantics, we have <a>Control.Auto.Interval</a>.
--   
--   See the examples of <a>emitOn</a> for more concrete good/bad use
--   cases.
emitJusts :: (a -> Maybe b) -> Auto m a (Blip b)

-- | Produces a blip stream that emits the input value whenever the input
--   satisfies a given predicate.
--   
--   Warning! This <a>Auto</a> has the capability of "breaking" blip
--   semantics. Be sure you know what you are doing when using this. Blip
--   streams are semantically supposed to only emit at discrete, separate
--   occurrences. Do not use this for interval-like (on and off for chunks
--   at a time) things; each input should be dealt with as a separate
--   thing.
--   
--   For interval semantics, we have <tt>Interval</tt> from
--   <a>Control.Auto.Interval</a>.
--   
--   Good example:
--   
--   <pre>
--   -- is only emitting at discrete blips
--   emitOn even . iterator (+ 1) 0
--   </pre>
--   
--   Bad examples:
--   
--   <pre>
--   -- is emitting for "durations" or "intervals" of time.
--   emitOn (&lt; 10) . iterator (+ 1) 0
--   
--   emitOn (const True) . foo
--   </pre>
--   
--   These bad examples would be good use cases of <tt>Interval</tt>.
--   
--   Can be particularly useful with prisms from the <i>lens</i> package,
--   where things like <tt>emitOn (has _Right)</tt> and <tt>emitOn (hasn't
--   _Right)</tt> will emit the input <tt>Either a b</tt> whenever it is or
--   isn't a <a>Right</a>. See <a>emitJusts</a> for more common uses with
--   <i>lens</i>.
emitOn :: (a -> Bool) -> Auto m a (Blip a)

-- | <tt><a>fromBlips</a> d</tt> is an <a>Auto</a> that decomposes the
--   incoming blip stream by constantly outputting <tt>d</tt> except when
--   the stream emits, and outputs the emitted value when it does.
fromBlips :: a -> Auto m (Blip a) a

-- | <tt><a>fromBlipsWith</a> d f</tt> is an <a>Auto</a> that decomposes
--   the incoming blip stream by constantly outputting <tt>d</tt> except
--   when the stream emits, and outputs the result of applying <tt>f</tt>
--   to the emitted value when it does.
fromBlipsWith :: b -> (a -> b) -> Auto m (Blip a) b

-- | <tt><a>holdWith</a> y0</tt> is an <a>Auto</a> whose output is always
--   the /most recently emitted/ value from the input blip stream. Before
--   anything is emitted, <tt>y0</tt> is outputted as a placeholder.
--   
--   Contrast with <tt>hold</tt> from <a>Control.Auto.Interval</a>.
holdWith :: Serialize a => a -> Auto m (Blip a) a

-- | A non-serializing/non-resumable version of <a>holdWith</a>.
holdWith_ :: a -> Auto m (Blip a) a

-- | Takes an <tt><a>Auto</a> m a b</tt> (an <a>Auto</a> that turns
--   incoming <tt>a</tt>s into outputting <tt>b</tt>s) into an
--   <tt><a>Auto</a> m (<a>Blip</a> a) (<a>Blip</a> b)</tt>; the original
--   <a>Auto</a> is lifted to only be applied to emitted contents of a blip
--   stream.
--   
--   When the stream emits, the original <a>Auto</a> is "stepped" with the
--   emitted value; when it does not, it is paused and frozen until the
--   next emission.
--   
--   <pre>
--   &gt;&gt;&gt; let sums = perBlip (sumFrom 0)
--   
--   &gt;&gt;&gt; let blps = eachAt 2 [1,5,2]
--   
--   &gt;&gt;&gt; take 8 . streamAuto' blps $ repeat ()
--   [NoBlip, Blip 1, NoBlip, Blip 5, NoBlip, Blip 2, NoBlip, NoBlip]
--   
--   &gt;&gt;&gt; take 8 . streamAuto' (sums . blps) $ repeat ()
--   [NoBlip, Blip 1, NoBlip, Blip 6, NoBlip, Blip 8, NoBlip, NoBlip]
--   </pre>
perBlip :: Monad m => Auto m a b -> Auto m (Blip a) (Blip b)

-- | An <a>Auto</a> that ignores its input and produces a blip stream never
--   emits.
never :: Auto m a (Blip b)

-- | Produces a blip stream that emits with the first received input value,
--   and never again after that.
--   
--   Often used with <a>pure</a>:
--   
--   <pre>
--   immediately . pure "Emit me!"
--   </pre>
--   
--   Or, in proc notation:
--   
--   <pre>
--   blp &lt;- immediately -&lt; "Emit me!"
--   </pre>
--   
--   to get a blip stream that emits a given value (eg., "Emit me!") once
--   and stops emitting ever again.
--   
--   <pre>
--   &gt;&gt;&gt; streamAuto' (immediately . pure "Emit me!") [1..5]
--   [Blip "Emit Me!", NoBlip, NoBlip, NoBlip, NoBlip]
--   </pre>
immediately :: Auto m a (Blip a)

-- | For <tt><a>onFor</a> n</tt>, the first <tt>n</tt> items in the output
--   stream are always "on" (passing through with exactly the value of the
--   corresponding input); for the rest, the output stream is always "off",
--   suppressing all input values forevermore.
--   
--   If a number less than 0 is passed, 0 is used.
onFor :: Int -> Interval m a a

-- | <a>Lifts</a> an <tt><a>Auto</a> m a b</tt> (transforming <tt>a</tt>s
--   into <tt>b</tt>s) into an <tt><a>Auto</a> m (<a>Maybe</a> a)
--   (<a>Maybe</a> b)</tt> (or, <tt><a>Interval</a> m (<a>Maybe</a> a)
--   b</tt>, transforming <i>intervals</i> of <tt>a</tt>s into
--   <i>intervals</i> of <tt>b</tt>.
--   
--   It does this by running the <a>Auto</a> as normal when the input is
--   "on", and freezing it<i>being "off" when the input is </i>off/.
--   
--   <pre>
--   &gt;&gt;&gt; let a1 = during (sumFrom 0) . onFor 2 . pure 1
--   
--   &gt;&gt;&gt; take 5 . streamAuto' a1 $ repeat ()
--   [Just 1, Just 2, Nothing, Nothing, Nothing]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let a2 = during (sumFrom 0) . offFor 2 . pure 1
--   
--   &gt;&gt;&gt; take 5 . streamAuto' a2 $ repeat ()
--   [Nothing, Nothing, Just 1, Just 2, Just 3]
--   </pre>
--   
--   (Remember that <tt><a>pure</a> x</tt> is the <a>Auto</a> that ignores
--   its input and constantly just pumps out <tt>x</tt> at every step)
--   
--   Note the difference between putting the <tt>sumFrom</tt> "after" the
--   <a>offFor</a> in the chain with <a>during</a> (like the previous
--   example) and putting the <tt>sumFrom</tt> "before":
--   
--   <pre>
--   &gt;&gt;&gt; let a3 = offFor 2 . sumFrom 0 . pure 1
--   
--   &gt;&gt;&gt; take 5 . streamAuto' a3 $ repeat ()
--   [Nothing, Nothing, Just 3, Just 4, Just 5]
--   </pre>
--   
--   In the first case (with <tt>a2</tt>), the output of <tt><a>pure</a>
--   1</tt> was suppressed by <a>offFor</a>, and <tt><a>during</a>
--   (<tt>sumFrom</tt> 0)</tt> was only summing on the times that the 1's
--   were "allowed through"...so it only "starts counting" on the third
--   step.
--   
--   In the second case (with <tt>a3</tt>), the output of the
--   <tt><a>pure</a> 1</tt> is never suppressed, and went straight into the
--   <tt><tt>sumFrom</tt> 0</tt>. <tt>sumFrom</tt> is always summing, the
--   entire time. The final output of that <tt><tt>sumFrom</tt> 0</tt> is
--   suppressed at the end with <tt><a>offFor</a> 2</tt>.
during :: Monad m => Auto m a b -> Interval m (Maybe a) b

-- | The output stream is alwayas off, regardless of the input.
--   
--   Note that any monadic effects of the input <a>Auto</a> when composed
--   with <a>off</a> are still executed, even though their result value is
--   suppressed.
--   
--   <pre>
--   off == pure Nothing
--   </pre>
off :: Interval m a b

-- | The output stream is always on, with exactly the value of the
--   corresponding input.
--   
--   <pre>
--   toOn == arr Just
--   </pre>
toOn :: Interval m a a

-- | An "interval collapsing" <a>Auto</a>. A stream of on/off values comes
--   in; the output is the value of the input when the input is on, and the
--   "default value" when the input is off.
--   
--   Much like <a>fromMaybe</a> from <a>Data.Maybe</a>.
--   
--   <pre>
--   fromInterval d = arr (fromMaybe d)
--   </pre>
fromInterval :: a -> Auto m (Maybe a) a

-- | Run an <a>Auto'</a> "interactively". Every step grab a string from
--   stdin, and feed it to the <a>Interval'</a>. If the <a>Interval'</a> is
--   "off", ends the session; if it is "on", then prints the output value
--   to stdout and repeat all over again.
--   
--   If your <a>Auto</a> outputs something other than a <a>String</a>, you
--   can use <a>fmap</a> to transform the output into a <a>String</a>
--   en-route (like <tt><a>fmap</a> <a>show</a></tt>).
--   
--   If your <a>Auto</a> takes in something other than a <a>String</a>, you
--   can <a>lmap</a> a function to convert the input <a>String</a> to
--   whatever intput your <a>Auto</a> expects.
--   
--   You can use <a>duringRead</a> or <a>bindRead</a> if you have an
--   <a>Auto'</a> or <a>Interval'</a> that takes something <a>read</a>able,
--   to chug along until you find something non-readable; there's also
--   <a>interactRS</a> which handles most of that for you.
--   
--   Outputs the final <a>Interval'</a> when the interaction terminates.
interactAuto :: Interval' String String -> IO (Interval' String String)

-- | Like <tt>interact</tt>, but instead of taking <tt><a>Interval'</a>
--   <a>String</a> <a>String</a></tt>, takes any <tt><a>Interval'</a> a
--   b</tt> as long as <tt>a</tt> is <a>Read</a> and <tt>b</tt> is
--   <a>Show</a>.
--   
--   Will "stop" if either (1) the input is not <a>read</a>-able or (2) the
--   <a>Interval'</a> turns off.
--   
--   Outputs the final <a>Auto'</a> when the interaction terminates.
interactRS :: (Read a, Show b) => Interval' a b -> IO (Interval' String String)

-- | Turns an <tt>Auto m' a b</tt> with a list of inputs into a "ListT
--   compatible effectful stream", as described at
--   <a>http://www.haskellforall.com/2014/11/how-to-build-library-agnostic-streaming.html</a>
--   
--   Any library that offers a "<tt>ListT</tt>" type can use this
--   result...and usually turn it into an effectful stream.
--   
--   For example, the <i>pipes</i> library offers <tt>runListT</tt> so you
--   can run this, running the <a>Auto</a> over the input list, all with
--   the effect stream manipulation tools and resource handling of
--   <i>pipes</i>.
--   
--   This is useful because <i>auto</i>, the library, mainly provides tools
--   for working with transformers for <i>value</i> streams, and not effect
--   streams or streams of effects. Using this, you can potentially have
--   the best of both worlds.
streamAutoEffects :: (Monad m, MonadTrans t, MonadPlus (t m), Monad m') => (forall c. m' c -> m c) -> [a] -> Auto m' a b -> t m b

-- | Turns an <tt>Auto m' a b</tt> and an "input producer" <tt>m a</tt>
--   into a "ListT compatible effectful stream", as described at
--   <a>http://www.haskellforall.com/2014/11/how-to-build-library-agnostic-streaming.html</a>
--   
--   Any library that offers a "<tt>ListT</tt>" type can use this
--   result...and usually turn it into an effectful stream.
--   
--   For example, the <i>pipes</i> library offers <tt>runListT</tt> so you
--   can run this, constantly pulling out <tt>a</tt>s from the stream using
--   the <tt>m a</tt>, feeding it in, and moving forward, all with the
--   effect stream manipulation tools and resource handling of
--   <i>pipes</i>.
--   
--   This is useful because <i>auto</i>, the library, mainly provides tools
--   for working with transformers for <i>value</i> streams, and not effect
--   streams or streams of effects. Using this, you can potentially have
--   the best of both worlds.
toEffectStream :: (Monad m, MonadTrans t, MonadPlus (t m), Monad m') => (forall c. m' c -> m c) -> m a -> Auto m' a b -> t m b

-- | Any instance of <a>ArrowApply</a> can be made into an instance of
--   <a>ArrowChoice</a> by defining <a>left</a> = <a>leftApp</a>.
leftApp :: ArrowApply a => a b c -> a Either b d Either c d

-- | Postcomposition with a pure function (right-to-left variant).
(^<<) :: Arrow a => c -> d -> a b c -> a b d
infixr 1 ^<<

-- | Precomposition with a pure function (right-to-left variant).
(<<^) :: Arrow a => a c d -> b -> c -> a b d
infixr 1 <<^

-- | Postcomposition with a pure function.
(>>^) :: Arrow a => a b c -> c -> d -> a b d
infixr 1 >>^

-- | Precomposition with a pure function.
(^>>) :: Arrow a => b -> c -> a c d -> a b d
infixr 1 ^>>

-- | The identity arrow, which plays the role of <a>return</a> in arrow
--   notation.
returnA :: Arrow a => a b b

-- | The basic arrow class.
--   
--   Instances should satisfy the following laws:
--   
--   <ul>
--   <li><pre><a>arr</a> id = <a>id</a></pre></li>
--   <li><pre><a>arr</a> (f &gt;&gt;&gt; g) = <a>arr</a> f &gt;&gt;&gt;
--   <a>arr</a> g</pre></li>
--   <li><pre><a>first</a> (<a>arr</a> f) = <a>arr</a> (<a>first</a>
--   f)</pre></li>
--   <li><pre><a>first</a> (f &gt;&gt;&gt; g) = <a>first</a> f &gt;&gt;&gt;
--   <a>first</a> g</pre></li>
--   <li><pre><a>first</a> f &gt;&gt;&gt; <a>arr</a> <a>fst</a> =
--   <a>arr</a> <a>fst</a> &gt;&gt;&gt; f</pre></li>
--   <li><pre><a>first</a> f &gt;&gt;&gt; <a>arr</a> (<a>id</a> *** g) =
--   <a>arr</a> (<a>id</a> *** g) &gt;&gt;&gt; <a>first</a> f</pre></li>
--   <li><pre><a>first</a> (<a>first</a> f) &gt;&gt;&gt; <a>arr</a>
--   <tt>assoc</tt> = <a>arr</a> <tt>assoc</tt> &gt;&gt;&gt; <a>first</a>
--   f</pre></li>
--   </ul>
--   
--   where
--   
--   <pre>
--   assoc ((a,b),c) = (a,(b,c))
--   </pre>
--   
--   The other combinators have sensible default definitions, which may be
--   overridden for efficiency.
class Category a => Arrow (a :: * -> * -> *)

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

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

-- | A mirror image of <a>first</a>.
--   
--   The default definition may be overridden with a more efficient version
--   if desired.
second :: Arrow a => a b c -> a (d, b) (d, c)

-- | Split the input between the two argument arrows and combine their
--   output. Note that this is in general not a functor.
--   
--   The default definition may be overridden with a more efficient version
--   if desired.
(***) :: Arrow a => a b c -> a b' c' -> a (b, b') (c, c')

-- | Fanout: send the input to both argument arrows and combine their
--   output.
--   
--   The default definition may be overridden with a more efficient version
--   if desired.
(&&&) :: Arrow a => a b c -> a b c' -> a b (c, c')

-- | Kleisli arrows of a monad.
newtype Kleisli (m :: * -> *) a b
Kleisli :: a -> m b -> Kleisli a b
[runKleisli] :: Kleisli a b -> a -> m b
class Arrow a => ArrowZero (a :: * -> * -> *)
zeroArrow :: ArrowZero a => a b c

-- | A monoid on arrows.
class ArrowZero a => ArrowPlus (a :: * -> * -> *)

-- | An associative operation with identity <a>zeroArrow</a>.
(<+>) :: ArrowPlus a => a b c -> a b c -> a b c

-- | Choice, for arrows that support it. This class underlies the
--   <tt>if</tt> and <tt>case</tt> constructs in arrow notation.
--   
--   Instances should satisfy the following laws:
--   
--   <ul>
--   <li><pre><a>left</a> (<a>arr</a> f) = <a>arr</a> (<a>left</a>
--   f)</pre></li>
--   <li><pre><a>left</a> (f &gt;&gt;&gt; g) = <a>left</a> f &gt;&gt;&gt;
--   <a>left</a> g</pre></li>
--   <li><pre>f &gt;&gt;&gt; <a>arr</a> <a>Left</a> = <a>arr</a>
--   <a>Left</a> &gt;&gt;&gt; <a>left</a> f</pre></li>
--   <li><pre><a>left</a> f &gt;&gt;&gt; <a>arr</a> (<a>id</a> +++ g) =
--   <a>arr</a> (<a>id</a> +++ g) &gt;&gt;&gt; <a>left</a> f</pre></li>
--   <li><pre><a>left</a> (<a>left</a> f) &gt;&gt;&gt; <a>arr</a>
--   <tt>assocsum</tt> = <a>arr</a> <tt>assocsum</tt> &gt;&gt;&gt;
--   <a>left</a> f</pre></li>
--   </ul>
--   
--   where
--   
--   <pre>
--   assocsum (Left (Left x)) = Left x
--   assocsum (Left (Right y)) = Right (Left y)
--   assocsum (Right z) = Right (Right z)
--   </pre>
--   
--   The other combinators have sensible default definitions, which may be
--   overridden for efficiency.
class Arrow a => ArrowChoice (a :: * -> * -> *)

-- | Feed marked inputs through the argument arrow, passing the rest
--   through unchanged to the output.
left :: ArrowChoice a => a b c -> a Either b d Either c d

-- | A mirror image of <a>left</a>.
--   
--   The default definition may be overridden with a more efficient version
--   if desired.
right :: ArrowChoice a => a b c -> a Either d b Either d c

-- | Split the input between the two argument arrows, retagging and merging
--   their outputs. Note that this is in general not a functor.
--   
--   The default definition may be overridden with a more efficient version
--   if desired.
(+++) :: ArrowChoice a => a b c -> a b' c' -> a Either b b' Either c c'

-- | Fanin: Split the input between the two argument arrows and merge their
--   outputs.
--   
--   The default definition may be overridden with a more efficient version
--   if desired.
(|||) :: ArrowChoice a => a b d -> a c d -> a Either b c d

-- | Some arrows allow application of arrow inputs to other inputs.
--   Instances should satisfy the following laws:
--   
--   <ul>
--   <li><pre><a>first</a> (<a>arr</a> (\x -&gt; <a>arr</a> (\y -&gt;
--   (x,y)))) &gt;&gt;&gt; <a>app</a> = <a>id</a></pre></li>
--   <li><pre><a>first</a> (<a>arr</a> (g &gt;&gt;&gt;)) &gt;&gt;&gt;
--   <a>app</a> = <a>second</a> g &gt;&gt;&gt; <a>app</a></pre></li>
--   <li><pre><a>first</a> (<a>arr</a> (&gt;&gt;&gt; h)) &gt;&gt;&gt;
--   <a>app</a> = <a>app</a> &gt;&gt;&gt; h</pre></li>
--   </ul>
--   
--   Such arrows are equivalent to monads (see <a>ArrowMonad</a>).
class Arrow a => ArrowApply (a :: * -> * -> *)
app :: ArrowApply a => a (a b c, b) c

-- | The <a>ArrowApply</a> class is equivalent to <a>Monad</a>: any monad
--   gives rise to a <a>Kleisli</a> arrow, and any instance of
--   <a>ArrowApply</a> defines a monad.
newtype ArrowMonad (a :: * -> * -> *) b
ArrowMonad :: a () b -> ArrowMonad b

-- | The <a>loop</a> operator expresses computations in which an output
--   value is fed back as input, although the computation occurs only once.
--   It underlies the <tt>rec</tt> value recursion construct in arrow
--   notation. <a>loop</a> should satisfy the following laws:
--   
--   <ul>
--   <li><i><i>extension</i></i> <tt><a>loop</a> (<a>arr</a> f) =
--   <a>arr</a> (\ b -&gt; <a>fst</a> (<a>fix</a> (\ (c,d) -&gt; f
--   (b,d))))</tt></li>
--   <li><i><i>left tightening</i></i> <tt><a>loop</a> (<a>first</a> h
--   &gt;&gt;&gt; f) = h &gt;&gt;&gt; <a>loop</a> f</tt></li>
--   <li><i><i>right tightening</i></i> <tt><a>loop</a> (f &gt;&gt;&gt;
--   <a>first</a> h) = <a>loop</a> f &gt;&gt;&gt; h</tt></li>
--   <li><i><i>sliding</i></i> <tt><a>loop</a> (f &gt;&gt;&gt; <a>arr</a>
--   (<a>id</a> *** k)) = <a>loop</a> (<a>arr</a> (<a>id</a> *** k)
--   &gt;&gt;&gt; f)</tt></li>
--   <li><i><i>vanishing</i></i> <tt><a>loop</a> (<a>loop</a> f) =
--   <a>loop</a> (<a>arr</a> unassoc &gt;&gt;&gt; f &gt;&gt;&gt; <a>arr</a>
--   assoc)</tt></li>
--   <li><i><i>superposing</i></i> <tt><a>second</a> (<a>loop</a> f) =
--   <a>loop</a> (<a>arr</a> assoc &gt;&gt;&gt; <a>second</a> f
--   &gt;&gt;&gt; <a>arr</a> unassoc)</tt></li>
--   </ul>
--   
--   where
--   
--   <pre>
--   assoc ((a,b),c) = (a,(b,c))
--   unassoc (a,(b,c)) = ((a,b),c)
--   </pre>
class Arrow a => ArrowLoop (a :: * -> * -> *)

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

-- | Right-to-left composition
(<<<) :: Category cat => cat b c -> cat a b -> cat a c
infixr 1 <<<
