packages feed

auto-0.3.0.0: tutorial/tutorial.md

Auto
====

Welcome to the tutorial for getting started with Auto!

This is actually just a basic overview of the library and some basic programs,
enough to get started, hopefully; for more, check out the [All About
Auto][aaa] series on my blog where I break down real world projects and
[auto-examples][] for more real-world examples, Up-to-date documentation is,
at the moment, hosted [on github][docs]...and the latest version of this
tutorial itself can be found on [the development branch][tutorial], normally!

Auto
----

Before we start, let's remember our imports!

~~~haskell
import Control.Auto                 -- the main entry point
import Prelude hiding ((.), id)     -- we use generalized versions from
                                    -- Control.Category, so we have to hide
                                    -- these.
~~~

### Semantic Picture

Semantically, a `Auto` describes *a relationship* between an input and an
output that is preserved over multiple steps.

In a way, you can think about `Auto`s as *value stream transformers*.  A
stream of sequential input values come in one at a time, and a stream of
output values pop out one at a time as well.  You can think of `streamAuto'` as
taking an `Auto' a b` and "unwrapping" its internal `[a] -> [b]`.

(We say a "value stream" to contrast from an "effect stream", a stream from an
effectful process like IO)

An `Auto` is a relationship; the simplest relationship is probably a straight
up apply-a-function-to-each-input-to-get-each-output relationship.  For that,
check out the `Auto` `arr (*2)`, where the outputs are the doubles of the
inputs:

