packages feed

auto 0.2.0.5 → 0.2.0.6

raw patch · 9 files changed

+265/−96 lines, 9 filesdep ~basedep ~profunctorsdep ~semigroupsPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

Dependency ranges changed: base, profunctors, semigroups

API changes (from Hackage documentation)

+ Control.Auto: streamAutoEffects :: (Monad m, MonadTrans t, MonadPlus (t m), Monad m') => (forall c. m' c -> m c) -> [a] -> Auto m' a b -> t m b
+ Control.Auto: 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
+ Control.Auto.Interval: holdJusts :: Serialize a => Interval m (Maybe a) a
+ Control.Auto.Interval: holdJusts_ :: Interval m (Maybe a) a
+ Control.Auto.Run: streamAutoEffects :: (Monad m, MonadTrans t, MonadPlus (t m), Monad m') => (forall c. m' c -> m c) -> [a] -> Auto m' a b -> t m b
+ Control.Auto.Run: 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

Files

CHANGELOG.md view
@@ -1,10 +1,30 @@+0.2.0.6+-------+<https://github.com/mstksg/auto/releases/tag/v0.2.0.6>++*   **Control.Auto.Run**: As a part of an effort to provide integration with+    *disciplined* effectful streaming, introduced `streamAutoEffects` and+    `toEffectStream`, which convert `Auto m a b`'s to *streams of effects* in+    `m` that can be processed and manipulated and integrated with any+    [`ListT`-compatible library][1], like *pipes*.  See documentation for more+    details.  These were also added to the exports of `Control.Auto`.+*   **Control.Auto.Interval**: New `Auto` `holdJusts`, which stretches the+    last seen "on"/`Just` value over the duration of a "off"/`Nothing`+    interval.+*   Documentation fixes to emphasize *auto*'s focus on *value* streams, not+    *effect* streams, in contrast to *pipes*, *conduit*, etc.+*   Version restrictions on some packages relaxed on *profunctors*,+    *semigroups*, and *base*.++[1]: http://www.haskellforall.com/2014/11/how-to-build-library-agnostic-streaming.html+ 0.2.0.5 ------- <https://github.com/mstksg/auto/releases/tag/v0.2.0.5>  *   **Control.Auto.Process.Random**: Added combinators and sealers dealing     for working with an underlying `Rand` or `RandT` monad.-*   Because of this, committed to adding `MonadRandom` as a dependency.+*   Because of this, committed to adding *MonadRandom* as a dependency.  0.2.0.4 -------
README.md view
@@ -1,7 +1,9 @@ Auto ==== -(Working name)+~~~bash+$ cabal install auto+~~~  Check it out! -------------@@ -29,7 +31,7 @@ -- recursive/cyclic graph of dependencies.  It's a feedback system, after all. -- pid :: MonadFix m => (Double, Double, Double) -> System m -> System m-pid (kp, ki, kd) blackbox = proc target -> do+pid (kp, ki, kd) blackbox = proc target -> do       -- proc syntax; see tutorial     rec --  err :: Double         --  the difference of the response from the target         let err        = target - response@@ -54,6 +56,7 @@         -- the response of the system, feeding the control into the blackbox         response <- blackbox   -< control +    -- the output of this all is the value of the response     id -< response ~~~ @@ -64,9 +67,11 @@ **Auto** is a Haskell DSL and platform providing an API with declarative, compositional, denotative semantics for discrete-step, locally stateful, interactive programs, games, and automations, with implicitly derived-serialization.  At the high-level, it allows you to describe your interactive-program or simulation as a *stream transformer*, by composition and-transformation of other stream transformers.+serialization.  It is suited for any domain where your program's input or+output is a stream of values, input events, or output views.  At the+high-level, it allows you to describe your interactive program or simulation+as a *value stream transformer*, by composition and transformation of other+stream transformers.  *   **Haskell DSL/library**: It's a Haskell library that provides a     domain-specific language for composing and declaring your programs/games.@@ -152,21 +157,22 @@  It's a part of this package directory and also on github at the above link. The current development documentation server is found at-<https://mstksg.github.io/auto>. You can find examples and demonstrations in-the [auto-examples][] repo on github; they are constantly being kept-up-to-date with the currently super unstable API.+<https://mstksg.github.io/auto>. -[auto-examples]: https://github.com/mstksg/auto-examples+From there, you can check out my [All About Auto][aaa] series on my blog,+where I break sample projects and show to approach projects in real life.  You+can also find examples and demonstrations in the [auto-examples][] repo on+github. -More examples and further descriptions will appear here as development-continues.+[aaa]: http://blog.jle.im/entries/series/+all-about-auto+[auto-examples]: https://github.com/mstksg/auto-examples  ### Support -Though this library is not officially released yet, the official support and-discussion channel is #haskell-auto on freenode.  You can also usually find me-(the maintainer and developer) as *jle`* on #haskell and #haskell-game.  Also,-contributions to documentation and tests are welcome! :D+The official support and discussion channel is *#haskell-auto* on freenode.+You can also usually find me (the maintainer and developer) as *jle`* on+*#haskell-game* or *#haskell*. Also, contributions to documentation and tests+are welcome! :D  Why Auto? ---------@@ -235,8 +241,8 @@  *   Cases involving inherently continuous time.  **Auto** is meant for     situations where time progresses in discrete ticks --- integers, not-    reals.  Auto is not suggested even to "simulate" continuous time with-    discrete sampling. You can do it...but FRP is a much, much better+    reals.  You can "fake" it by faking continuous time with discrete+    sampling...but FRP is a much, much more powerful and safe     abstraction/system for handling this than **Auto** is.  See the later     section on FRP. @@ -252,7 +258,8 @@     can be useful for file processing and stream modification, but only if you     separately handle the IO portions.  **Auto** works very well with *pipes*     or *conduit*; those libraries are used to "connect" **Auto** to the-    outside word, and provide a safe interface.+    outside word, and provide a safe interface.  In other words, Auto handles+    "value streams", while pipes/conduit handle "effect streams"   Relation to FRP@@ -260,17 +267,19 @@  **Auto** borrows a lot of concepts from *[Functional Reactive Programming][frp]* --- especially arrowized, locally stateful libraries like-[netwire][].  **Auto** attempts to bring an applicable subset of FRP's-high-level concepts and semantics and transplant them into the world of-fundamentally discrete-step/discrete-time contexts.  Users of such libraries-would likely be able to quickly pick up **Auto**, and the reverse is-(hopefully) true too.+[netwire][].  At best, **Auto** can be said to bring a lot of API ideas and+borrows certain aspects of the semantic model of FRP and incorporates them as+a part of a broader semantic model more suitable for discrete-time+discrete-stel contexts.  But, users of such libraries would likely be able to+quickly pick up **Auto**, and the reverse is (hopefully) true too.  Note that this library is not meant to be any sort of meaningful substitution for implementing situations which involve concepts of continuous ("real number-valued", as opposed to "integer valued") time (like real-time games); you can "fake" it using **Auto**, but in those situations, FRP provides a much-superior semantics and set of concepts for working in such contexts.+superior semantics and set of concepts for working in such contexts.  That is,+you can "fake" it, but you then lose almost all of the benefits of FRP in the+first place.  [frp]: http://en.wikipedia.org/wiki/Functional_reactive_programming [netwire]: https://hackage.haskell.org/package/netwire@@ -285,8 +294,8 @@ import Prelude hiding ((.), id)  -- Let's build a big chat bot by combining small chat bots.--- A "ChatBot" is going to be an `Auto` taking in a tuple of an incoming nick,--- message, and timestamp at every step; the result is a "blip stream" that+-- A "ChatBot" is going to be an `Auto` taking in a stream of tuples of+-- incoming nick, message, and timestamps; the result is a "blip stream" that -- emits with messages whenever it wants to respond.  type Message   = String@@ -296,7 +305,7 @@  -- Keeps track of last time a nick has spoken, and allows queries seenBot :: Monad m => ChatBot m-seenBot = proc (nick, msg, time) -> do+seenBot = proc (nick, msg, time) -> do          -- proc syntax; see tutorial     -- seens :: Map Nick UTCTime     -- Map containing last time each nick has spoken     seens <- accum addToMap M.empty -< (nick, time)@@ -399,18 +408,22 @@ Open questions -------------- -*   In principle very little of your program should be over `IO` as a-    monad...but sometimes, it becomes quite convenient for abstraction-    purposes.  Handling IO errors in a robust way isn't quite my strong point,-    and so while almost all `Auto` idioms avoid `IO` and runtime, for some-    applications it might be unavoidable.  Providing industry-grade tools for-    making `IO` robust would be a good next priority.- *   "Safecopy problem"; serialization schemes are implicitly derived, but if     your program changes, it is unlikely that the new serialization scheme     will be able to resume something from the old one.  Right now the solution     is to only serialize small aspects of your program that you *can* manage     and manipulate directly when changing your program.  A better solution     might exist.++*   In principle very little of your program should be over `IO` as a+    monad...but sometimes, it becomes quite convenient for abstraction+    purposes.  Handling IO errors in a robust way isn't quite my strong point,+    and so while almost all *auto* idioms avoid `IO` and runtime, for some+    applications it might be unavoidable.  *auto* is not and will never be+    about streaming IO effects...but knowing what parts of IO fit into the+    semantic model of *value stream transformers* would yield a lot of+    insight.  Also, most of the `Auto` "runners" (the functions that translate+    an `Auto` into `IO` that executes it) might be able to benefit from a more+    rigorous look too.  *   Tests; tests aren't really done yet, sorry!  Working on those :)
auto.cabal view
@@ -1,21 +1,28 @@ name:                auto-version:             0.2.0.5+version:             0.2.0.6 synopsis:            Denotative, locally stateful programming DSL & platform description:         (Up to date documentation is maintained at                      <https://mstksg.github.com/auto>)                      .+                     Read the README first!+                     <https://github.com/mstksg/auto/blob/master/README.md>+                     , for motivating examples, and concrete explanations of+                     things described here.+                     .                      /auto/ 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.+                     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.                      .                      /auto/ works by providing a type that encapsulates-                     "stream transformers", or locally stateful functions; by-                     specifying your program as a (potentially cyclic) graph-                     of relationships between streams, you create a way of-                     "declaring" a system based simply on static relationships-                     between quantities.+                     "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 global state, /auto/ works by@@ -74,18 +81,18 @@                      , Control.Auto.Serialize                      , Control.Auto.Switch                      , Control.Auto.Time-  -- other-modules:       -  -- other-extensions:    -  build-depends:       base         >= 4.6      && < 4.8+  -- other-modules:+  -- other-extensions:+  build-depends:       base         >= 4.6      && < 4.9+                     , MonadRandom  >= 0.3.0.1  && < 0.4                      , bytestring   >= 0.10.4.0 && < 0.11                      , cereal       >= 0.4.1.1  && < 0.5                      , containers   >= 0.5.5.1  && < 0.6                      , deepseq      >= 1.3.0.2  && < 2.0-                     , profunctors  >= 4.4.1    && < 5.0+                     , profunctors  >= 4.3      && < 5.0                      , random       >= 1.1      && < 2.0-                     , semigroups   >= 0.16.2.2 && < 0.17+                     , semigroups   >= 0.16     && < 0.17                      , transformers >= 0.4.2.0  && < 0.5-                     , MonadRandom  >= 0.3.0.1  && < 0.4   hs-source-dirs:      src   default-language:    Haskell2010   ghc-options:         -Wall
src/Control/Auto.hs view
@@ -121,6 +121,8 @@   -- * Running   , interactAuto   , interactRS+  , streamAutoEffects+  , toEffectStream   -- * Re-exports   , module Control.Applicative   , module Control.Arrow
src/Control/Auto/Core.hs view
@@ -15,6 +15,10 @@ -- This module defines and provides the core types, (smart) constructors, -- and general high and low-level utilities used by the /auto/ library. --+-- Note that importing and using functions from this module in part voids+-- some of the "semantic contracts" of the 'Auto' 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@@ -114,10 +118,11 @@ -- (optionally) maintained within the context of a monad. -- -- A lot of fancy words, I know...but you can think of an 'Auto' as nothing--- more than a "stream transformer".  A stream of sequential inputs come in--- one at a time, and a stream of outputs pop out one at a time, as well.+-- 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 'streamAuto' function, you can "unwrap" the inner stream+-- Using the 'streamAuto' function, you can "unwrap" the inner value stream -- transformer from any 'Auto': if @a :: 'Auto' m a b@, 'streamAuto' lets -- you turn it into an @[a] -> m [b]@.  "Give me a stream of @a@s, one at -- a time, and I'll give you a list of @b@s, matching a relationship to@@ -127,6 +132,11 @@ -- -- unwrap your inner [a] -> m [b]! -- 'streamAuto' :: Monad m => 'Auto' m a b -> ([a] -> m [b]) -- @+--+-- You can also turn an @'Auto' m a b@ into an /effects stream/ that+-- executes effects sequentially with 'toEffectStream' and+-- 'streamAutoEffects', so you can run it with a ListT-compatible library+-- like /pipes/. -- -- There's a handy type synonym 'Auto'' for relationships that don't really -- need a monadic context; the @m@ is just 'Identity':
src/Control/Auto/Interval.hs view
@@ -43,6 +43,9 @@   , hold_   , holdFor   , holdFor_+  -- * Stretching+  , holdJusts+  , holdJusts_   -- * Composition with 'Interval'   , during   , compI@@ -526,6 +529,22 @@                    (Blip b,  _    ) -> (Just b , n    )                    (_     , (_, 0)) -> (Nothing, 0    )                    (_     , (z, j)) -> (z      , j - 1)++-- | "Stretches" the last "on"/'Just' input over the entire range of+-- following "off"/'Nothing' inputs.  Holds on to the last 'Just' until+-- another one comes along.+--+-- >>> streamAuto' holdJusts [Nothing, Just 1, Just 3, Nothing, Nothing, Just 5]+-- [Nothing, Just 1, Just 3, Just 3, Just 3, Just 5]+--+holdJusts :: Serialize a+          => Interval m (Maybe a) a+holdJusts = accum (flip (<|>)) Nothing++-- | The non-resuming/non-serializing version of 'holdJusts'.+--+holdJusts_ :: Interval m (Maybe a) a+holdJusts_ = accum_ (flip (<|>)) Nothing  -- | Forks a common input stream between the two 'Interval's and returns, -- itself, an 'Interval'.  If the output of the first one is "on", the
src/Control/Auto/Process/Random.hs view
@@ -376,7 +376,7 @@             -> (Blip a, g) _bernoulliF p x g = (outp, g')   where-    (roll, g') = randomR (0, 1) g+    (roll, g') = randomR (0 :: Double, 1) g     outp | roll <= p = Blip x          | otherwise = NoBlip @@ -450,7 +450,7 @@                 -> (Maybe a, (g, Bool)) _randIntervalsF thresh x (g, onoff) = (outp, (g', onoff'))   where-    (roll, g') = randomR (0, 1) g+    (roll, g') = randomR (0 :: Double, 1) g     onoff' = onoff `xor` (roll <= thresh)     outp = x <$ guard onoff     -- should this be onoff' ?
src/Control/Auto/Run.hs view
@@ -45,18 +45,22 @@   -- * Running on concurrent channels   , runOnChan   , runOnChanM+  -- * Running on as a ListT-compatible stream+  , streamAutoEffects+  , toEffectStream   ) where  import Control.Applicative import Control.Auto.Core import Control.Auto.Interval import Control.Concurrent-import Control.Monad hiding  (mapM, mapM_)+import Control.Monad hiding      (mapM, mapM_)+import Control.Monad.Trans.Class import Data.Functor.Identity import Data.Maybe import Data.Profunctor-import Prelude hiding        (interact, mapM, mapM_)-import Text.Read+import Prelude hiding            (interact, mapM, mapM_)+import Text.Read hiding          (lift)  -- | Streams the 'Auto' over a list of inputs; that is, "unwraps" the @[a] -- -> m [b]@ inside.  Streaming is done in the context of the underlying@@ -127,7 +131,9 @@  -- | Stream an 'Auto' 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.+-- fine with infinite lists.  (That is, @'streamAuto' ('arrM' f)@ behaves+-- exactly like @'mapM' f@, and you can reason with 'Auto's as if you'd+-- reason with @mapM@ on an infinite list) -- -- Note that, conceptually, this turns an @'Auto' m a b@ into an @[a] -> -- m [b]@.@@ -148,6 +154,34 @@ -- @a@ here is like @'sumFrom' 0@, 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 /pipes/ or /conduit/.  We don't stream over the @m@ Monad (like+-- @IO@)...we stream over the __input elements__.  Using 'streamAuto' on an+-- infinite list allows you to "stop", for example, to find the+-- result...but it will still sequence all the *effects*.+--+-- For example:+--+-- >>> take 10 <$> streamAuto (arrM print *> id) [1..]+--+-- Will execute 'print' on every element before "returning" with [1..10].+--+-- >>> flip runState 0 $ take 10 <$> streamAuto (arrM (modify . (+)) *> id) [1..]+-- ([1,2,3,4,5,6,7,8,9,10], .... (never terminates)+--+-- This will immediately return the "result", and you can bind to the+-- result with `(>>=)`, but it'll never return a "final state", because the+-- final state involves executing all of the 'modify's.+--+-- In other words, we stream /values/, not /effects/.  You would analyze+-- this behavior the same way you would look at something like 'mapM'.+--+-- If you want to stream effects, you can use 'streamAutoEffects' or+-- 'toEffectStream', and use an effects streaming library like /pipes/ (or+-- anything with /ListT/)...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        -- ^ 'Auto' to stream            -> [a]               -- ^ input stream@@ -474,3 +508,58 @@            -> IO (Auto' a b)          -- ^ final 'Auto' after it all, when                                       --     the handle resturns 'False' runOnChan = runOnChanM (return . runIdentity)++-- | Turns an @Auto m' a b@ and an "input producer" @m a@ into a "ListT+-- compatible effectful stream", as described at+-- <http://www.haskellforall.com/2014/11/how-to-build-library-agnostic-streaming.html>+--+-- Any library that offers a "@ListT@" type can use this result...and+-- usually turn it into an effectful stream.+--+-- For example, the /pipes/ library offers @runListT@ so you can run this,+-- constantly pulling out @a@s from the stream using the @m a@, feeding+-- it in, and moving forward, all with the effect stream manipulation tools+-- and resource handling of /pipes/.+--+-- This is useful because /auto/, the library, mainly provides tools for+-- working with transformers for /value/ 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)   -- ^ function to change the underyling monad from @m'@ to @m@+               -> m a                       -- ^ action to generate inputs+               -> Auto m' a b               -- ^ Auto to run as an effectful stream+               -> t m b                     -- ^ @ListT@-compatible type+toEffectStream nt getInp = go+  where+    go a0 = do+      (y, a1) <- lift $ do x <- getInp+                           nt $ stepAuto a0 x+      return y `mplus` go a1++-- | Turns an @Auto m' a b@ with a list of inputs into a "ListT compatible+-- effectful stream", as described at+-- <http://www.haskellforall.com/2014/11/how-to-build-library-agnostic-streaming.html>+--+-- Any library that offers a "@ListT@" type can use this result...and+-- usually turn it into an effectful stream.+--+-- For example, the /pipes/ library offers @runListT@ so you can run this,+-- running the 'Auto' over the input list, all with the effect stream+-- manipulation tools and resource handling of /pipes/.+--+-- This is useful because /auto/, the library, mainly provides tools for+-- working with transformers for /value/ 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+streamAutoEffects nt = go+  where+    go [] _      = mzero+    go (x:xs) a0 = do+      (y, a1) <- lift . nt $ stepAuto a0 x+      return y `mplus` go xs a1
tutorial/tutorial.md view
@@ -4,16 +4,11 @@ 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 further information, check out-[auto-examples][] for more real-world examples, and some of my writeups on [my-blog][blog].  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-examples]: https://github.com/mstksg/auto-examples-[blog]: http://blog.jle.im-[docs]: https://mstksg.github.io/auto/-[tutorial]: https://github.com/mstksg/auto/blob/develop/tutorial/tutorial.md+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 ----@@ -32,11 +27,14 @@ 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 *stream transformers*.  A stream of-sequential inputs come in one at a time, and a stream of outputs 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]`.+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@@ -68,7 +66,7 @@ `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 *causual*; the nth item of the output+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.@@ -132,7 +130,7 @@ `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 actaully+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@@ -252,7 +250,7 @@ a b` is a `Monoid` if `b` is a `Monoid`.  ~~~haskell-mconcat :: Monoid m => [Auto m a b] -> Auto m a b+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@@ -323,14 +321,14 @@ ~~~  (Math nuts might recognize this as saying that `streamAuto'` is a "category-homomorphism"...aka, a functr :)  Seeing that `streamAuto' (id :: Auto' a a)+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 and+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: @@ -353,13 +351,14 @@  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-cominings from `Applicative` and `Arrow` methods.+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).  But more-importantly, we get proc notation!+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)@@ -432,7 +431,7 @@ 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 someothing like this:+We can't do something like this:  ~~~haskell foo :: Auto' Int Int@@ -446,7 +445,7 @@ "compile"/"building" time.  `y` is what we're calling the result of `productFrom 1`, at every step, so its value changes at every step, and every `Auto` has to be a **fixed `Auto`**.  Remember, `Auto` relationships are-"forever" and fixed, declaritive style.  So the `Auto` where `sumFrom` is,+"forever" and fixed, declarative style.  So the `Auto` where `sumFrom` is, there, has to be a fixed thing that doesn't change at every step...but `y` is a value that will very as the stream marches on. @@ -594,7 +593,7 @@ 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 promitives to create bigger things that denote+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.@@ -796,10 +795,10 @@ replace itself with.  These are really useful for implementing things like "modes" --- your program-has different modes of behavior, which you can represet with a different+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 thise at the *[Control.Auto.Swtich][]* module for+See the documentation for these at the *[Control.Auto.Swtich][]* module for more information!  #### Collections@@ -956,7 +955,7 @@  ### Serialization composes -The magic of implicit serialization is that the serliazation of complex+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@@ -995,7 +994,7 @@ --------------  One last note before finishing up...if you ever want to implement a low-level-library, or implement a "backend", defining your own `Auto`s and working with+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@@ -1015,28 +1014,38 @@ 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]+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 wouild be also just looking 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.-There will also be writeups on [my blog][blog] coming up too!+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]. -[twitter]: https://twitter.com/mstk-[issues]: https://github.com/mstksg/auto/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-[Control.Auto.Core]: http://mstksg.github.io/auto/Control-Auto-Core.html-[mkAutoM]: http://mstksg.github.io/auto/Control-Auto-Core.html#v:mkAutoM+