auto-0.4.1.0: Denotative, locally stateful programming DSL & platform

Copyright(c) Justin Le 2015
LicenseMIT
Maintainerjustin@jle.im
Stabilityunstable
Portabilityportable
Safe HaskellNone
LanguageHaskell2010

Control.Auto.Generate

Contents

Description

This module contains various Autos that act as "producing" streams; they all ignore their input streams and produce output streams through a pure or monadic process.

Synopsis

From lists

fromList Source

Arguments

:: Serialize b 
=> [b]

list to output element-by-element

-> Interval m a b 

An Interval 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!

fromLongList can be used for longer lists or infinite lists; or, if your list can be boild down to an unfoldr, you can use unfold.

  • Storing: O(n) time and space on length of remaining list
  • Loading: O(1) time in the number of times the Auto has been stepped + O(n) time in the length of the remaining list.

fromList_ Source

Arguments

:: [b]

list to output element-by-element

-> Interval m a b 

The non-resuming/non-serializing version of fromList.

fromLongList Source

Arguments

:: [b]

list to output element-by-element

-> Interval m a b 

A version of fromList 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 O(n) on the number of times the Auto had been stepped at the time of saving. This is because it has to drop the n first elements in the list, to "resume" to the proper position.

  • Storing: O(1) time and space on the length of the remaining list
  • Loading: O(n) time on the number of times the Auto has been stepped, maxing out at O(n) on the length of the entire input list.

Constant producers

Here we have the "constant producers": Autos whose output is always the same value, or the result of executing the same monadic action.

pure   :: Monad m => b   -> Auto m a b
effect :: Monad m => m b -> Auto m a b

pure always outputs the same value, ignoring its input, and effect always outputs the result of executing the same monadic action, ignoring its input.

pure :: Applicative f => forall a. a -> f a

Lift a value.

effect Source

Arguments

:: m b

monadic action to contually execute.

-> 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" pure:

pure   :: b   -> Auto m a b
effect :: m b -> Auto m a b

The output of pure is always the same, and the output of effect is always the result of the same monadic action. Both ignore their inputs.

Fun times when the underling Monad is, for instance, Reader.

>>> let a = effect ask    :: Auto (Reader b) a b
>>> let r = evalAuto a () :: Reader b b
>>> runReader r "hello"
"hello"
>>> runReader r 100
100

If your underling monad has effects (IO, State, Maybe, Writer, etc.), then it might be fun to take advantage of *> from Control.Applicative to "tack on" an effect to a normal Auto:

>>> let a = effect (modify (+1)) *> sumFrom 0 :: Auto (State Int) Int Int
>>> let st = streamAuto a [1..10]
>>> let (ys, s') = runState st 0
>>> ys
[1,3,6,10,15,21,28,36,45,55]
>>> s'
10

Out Auto a behaves exactly like sumFrom 0, except at each step, it also increments the underlying/global state by one. It is sumFrom 0 with an "attached effect".

From functions

Iterating

iterator Source

Arguments

:: Serialize b 
=> (b -> b)

iterating function

-> b

starting value and initial output

-> Auto m a b 

Analogous to iterate from Prelude. 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.

>>> take 10 . streamAuto' (iterator (*2) 1) $ repeat ()
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]

iterator_ Source

Arguments

:: (b -> b)

iterating function

-> b

starting value and initial output

-> Auto m a b 

The non-resuming/non-serializing version of iterator.

iteratorM Source

Arguments

:: (Serialize b, Monad m) 
=> (b -> m b)

(monadic) iterating function

-> b

starting value and initial output

-> Auto m a b 

Like iterator, but with a monadic function.

iteratorM_ Source

Arguments

:: Monad m 
=> (b -> m b)

(monadic) iterating function

-> b

starting value and initial output

-> Auto m a b 

The non-resuming/non-serializing version of iteratorM.

Enumerating results of a function

discreteF Source

Arguments

:: (Enum c, Serialize c) 
=> (c -> b)

discrete function

-> c

initial input

-> Auto m a b 

Given a function from discrete enumerable inputs, iterates through all of the results of that function.

>>> take 10 . streamAuto' (discreteF (^2) 0) $ repeat ()
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

discreteF_ Source

Arguments

:: Enum c 
=> (c -> b)

discrete function

-> c

initial input

-> Auto m a b 

The non-resuming/non-serializing version of discreteF.

Unfolding

"Iterating with state".

unfold Source

Arguments

:: Serialize c 
=> (c -> Maybe (b, c))

unfolding function

-> c

initial accumulator

-> Interval m a b 

Analogous to unfoldr from Prelude. Creates an Interval (that ignores its input) by maintaining an internal accumulator of type c and, at every step, applying to the unfolding function to the accumulator. If the result is Nothing, then the Interval will turn "off" forever (output Nothing forever); if the result is Just (y, acc), then it will output y and store acc as the new accumulator.

Given an initial accumulator.

>>> let countFromTil n m = flip unfold n $ \i -> if i <= m
                                                   then Just (i, i+1)
                                                   else Nothing
>>> take 8 . streamAuto' (countFromTil 5 10) $ repeat ()
[Just 5, Just 6, Just 7, Just 8, Just 9, Just 10, Nothing, Nothing]

unfold f c0 behaves like overList (unfoldr f c0).

unfold_ Source

Arguments

:: (c -> Maybe (b, c))

unfolding function

-> c

initial accumulator

-> Interval m a b 

The non-resuming & non-serializing version of unfold.

unfoldM Source

Arguments

:: (Serialize c, Monad m) 
=> (c -> m (Maybe (b, c)))

unfolding function

-> c

initial accumulator

-> Interval m a b 

Like unfold, but the unfolding function is monadic.

unfoldM_ Source

Arguments

:: Monad m 
=> (c -> m (Maybe (b, c)))

unfolding function

-> c

initial accumulator

-> Interval m a b 

The non-resuming & non-serializing version of unfoldM.

Enumerating

enumFromA Source

Arguments

:: (Serialize b, Enum b) 
=> b

initial value

-> Auto m a b 

Continually enumerate from the starting value, using succ.

enumFromA_ Source

Arguments

:: Enum b 
=> b

initial value

-> Auto m a b 

The non-serializing/non-resuming version of enumFromA.