varying-0.4.0.0: FRP through value streams and monadic splines.

Copyright(c) 2015 Schell Scivally
LicenseMIT
MaintainerSchell Scivally <schell.scivally@synapsegroup.com>
Safe HaskellNone
LanguageHaskell2010

Control.Varying.Core

Contents

Description

Value streams represent values that change over a given domain.

A stream takes some input (the domain e.g. time, place, etc) and when sampled using runVarT - produces a value and a new value stream. This pattern is known as an automaton. varying uses this pattern as its base type with the additon of a monadic computation to create locally stateful signals that change over some domain.

Synopsis

Documentation

type Var a b = VarT Identity a b Source

A value stream parameterized with Identity that takes input of type a and gives output of type b. This is the pure, effect-free version of VarT.

data VarT m a b Source

A value stream is a structure that contains a value that changes over some input. It's a kind of Mealy machine (an automaton) with effects. Using runVarT with an input value of type a yields a "step", which is a value of type b and a new VarT for yielding the next value.

Constructors

VarT 

Fields

runVarT :: a -> m (b, VarT m a b)

Given an input value, return a computation that effectfully produces an output value and a new stream for producing the next sample.

Instances

(Applicative m, Monad m) => Category * (VarT m) Source

A very simple category instance.

  id = var id
  f . g = g ~> f

or

 f . g = f <~ g

It is preferable for consistency (and readability) to use 'plug left' (<~) and 'plug right' (~>) instead of (.) where possible.

(Applicative m, Monad m) => Arrow (VarT m) Source

Streams are arrows, which means you can use proc notation.

v = proc a -> do
      ex <- intEventVar -< ()
      ey <- anotherIntEventVar -< ()
      returnA -< (+) <$> ex <*> ey

which is equivalent to

 v = (\ex ey -> (+) <$> ex <*> ey) <$> intEventVar <*> anotherIntEventVar
(Applicative m, Monad m) => Functor (VarT m b) Source

You can transform the sample value of any stream:

 fmap (*3) $ accumulate (+) 0

Will sum input values and then multiply the sum by 3.

(Applicative m, Monad m) => Applicative (VarT m a) Source

Streams are applicative.

 (,) <$> pure True <*> var "Applicative"
(Applicative m, Monad m, Floating b) => Floating (VarT m a b) Source

Streams can be written as floats.

 let v = pi ~> accumulate (*) 0.0

which will attempt (and succeed) to multiply pi by zero every step.

(Applicative m, Monad m, Fractional b) => Fractional (VarT m a b) Source

Streams can be written as fractionals.

 let v = 2.5 ~> accumulate (+) 0

which will add 2.5 each step.

(Applicative m, Monad m, Num b) => Num (VarT m a b) Source

Streams can be written as numbers.

 let v = 1 ~> accumulate (+) 0

which will sum the natural numbers.

(Applicative m, Monad m, Monoid b) => Monoid (VarT m a b) Source

Streams can be monoids

let v = var (const "Hello ") `mappend` var (const "World!")

Creating value streams

You can create a pure value stream by lifting a function (a -> b) with var:

addsOne :: Monad m => VarT m Int Int
addsOne = var (+1)

var is equivalent to arr.

You can create a monadic value stream by lifting a monadic computation (a -> m b) using varM:

getsFile :: VarT IO FilePath String
getsFile = varM readFile

You can create either with the raw constructor. You can also create your own combinators using the raw constructor, as it allows you full control over how value streams are stepped and sampled:

delay :: Monad m => b -> VarT m a b -> VarT m a b
delay b v = VarT $ a -> return (b, go a v)
    where go a v' = VarT $ a' -> do (b', v'') <- runVarT v' a
                                    return (b', go a' v'')

var :: Applicative m => (a -> b) -> VarT m a b Source

Lift a pure computation into a stream.

varM :: Monad m => (a -> m b) -> VarT m a b Source

Lift a monadic computation into a stream.

mkState Source

Arguments

:: Monad m 
=> (a -> s -> (b, s))

state transformer

-> s

intial state

-> VarT m a b 

Create a stream from a state transformer.

Composing value streams

You can compose value streams together using ~> and <~. The "right plug" (~>) takes the output from a value stream on the left and "plugs" it into the input of the value stream on the right. The "left plug" does the same thing in the opposite direction. This allows you to write value streams that read naturally.

(<~) :: Monad m => VarT m b c -> VarT m a b -> VarT m a c infixl 1 Source

Same as ~> with flipped parameters.

(~>) :: Monad m => VarT m a b -> VarT m b c -> VarT m a c infixr 1 Source

Connects two streams by chaining the first's output into the input of the second. This is the defacto stream composition method and in fact . is an alias of <~, which is just ~> flipped.

Adjusting and accumulating

delay :: Monad m => b -> VarT m a b -> VarT m a b Source

Delays the given stream by one sample using the argument as the first sample. This enables the programmer to create streams that depend on themselves for values. For example:

let v = 1 + delay 0 v in testVar_ v

accumulate :: Monad m => (c -> b -> c) -> c -> VarT m b c Source

Accumulates input values using a folding function and yields that accumulated value each sample.

Sampling value streams (running and other entry points)

The easiest way to sample a stream is to run it in the desired monad with runVarT. This will produce a sample value and a new stream.

do (sample, v') <- runVarT v inputValue

Much like Control.Monad.State there are other entry points for running value streams like evalVar, execVar. There are also extra control structures such as loopVar and whileVar.

evalVar :: Functor m => VarT m a b -> a -> m b Source

Iterate a stream once and return the sample value.

execVar :: Functor m => VarT m a b -> a -> m (VarT m a b) Source

Iterate a stream once and return the next stream.

loopVar :: Monad m => a -> VarT m a a -> m a Source

Loop over a stream that produces its own next input value.

loopVar_ :: (Functor m, Monad m) => VarT m () a -> m () Source

Loop over a stream that takes no input value.

whileVar Source

Arguments

:: Monad m 
=> (a -> Bool)

The predicate to evaluate samples.

-> a

The initial input/sample value.

-> VarT m a a

The stream to iterate

-> m a

The last sample

Iterate a stream that produces its own next input value until the given predicate fails.

whileVar_ :: Monad m => (a -> Bool) -> VarT m () a -> m a Source

Iterate a stream that requires no input until the given predicate fails.

scanVar :: (Applicative m, Monad m) => VarT m a b -> [a] -> m [b] Source

Run the stream over the input values, gathering the output values in a list.

stepMany :: (Monad m, Functor m, Monoid a) => [a] -> VarT m a b -> m (b, VarT m a b) Source

Iterate a stream using a list of input until all input is consumed and output the result.

Testing value streams

testVar :: (Read a, Show b) => VarT IO a b -> IO () Source

A utility function for testing streams that require input. The input must have a Read instance. Use this in GHCI to step through your streams by typing the input and hitting return.

testVar_ :: Show b => VarT IO () b -> IO () Source

A utility function for testing streams that don't require input. Use this in GHCI to step through your streams using the return key.

testWhile_ :: Show a => (a -> Bool) -> VarT IO () a -> IO () Source

A utility function for testing streams that don't require input. Runs a stream printing each sample until the given predicate fails.

vtrace :: (Applicative a, Show b) => VarT a b b Source

Trace the sample value of a stream and pass it along as output. This is very useful for debugging graphs of streams.

vstrace :: (Applicative a, Show b) => String -> VarT a b b Source

Trace the sample value of a stream with a prefix and pass the sample along as output. This is very useful for debugging graphs of streams.

vftrace :: Applicative a => (b -> String) -> VarT a b b Source

Trace the sample value after being run through a "show" function. This is very useful for debugging graphs of streams.