~~~haskell
-- streamAuto' :: Auto' a b -> [a] -> [b]
-- [ 1, 2, 3, 4, 5, 6, 7, 8, 9,10...        -- the inputs
ghci> take 10 $ streamAuto' (arr (*2)) [1..]
   [ 2, 4, 6, 8,10,12,14,16,18,20]          -- the outputs
~~~

`streamAuto' (arr f)` is just `map f`, as you can see!

In general, the input-output relationship is allowed to depend on the history
of the inputs, as well.  For example, we have the `Auto` `sumFrom 0` --- the
relationship is that the output is always the cumulative sum of the inputs
received so far:

~~~haskell
-- [ 1, 2, 3, 4, 5, 6, 7, 8, 9,10...        -- the inputs
ghci> take 10 $ streamAuto' (sumFrom 0) [1..]
   [ 1, 3, 6,10,15,21,28,36,45,55]          -- the outputs
~~~

A bit on types --- `sumFrom n` is `Num a => Auto m a a` ... or, if
specializing it helps, `Auto' Int Int`.  You can read this as "a relationship
between two `Int`s fixed over the stream", or "a one-by-one mapping of an
`Int` stream to another `Int` stream".  For `sumFrom n`, the relationship is
that the output is always the cumulative sum of the inputs.

Note that these relationships are always *causal*; the nth item of the output
can only depend on the first n items of the input.  We say that they are
"real-time" stream transformers in that every time you get an input, exactly
one output pops out.

That's what they are semantically, and an `Auto` denotes exactly such an
input-output relationship that is maintained over several steps.

### Operational picture

Operationally, an `Auto` does this by acting as a "stateful function" that we
can "run" with `stepAuto`.  A function with "internal state".

~~~haskell
-- stepAuto' :: Auto' a b -> a -> (b, Auto' a b)
ghci> let (x, nextAuto ) = stepAuto' (sumFrom 0) 5
ghci> x
5
ghci> let (y, nextAuto2) = stepAuto' nextAuto 3
ghci> y
8
ghci> evalAuto' nextAuto2 4
12
~~~

`stepAuto'` lets you take an `Auto' a b`, give it an `a` as an input, and
returns an `b` as the output, and a "next/updated `Auto'`", which is the
`Auto'` with an updated internal state.  Running the "next `Auto'`" given will
continue along with the new updated state.  (`evalAuto'` is like `stepAuto'`
but throws away the "next `Auto`")   In this case, the "internal state" is an
accumulator, the sum of all received elements so far.

In practice, this is usually going to be your "main loop", or "game loop":

1.  Collect input from the world (using IO, or whatever you need)
2.  Step the `Auto` you have with that input.
3.  Get the output from that `Auto`, and the next `Auto`
4.  Show or render your output to the world however you want.
5.  Repeat all again, but with the new `Auto` from step 3.

(If your program doesn't need any outside input, then you can just use
`stepAutoN` with `()`, or `streamAuto'` with an infinite list.)

There are some built-in "loops" like this in the *[Control.Auto.Run][]*
module, for running in `IO` by reading and showing inputs and ouputs
(`interactAuto`, `interactRS`) if you want to try these out!

What's in a type?
-----------------

Enough handwaving!  What do these types even mean?  What are the type
parameters?

An `Auto' a b` describes *a relationship* between a stream of inputs `a` and a
stream of outputs `b` that is maintained over several steps of inputs.

One way to look at it is that, with `streamAuto'` an `Auto' a b` gives you the
"unwrapped" `[a] -> [b]`.

From an operational perspective, you can think of an `Auto' a b` as a function
with internal state that, when fed an `a`, gives you a `b` and a "next/updated
`Auto`".  With `stepAuto'`, an `Auto' a b` gives you an `a -> (b, Auto' a b)`.
An `Auto' a b` is basically a `a -> b` with "internal state".

The more general type is actually `Auto m a b` --- an `Auto' a b` is actually
just a type alias for `Auto Identity a b`.

An `Auto m a b` describes *a relationship*, again, between a stream of inputs
`a` and a stream of outputs `b` maintained over several steps of inputs...and
maintains this relationship with within an underlying monadic context `m`.

If `streamAuto'` from an `Auto' a b` gives you an `[a] -> [b]`, then
`streamAuto` from an `Auto m a b` gives you the "unwrapped" `[a] -> m [b]`.

Operationally, if `Auto' a b` is a `a -> b` with internal state, then `Auto m
a b` is a `a -> m b` with internal state.  If you feed it an `a`, it'll return
a `b` and a "next/updated `Auto`" in a monadic context --- with `stepAuto`,
you get a `a -> m (b, Auto m a b)`.

This monadic context means that in the process of "stepping" or "running" the
`Auto`, you can perform effects and get input from an outside world.

For the most part, real-life `Auto`s will be written parameterized over
`Monad` or some `Monad`-based typeclass:

~~~haskell
myAuto :: Monad m => Auto m Int Bool
~~~

Working with `Monad m => Auto m a b` is practically identical to working with
`Auto' a b`, so there really isn't ever a real point to actually *write* an
`Auto'`.  However, specializing to `Auto'` lets us use simple "running"
functions like `streamAuto'` and `stepAuto'`.

While we're on the subject, there is another type alias for `Auto`s: an
`Interval m a b` is an `Auto m a (Maybe b)` (they're just type aliases).
Semantically, it represents an `Auto` that is "on" or "off" for durations of
steps.  Similarly, `Interval' a b` is an `Auto' a (Maybe b)`.  You get the
picture, I hope!  We'll learn more about `Interval` later.

Building up Autos
-----------------

So of course, having simple `Auto`s like this being your whole program isn't
very reasonable...do you think I have a `chatBot` or `chessEngine` `Auto` in
the library? :)

The "magic" of this library is that you have the ability to build up complex
and intricate relationships and behaviors (and programs) by composing small
"primitive" `Auto`s.  These combinators are exposed both through familiar
typeclasses we know and love, and also through functions in this library.

### Modifying and combining `Auto`s

For example, with the `Functor` instance, you can apply functions to the
"output" of an `Auto`:

~~~haskell
ghci> streamAuto' (sumFrom 0) [1..5]
[ 1 , 3 , 6 , 10 , 15 ]
ghci> streamAuto' (show <$> sumFrom 0) [1..5]
["1","3","6","10","15"]
~~~

`lmap` from `Profunctor` lets you apply functions "before" the input of the
`Auto`:

~~~haskell
-- mappender :: Monoid m => Auto' m m
ghci> streamAuto' mappender ["1","2","3"]
["1","12","123"]
ghci> streamAuto' (lmap show mappender) [1,2,3]
["1","12","123"]
~~~

(`mappender` is an `Auto` where the output is always the cumulative `mconcat`
of all of the inputs so far)

The `Applicative` instance gives you a "constant `Auto`", which ignores its
input and whose output is always a constant value:

~~~haskell
ghci> take 10 $ streamAuto' (pure 4) [1..]
[4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
~~~

The `Applicative` instance also gives you the ability to "fork" the input
streams of two `Auto`s and then re-combine their output streams later:

~~~haskell
ghci> streamAuto' (sumFrom 0) [1..5]
[ 1, 3,  6, 10,  15]
ghci> streamAuto' (productFrom 1) [1..5]
[ 1, 2,  6, 24, 120]
ghci> streamAuto' (liftA2 (+) (sumFrom 0) (productFrom 1)) [1..5]
[ 2, 5, 12, 34, 135]
~~~

You can also "fork" an input stream to two `Auto`s, and then throw away the
output stream of one: (very useful for `Auto`s like `effect`, which we will
see later, where we only care about the monadic effects and not about the
actual output stream)

~~~haskell
ghci> streamAuto' (sumFrom 0 *> productFrom 1) [1..5]
[ 1, 2,  6, 24, 120]
ghci> streamAuto' (sumFrom 0 <* productFrom 1) [1..5]
[ 1, 3,  6, 10,  15]
~~~

Heck, you can even `sequenceA` several!

~~~haskell
sequenceA :: [Auto m a b] -> Auto m a [b]
~~~

It will take a list of `Auto`s and return an `Auto` that "forks" the input
stream into *all* of the original `Auto`s and aggregates together all of the
output streams.  A multi-way fork.

We also have the Applicative-derived instances like `Monoid`, so any `Auto m
a b` is a `Monoid` if `b` is a `Monoid`.

~~~haskell
mconcat :: Monoid b => [Auto m a b] -> Auto m a b
~~~

A lot of times you'll have a lot of things handling the same input in
different ways, and you'll want to recombine them all at the end.  Well,
`mconcat`, `sequence`, etc. are at your service!

This is the principle of "[scalable program architectures][spa]" at work!
The `mappend` of two `Auto`s is...another `Auto`!

[spa]: http://www.haskellforall.com/2014/04/scalable-program-architectures.html

Of course there the Applicative-derived `Num` (and assorted numerical
instances) too:

~~~haskell
ghci> streamAuto' (0 * sumFrom 0) [1..5]
[0, 0, 0, 0, 0,]
ghci> streamAuto' (negate (sumFrom 0)) [1..5]
[-1, -3, -6, -10, -15]
ghci> streamAuto' (10 + sumFrom 0) [1..5]
[11, 13, 16, 20, 25]
ghci> streamAuto' (sumFrom 0 + productFrom 1) [1..5]
[ 2, 5, 12, 34, 135]
~~~

Just don't go too crazy with these, okay?

Now, the `Category` instance is probably the most powerful tool at your
disposal.  As a first treat, it gives you `id :: Auto m a a`, an `Auto` whose
output is always exactly the corresponding input.

But more importantly, you can "chain together" `Auto`s end-to-end.  Compose
them as if they were functions.

You know how an `Auto` takes a stream and outputs a stream?  Well,
"chaining"/"composing" two `Auto`s will "pipe together" the streams.  `a2 .
a1` will be a new `Auto` that runs an input stream through both `a1` and `a2`.

~~~haskell
ghci> streamAuto' (sumFrom 0) [1..5]
[1,3,6,10,15]
ghci> streamAuto' (productFrom 1) [1,3,6,10,15]
[1,3,18,180,2700]
ghci> streamAuto' (productFrom 1 . sumFrom 0) [1..5]
[1,3,18,180,2700]
~~~

`sumFrom 0`'s output stream is the cumulative sum of the input stream.
`productFrom 1`'s output stream is the cumulative product of the input stream.
So their chaining/piping/composition is the cumulative product of the
cumulative sum.

~~~haskell
(.) :: Auto m b c -> Auto m a b -> Auto m a c
~~~

If you imagine an `Auto'` as an `[a] -> [b]`, then you can think of this as
"composing" the `[a] -> [b]` functions:

~~~haskell
-- streamAuto' gives us an [Int] -> [Int], so we can compose them using normal
-- function composition:
ghci> streamAuto' (productFrom 1) . streamAuto' (sumFrom 0) $ [1..5]
[1,3,18,180,2700]
-- composing `Auto`s is like composing their resulting `[a] -> [b]`s
ghci> streamAuto' (productFrom 1 . sumFrom 0) $ [1..5]
[1,3,18,180,2700]
~~~

(Math nuts might recognize this as saying that `streamAuto'` is a "category
homomorphism"...aka, a functor :)  Seeing that `streamAuto' (id :: Auto' a a)
== (id :: [a] -> [a])`, of course!)

Operationally, at every "step", it passes in each input to the first `Auto`,
and gets the output of that and passes it into the second `Auto`, and uses the
output of the second `Auto` as the result, updating *each* internal state.

Another example, here we have an `Auto` that takes an input stream and
outputs a `Blip` stream (more on that later) that emits whenever there is a
multiple of 5:

~~~haskell
       -- emitOn5s :: Auto' Int (Blip Int)
ghci> let emitOn5s = emitOn (\x -> x `mod` 5 == 0)
ghci> streamAuto' emitOn5s [1,5,9,3,10,2]
[NoBlip, Blip 5, NoBlip, NoBlip, Blip 10, NoBlip]
ghci> streamAuto' (hold . emitOn5s) [1,5,9,3,10,2]
[Nothing, Just 5, Just 5, Just 5, Just 10, Just 10]
~~~

`hold :: Auto' (Blip a) (Maybe a)` takes a stream of `Blip`s and returns a
stream that is `Maybe a`, where it is `Nothing` until the first emitted `Blip`
value, and `Just x` as the last received `Blip` value.

So here, we "chain" `hold` onto `emitOn5s`.  `emitOn5s` emits on everything
that is a multiple of `5`, and `hold` "holds on" to all of the emitted values.
Neat!

This can be used in conjunction with the `Applicative` instance for great
power.  In the end, your programs will really just be `(.)`-composed `Auto`s
with forks and re-combinings from `Applicative` and `Arrow` methods.

Speaking of `Arrow`, we also have a neat interface exposed by `Arrow`,
`ArrowPlus`, and `ArrowLoop`.  First of all, we get `arr :: (a -> b) -> Auto m
a b`, which basically an `Auto` that is a constant, pure function (the output
is the corresponding input applied to the given function).  We get the ability
to make an `Auto` run on "only the first item in a tuple" (`first`), or "only
`Left`s that come in" (`left`).  Also, we get proc notation!

~~~haskell
foo :: Auto' Int (Int, Maybe Int)
foo = proc x -> do
    sumX     <- sumFrom 0          -< x
    prodX    <- productFrom 1      -< x + sumX
    lastEven <- hold . emitOn even -< x
    id -< (prodX, lastEven)
~~~

~~~haskell
ghci> streamAuto' foo [4,7,3,6,5,1]
[ (    4, Just 4), (    144, Just 4), (    2448, Just 4)
, (63648, Just 6), (1909440, Just 6), (51554880, Just 6) ]
~~~

Most of what was just done could be written with the `Applicative`
instance as well...but in this way, the entire thing looks a lot like a
dependency graph, and it's pretty expressive and powerful.

#### Brief Primer on Proc Notation

An explanation on the syntax; when you see:

~~~haskell
sumX <- sumFrom 0 -< x
~~~

This reads as you are defining a binding `sumX`, and *the relationship between
sumX and x* is that `sumX` is the *cumulative sum* of `x`.

(from the first line, `foo = proc x -> do`, `x` is the input of the entire
`Auto`)

When we see:

~~~haskell
prodX <- productFrom 1 -< x + sumX
~~~

This reads as you are defining a binding `prodX`, and `prodX` is maintained as
the cumulative product of `x + sumX`.

All "values" in your proc block are actually *streams*.  `prodX` is a stream
of numbers, `x` is a stream, `sumX` is a stream...and `productFrom 1` lets you
describe the (static) *relationship* between those three streams.

The result of the last line of the proc block is the result of the entire
block:

~~~haskell
id -< (prodX, lastEven)
~~~

Means that the output stream of the entire block is just echoing the tuple
`(prodX, lastEven)`.

(Operationally, you can imagine that, at every step, `x` is "fed into"
`sumFrom 0`, and the result is named `sumX`; `x + sumX` is "fed into"
`productFrom 1`, etc.)

The power here is that it really reads like a straight-up dependency graph...a
graph of relationships to names.  Lay out your relationships explicitly and
declaratively, and the library takes care of the rest!  The semantic model of
an `Auto` representing a maintained relationship is made very clear in `proc`
notation.

Later on you can see that `proc` blocks can be pretty expressive --- using
if/then's and case statements, and also recursive bindings (so you can even
declare recursive graphs of concepts, and the library will figure out how to
solve it for you).

By the way, there are some "scoping" issues to be aware of.  Remember that
proc more or less builds a graph of relationships between values using `Auto`s
at compile-time; the whole graph and chaining-together-of-`Auto`s is done at
compile time.  So, the `Auto`s themselves have to be known at compile time.
We can't do something like this:

~~~haskell
foo :: Auto' Int Int
foo = proc x -> do
    y <- productFrom 1 -< x
    z <- sumFrom y     -< x
    id -< y + z
~~~

We can't do `sumFrom y`, because `y` isn't actually a "value" we have at
"compile"/"building" time...`y` is the stream that is the cumulative product
of the stream `x`.  `y` changes at every "point in time".  Remember, `Auto`
relationships in a proc block are "fixed", and "forever"; `productFrom 1` is
the "static relationship" between `x` and `y`.  So the `Auto` where `sumFrom`
is...it has to be a fixed thing that never changes.  But `y` changes every
step!

You can however do something like:

~~~haskell
bar :: Int -> Auto' Int Int
bar x0 = proc x -> do
    y <- productFrom 1 -< x
    z <- sumFrom x0    -< x
    id -< y + z
~~~

Because when we are "building" `bar x0`, we *have* `x0`!  It'll be `sumFrom
x0`, forever!

### Anyways!

Anyways!  Those are the primary typeclass based interfaces; explore the
library for more!

### From scratch

If you have to, when creating `Auto`s from scratch, we have:

~~~haskell
pure   :: b          -> Auto m a b
effect :: m b        -> Auto m a b
arr    :: (a -> b)   -> Auto m a b
arrM   :: (a -> m b) -> Auto m a b
~~~

`pure` and `effect` give you "constant-producing `Auto`"s that ignore their
input; `pure x` is an `Auto` that ignores its input and always outputs `x`.
`effect m` is an `Auto` that ignores its input and executes/sequences `m` at
every "step", and outputs the result at every step.  `arr` is an `Auto` that
maps every input to an output by running a pure function, and `arrM` is an
`Auto` that does the same but with a "monadic" function.

Here is a handy little summary!

~~~haskell
streamAuto' (pure x)  == map (const x)
streamAuto (effect m) == mapM (const m)
streamAuto' (arr f)   == map f
streamauto (arrM f)   == mapM f
~~~

None of these `Auto`s have "internal state"; however, we can make our own
internally stateful `Auto`s from scratch:

~~~haskell
iterator  :: (b -> b)             -> b -> Auto m a b
iteratorM :: (b -> m b)           -> b -> Auto m a b
accum     :: (b -> a -> b)        -> b -> Auto m a b
accumM    :: (b -> a -> m b)      -> b -> Auto m a b
mkState   :: (a -> s -> (b, s))   -> s -> Auto m a b
mkStateM  :: (a -> s -> m (b, s)) -> s -> Auto m a b
mkAuto_   :: (a -> (b, Auto m a b))    -> Auto m a b
mkAutoM_  :: (a -> m (b, Auto m a b))  -> Auto m a b
~~~

You can look at the documentation for all of these, but these all basically
work with "internal state" --- `iterator` ignores its input and repeatedly
applies a function to a value and pops it out at every step.  `accum`
maintains that the *output* is always the result of "folding together" (a la
`foldl`) all of the inputs so far, with a starting value.  `mkState` is
like a more powerful `accum`, which keeps an internal state that is updated
at every step.  `mkAuto_` lets you describe an `Auto` by its behavior under
`stepAuto'`.

~~~haskell
ghci> take 10 $ streamAuto' (iterator (+1) 0) (repeat ())
[0,1,2,3,4,5,6,7,8,9]
ghci> take 10 $ streamAuto' (accum (+) 0)   [1..]
[1,3,6,10,15,21,28,36,45,55]
~~~

It is recommended to only use `accum`, `mkState`, `mkAuto` only when
absolutely necessary; usually you can make what you want from combining
smaller, simple, pre-made `Auto`s.  But sometimes the case does arrive.

The Big Picture
---------------

So, at this point, let's look at the "big picture".  A program written with
`Auto` will involve, at every "step", gathering input, feeding into the
"master program `Auto`", getting the output, rendering it somehow, and
repeating.  But how do we build our `Auto`?  What is the advantage of using
`Auto` instead of `State`, etc.?

`Auto` lets you compose little meaning-bits into more complex meaning bits, by
specifying *invariant relationships* between *items of streams*.  These are
"forever-relationships" --- they don't just describe step-by-step, iterative,
stateful actions --- they describe invariant relationships.  And you can
create your own by composing, modifying, chaining, etc. all of the primitives.

Building a program in `Auto` is basically specifying relationships that are
maintained "forever"...and thinking about your program in that manner.

For example:

~~~haskell
sumAndProd :: Auto' Int Int
sumAndProd = proc x -> do
    sumX  <- sumFrom 0     -< x
    prodX <- productFrom 1 -< x
    id -< sumX + prodX

-- sumAndProd = liftA2 (+) (sumFrom 0) (productFrom 1)
~~~

`sumX` is a "forever" quantity...and so is `x`.  We say that the relationship
between `sumX` and `x` is that `sumX` is the cumulative sum (`sumFrom 0`) of
`x`.  The relationship between `prodX` and `x` is that `prodX` is the
cumulative product...and the relationship between `x` and the output is that
the output is the sum of `sumX` and `prodX` at every point in time.

Operationally, you also have a huge advantage here over using something like
`State` in that each `Auto` really contains its own "internal state" that is
inaccessible by the world.  For example, in that last example, `sumFrom 0`
works by maintaining its own internal state.  `productFrom 1` also maintains
its own internal state.

Nobody can ever "touch" or "inspect" the internal state of `sumFrom 0` and
`prudctFrom 1`.  It maintains it on its own.  This is in big contrast to
`State`-based solutions, which necessarily work on "global state", and
managing global vs. local state with monad morphisms.

Note that this "composes"; we can use `sumAndProd` in another `Auto`:

~~~haskell
foo :: Auto' Int String
foo = proc x -> do
    sp <- sumAndProd -< x
    y  <- blah blah  -< sp + x
    id -< show y
~~~

And `sumAndProd` now is its own "internally stateful" thing...you can take it
and pop it onto any other chain.  In `State`, you'd open yourself up to having
to create new sum types for extra state...whenever you combined any two
stateful operations on different states.

This locally stateful property truly allows us to "compose" ideas together and
relationships together and think of them as fixed invariants in a big picture.
Because each `Auto` "denotes" a relationship, and we build up bigger `Auto`s
by combining small denotative primitives to create bigger things that denote
more complex relationships, it really allows us to create a denotative
"language", where we declare relationships by building up smaller units of
meaning into bigger units of meaning.

Now...how do we actually implement the behavior that we want?  This is a job
for the primitive `Auto`s, but also really much a big job for ... the semantic
tools that come with the library!

Semantic Tools
--------------

An `Auto` represents a relationship between an input stream and an output
stream, but in order to build more expressive programs, this library also
comes with more semantic tools to work with in characterizing your streams
with "meaning", and tools to manipulate them and compose them in powerful ways
(within this framework of meaning) to express your programs.

The two main ones are `Blip` and `Interval`.

### Blip

We say that, in the context of inputs/outputs of `Auto`, a `Blip a` represents
a "blip stream" that occasionally, in isolated incidents, emits a value of
type `a`.

For example, `Auto' a (Blip b)` is an `Auto'` that a stream of `a`'s as input
and outputs a *blip stream* that occasionally emits with a `b`.  An `Auto'
(Blip a) b` is an `Auto'` that takes a *blip stream* that occasionally emits
with a `a` and outputs a stream of `b`'s.

If an `Auto` takes or outputs a "blip stream", it comes with some "semantic"
contracts on to how the stream behaves.  The main contract is that your `Blip`
stream should only output on (meaningfully) "isolated" incidents, and never on
continuous regions of the input stream.

This isn't enforced by the type system, but almost all of the `Auto`s offered
in this library will preserve this property!  And we encourage any that you
make to also preserve this property, in order to make "blip streams" *useful
in the first place*.

We saw an example earlier,

~~~haskell
ghci> let emitOn5s = emitOn (\x -> x `mod` 5 == 0)
ghci> streamAuto' emitOn5s [1,5,9,3,10,2]
[NoBlip, Blip 5, NoBlip, NoBlip, Blip 10, NoBlip]
~~~

Let's see if we can play around with it!  Well, we can "tag" blip emissions:

~~~haskell
ghci> streamAuto' (tagBlips "hey" . emitOn5s) [1,5,9,3,10,2]
[NoBlip, Blip "hey", NoBlip, NoBlip, Blip "hey", NoBlip]
~~~

And with proc blocks, we can even "name" blip streams and manipulate them as
streams!  Oh, also, `Blip` is a `Functor`, so you can use `fmap` and `(<$)`.

~~~haskell
blippy :: Monad m => Auto m Int String
blippy = proc x -> do
    on3s  <- tagBlips "3!" . emitOn3s -< x
    on5s' <- emitOn5s    -< x
    let on5s  = "5!" <$ on5s        -- from Data.Functor: replace all emitted
                                    -- values with the string "5!"
        on35s = on3s `mergeL` on5s  -- merge the streams, favoring the left
    intro  <- immediately -< "hello!"
    middle <- inB 6       -< "#6!"
    wut    <- never       -< "this should never happen!"
    id -< mergeLs [never, intro, middle, on35s] -- merge all, favoring firsts
~~~

~~~haskell
ghci> streamAuto' blippy [5,7,15,10,13,15,2]
[Blip "hello!", NoBlip, Blip "3!", Blip "5!", NoBlip, Blip "#6!", NoBlip]
--    ^ intro             ^ on3s     ^ on5s            ^ middle
~~~

Blip streams and "blip contracts"/"blip semantics" are useful because a lot of
the other semantic abstractions in `Auto` (like switches, and `Interval`) all
work with the "idea" of a "discrete", occasional, conceptually
"non-contiguous" blip stream.

Check out all of the built-in blip stream combinators at
*[Control.Auto.Blip][]*.

### Interval

The "opposite" of `Blip` and blip streams are "intervaled" `Auto`s: `Auto`s
that are "on" or "off" for (conceptually) contiguous chunks of steps.

An `Interval' a b` represents an `Auto` that takes a stream of `a`s as input,
and outputs a stream of `b`s that is "on" or "off", at contiguous swaths.

In truth, `Interval' a b` is just a type synonym for `Auto' a (Maybe b)`, and
`Interval m a b` is just a type synonym for `Auto m a (Maybe b)`.  But, if you
see a library auto with type `Interval`, or if you make an auto with type
`Interval`, it comes with "contracts".  These contracts help us really use
`Interval`s in a meaningful way --- that they are supposed to represent
`Auto`s that output things that are "on" or "off" for contiguous steps.

`Blip`s are "blippy", `Interval`s are "chunky".

We've already seen an `Interval` earlier:

~~~haskell
ghci> streamAuto' (hold . emitOn5s) [1,5,9,3,10,2]
[Nothing, Just 5, Just 5, Just 5, Just 10, Just 10]
~~~

`hold :: Interval' (Blip a) a`, so it turns a blip stream into a stream of
`a`s that are on and off.  In this case, it starts off "off", and is "on"
after the first emitted value, with the last emitted value.

`Interval`s are nice because you can have "choices" between two "on-off"
`Auto`s:

~~~haskell
ghci> let a1 = (onFor 3 . arr (+ 100)) <|!> whenI (> 6) <|!> arr (+ 200)
ghci> take 10 $ streamAuto' a1 [1..]
[101, 102, 203, 204, 205, 206, 7, 8, 9, 10]
ghci> let a2 = chooseInterval [offFor 8, onFor 3 . arr (+ 100)]
ghci> take 10 $ streamAuto' a2 [1..]
[Just 101, Just 102, Just 103, Nothing, Nothing, Just 6, Just 7]
~~~

(`<|!>`) forks the input into both `Interval`s, and the outputted one is the
first one that is "on".  You can chain them as long as the "final" `Auto` is
an `Auto`, and not an `Interval`:

~~~haskell
(<|!>) :: Interval m a b -> Auto m a b -> Auto m a b
~~~

`onFor n` lets the input pass for `n` steps.  `whenI` lets the input "pass
through" when the predicate is true (being sure to pick a meaningful predicate
based on the expected input for "chunky" output)

You can also "chain" `Interval`s with `bindI` and `compI`:

~~~haskell
ghci> streamAuto' (whenI (< 3) `compI` whenI (> 6)) [1..8]
[Just 1, Just 2, Nothing, Nothing, Nothing, Just 6, Just 7, Just 8]
ghci> streamAuto' (bindI (whenI (< 3)) . whenI (> 6)) [1..8]
[Just 1, Just 2, Nothing, Nothing, Nothing, Just 6, Just 7, Just 8]
~~~

Intervals are also used for things that want their `Auto`s to "signal" when
they are "off".  `Interval` is the universal language for, "you can be done
with me", when it is needed.  For example, the `interactAuto` loop takes an
`Interval String String`, and "turns off" on the first `Nothing` or "off"
value.

~~~haskell
ghci> interactAuto (onFor 4 . (++ "!!!"))
> hello
hello!!!
> how
how!!!
> are
are!!!
> you
you!!!
> today
--- (end of output)
~~~

Like with blip streams, intervals are used to great effect with switches, like
the useful `(-->)` combinator:

~~~haskell
ghci> let a1 = whileI (<= 4) --> pure 0
ghci> streamAuto' a1 [1..10]
[1, 2, 3, 4, 0, 0, 0, 0, 0, 0]
               -- look, recursion!
ghci> let a2 = (onFor 3 . pure "hi") --> (onFor 2 . pure "bye") --> a2
ghci> take 10 $ streamAuto' a2 (repeat ())
["hi", "hi", "hi", "bye", "bye", "hi", "hi", "hi", "bye", "bye"]
~~~

You can see all of the built-in `Interval` combinators in
*[Control.Auto.Interval][]*.

### More Tools

#### Switching

A powerful grab-bag of tools that can be used with intervals and blip streams
is the idea of "switching", as mentioned earlier.  `Auto`s that behave like
one `Auto` for a while, and then another afterwards.

For example, `switchOn_` and `switchOnF` lets you have an `Auto` that behaves
like one `Auto`, until the blip stream it is receiving emits something ---
then, it behaves like a totally new one, based on the emitted value.

`switchFrom_` and `switchFromF` also gives you an `Auto` that behaves like one
`Auto`...except that `Auto` has the ability to "replace itself" by having its
output blip stream emit a value.  The value determines what it wants to
replace itself with.

These are really useful for implementing things like "modes" --- your program
has different modes of behavior, which you can represent with a different
`Auto` for each mode...and you can switch between them with these switches!

See the documentation for these at the *[Control.Auto.Swtich][]* module for
more information!

#### Collections

In *[Control.Auto.Collection][]*, we have a bunch of "`Auto` boxes" and
"`Auto` collections", which maintain `Auto`s that are dynamic collections of
`Auto`s.

For example, you have `zipAuto`, which takes a list of `Auto`s and returns an
`Auto` taking in a list, that feeds each item in the input list into each
corresponding `Auto`.  It's like running multiple `Auto`s in parallel on
different inputs.

For example, you have `mux f :: Auto m (k, a) b`, which stores a bunch of
`Auto m a b`s indexed by a key `k`.  At every step, it takes a `(k, a)`,
looks up the `Auto` at that `k`, feeds in the `a`, and outputs that output
`b`.  You can use this to store several `Auto`s in parallel and really just
run the one you want at any given time.

There's also `gather f :: Auto m (k, a) (Map k b)`, which again stores a bunch
of `Auto m a b`s indexed by a key `k`.  At every step, it *updates* only the
`Auto` at that key `k`, but outputs a `Map` of all the outputs so far by all
of the internal `Auto`s.

See the documentation at *[Control.Auto.Collection][]* for more!

### Recursive relationships

Not exactly a tool per se, but the *auto* library has the ability to state and
"solve" for recursive relationships.

We can define an `Auto` that "chases" its input:

~~~haskell
chaseFrom :: Num a => a -> Auto' a a
chaseFrom x0 = proc target -> do
    rec let step = signum (target - x)  -- 1 if target is bigger
                                        -- 0 if matches
                                        -- -1 if smaller

        x <- sumFromD 0 -< step

    id -< x
~~~

~~~haskell
ghci> streamAuto' (chaseFrom 0) [3,3,3,3,3,-1,-1,-1,-1,-1]
  [0,1,2,3,3,3,2,1,0,-1]
-- ^ chasing 3 ^
--             ^ chasing -1
~~~

`x` is the cumulative sum of each `step` and the `step` is determined based on
the `target` and the current position `x`.  So `x`'s relationship is that it
is the cumulative sum of `step`, and `step`'s relationship is that it is the
difference between `x` and `target`.  It's a recursive relationship!

The *auto* library will attempt to find a "fixed point" of the recursive
relationship...sort of "solving for" the output stream that will match this
recursive relationship.  However, it needs a little help.  For every step, it
needs a way to get a "first value" from *something* without needing any input.
That is, at least *one* of the `Auto`s in your proc block has to be able to
pop out its *first* result without an input.

This is what `sumFromD` is for...we don't use `sumFrom`, but `sumFromD`.
`sumFromD` will always output *its original accumulator first*, before taking
into account the inputs:

~~~haskell
ghci> streamAuto' (sumFrom 0) [1..10]
[1,3,6,10,15,21,28,36,45,55]
ghci> streamAuto' (sumFromD 0) [1..10]
[0,1,3,6,10,15,21,28,36,45]
~~~

This is how the *auto* library will "tie" the loop and find the fixed point.
Have this, and everything works!  Cyclic relationships and feedback loops...
just like in real life!


Serialization
-------------

One of this library's features is that the `Auto` type offers an interface in
which you can serialize ("freeze") and "resume" an Auto, in `ByteString`
(binary) form.

You can "freeze" any `Auto` into a `ByteString` using `encodeAuto`, and you
can "resume" any `Auto` from a `ByteString` using `decodeAuto`.

Note `decodeAuto` and `loadAuto` "resume" a *given `Auto`*.  That is, if
you call `decodeAuto` on a "fresh `Auto`", it'll decode a `ByteString`
into *that `Auto`, but "resumed"*.  That is, it'll "fast forward" that
`Auto` into the state it was when it was saved.

For example, let's look at `sumFrom 0`.  If it is fed 3 and 10, it'll have its
internal accumulator as 13, keeping track of all the numbers it has seen so
far.

~~~haskell
ghci> let a         = sumFrom 0
ghci> let (_, a')   = stepAuto' a  3
ghci> let (_, a'')  = stepAuto' a' 10
~~~

`encodeAuto` can be used to "freeze"/"save" the `Auto` into the `ByteString`
`bs`:

~~~haskell
ghci> let bs            = encodeAuto a''
~~~

`decodeAuto` can be used to "resume" from the *original* `a`.  Remember, `a`
was the original `Auto`, the summer `Auto` with a starting accumulator of 0.
`decodeAuto` will "resume" it, with and resume it with its internal
accumulator at 13.

~~~haskell
ghci> let Right resumed = decodeAuto a bs
ghci> let (y, _)        = stepAuto' resumed 0
13
~~~

Note that not all `Auto`s in this library can be resumed.  By default, you can
assume that they *can*...while those that can't will by naming convention be
suffixed with a `_`:  `sumFrom` vs. `sumFrom_`, for example.  This means that
when you "save" the `Auto`, you don't really save any state...and when you
"resume" it, nothing is really resumed, and resuming is a no-op:

~~~haskell
-- sumFrom_ can't be saved/resumed, so it "goes nowhere" when resumed.
decodeAuto (sumFrom_ 0) bs = Right (sumFrom_ 0)
~~~

This feature is useful for "save states" of certain `Auto`s, or just for
serialization and resuming in general.

You can play some fun tricks with the *[Control.Auto.Serialize][]*
module...for example, `saving "foo.dat"` will turn any `Auto` into an `Auto`
that serializes itself at every step to "foo.dat"

~~~haskell
ghci> let a1 = saving "foo.dat" (sumFrom 0) :: Auto IO Int Int
ghci> streamAuto a1 [1..10]         -- saves the Auto as it goes along
[ 1, 3, 6,10,15,21,28,36, 45, 55]
ghci> a2 <- readAutoErr "foo.dat" a1 :: Auto IO Int Int
ghci> streamAuto a2 [1..10]         -- a2 is resumed to where a1 was last
[56,58,61,65,70,76,83,91,100,110]
~~~

If you want to make your own `Auto` combinators and transformers that work
with serialization, see the mini-tutorial at the documentation for
[mkAutoM][] in the [Control.Auto.Core][] module

### Serialization composes

The magic of implicit serialization is that the serialization of complex
`Auto`s is preserved under combination and manipulation with the various
instances and combinators in this library.  For example, serializing the
complex `blippy` example above, or a huge complex application, is all done
automatically!  The overall serialization structure is implicitly built and
inferred.  Think of it like the library analyzing what needs to be serialized
in your program, and coming up with a serialization and reloading strategy.

This is used to great effect in [auto-examples][], where entire applications and
chat bots are serialized..."for free".  Build complex chat bots, and the
serialization is handled implicitly.

### Safecopy problem

There is one slightly drawback however...the "safecopy" problem.  If you
alter the structure of your `Auto` by adding another aspect that needs to be
serialized...your `Auto` can no longer "read"/resume from the binary
serialization of its older version, because it'll expect the previous
serialization strategy, and be unable to read it.  This means that, if you
publish programs, save files might become unloadable by new versions of your
`Auto`.

One solution is to *serialize individual portions* only of your program ---
portions that you know will stay fixed.  You can do this by techniques in
[chatbot][], where each individual module of the chatbot is serialized to its
own place on disk using `serializing`, a variation of `saving` from above.
That way, if you add more modules to the chat bot, it can still individually
resume its smaller modules without caring about the rest.

[chatbot]: https://github.com/mstksg/auto-examples#chatbot

(I'll admit that this is not a perfect solution; more research and experiments
are continually being done.  Feel free to talk to me if you have any ideas or
leads!)

Final partings
--------------

One last note before finishing up...if you ever want to implement a low-level
library, or implement a "back-end", defining your own `Auto`s and working with
them has its own rules.  You're a bit "on your own", in this sense; the
optimization game might take you to places that really get rid of the nice
semantic denotative ideals of this library. I plan on writing a
framework/low-level guide soon (for writing, say, a GUI framework, or hooking
on GUI).

However, one good principle is just to *separate* your "two hats" as much as
possible.  There's the hat you wear when you are thinking about your program
logic, dealing with compositions of ideas ... and there's the hat you wear
when you are at the nitty-gritty interface between your system and the real
world. One goal in Haskell is always to be able to create as clear a divide as
possible...so you can really enjoy the best of both worlds.  So just make sure
that the `Auto`s and API that you export behave in meaningful ways that you
can reason about...just what we expect from using `Auto` :)

Anyways, I recommend just looking over the combinators available to you in the
various modules, like *[Control.Auto.Blip][]*, *[Control.Auto.Interval][]*,
and *[Control.Auto.Switch][]*.  We didn't go over anything close to all of
them in this tutorial, so it's nice for getting a good overview.  The most
up-to-date documentation at this point in time is on [the github pages][docs],
but there's also the [hackage docs][hackage] as well.

A good next step too would be to check out the [All About Auto][aaa] series on
my blog, where I break down approaching and finishing real-world problems with
the library using the tools described here. You can also look at the
[auto-examples][] directory and peruse over the examples, which each highlight
a different aspect of the library, so you can see how all of these ideas work
together.

Help is always available on the *#haskell-auto* channel on freenode IRC; you
can also email me at <justin@jle.im>, or find me on twitter as
[mstk][twitter].  There is no mailing list or message board yet, but for now,
feel free to abuse the [github issue tracker][issues].

Now go forth and make locally stateful, denotative, declarative programs!

[aaa]: http://blog.jle.im/entries/series/+all-about-auto
[auto-examples]: https://github.com/mstksg/auto-examples
[blog]: http://blog.jle.im
[docs]: https://mstksg.github.io/auto/
[hackage]: http://hackage.haskell.org/package/auto
[issues]: https://github.com/mstksg/auto/issues
[mkAutoM]: http://mstksg.github.io/auto/Control-Auto-Core.html#v:mkAutoM
[tutorial]: https://github.com/mstksg/auto/blob/develop/tutorial/tutorial.md
[twitter]: https://twitter.com/mstk

[Control.Auto.Blip]: http://mstksg.github.io/auto/Control-Auto-Blip.html
[Control.Auto.Collection]: http://mstksg.github.io/auto/Control-Auto-Collection.html
[Control.Auto.Core]: http://mstksg.github.io/auto/Control-Auto-Core.html
[Control.Auto.Interval]: http://mstksg.github.io/auto/Control-Auto-Interval.html
[Control.Auto.Run]: http://mstksg.github.io/auto/Control-Auto-Run.html
[Control.Auto.Serialize]: http://mstksg.github.io/auto/Control-Auto-Serialize.html
[Control.Auto.Switch]: http://mstksg.github.io/auto/Control-Auto-Switch.html