Copyright | (c) 2015 Schell Scivally |
---|---|
License | MIT |
Maintainer | Schell Scivally <schell.scivally@synapsegroup.com> |
Safe Haskell | None |
Language | Haskell2010 |
Values that change over a given domain.
Varying values take some input (the domain ~ time, place, etc) and produce
a sample and a new varying value. 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.
- data Var m b c = Var {}
- var :: Applicative a => (b -> c) -> Var a b c
- varM :: Monad m => (a -> m b) -> Var m a b
- (<~) :: Monad m => Var m b c -> Var m a b -> Var m a c
- (~>) :: Monad m => Var m a b -> Var m b c -> Var m a c
- delay :: Monad m => b -> Var m a b -> Var m a b
- accumulate :: Monad m => (c -> b -> c) -> c -> Var m b c
- evalVar :: Functor m => Var m a b -> a -> m b
- execVar :: Functor m => Var m a b -> a -> m (Var m a b)
- loopVar :: Monad m => a -> Var m a a -> m a
- loopVar_ :: (Functor m, Monad m) => Var m () a -> m ()
- whileVar :: Monad m => (a -> Bool) -> a -> Var m a a -> m a
- whileVar_ :: Monad m => (a -> Bool) -> Var m () a -> m a
- testVar :: (Read a, Show b) => Var IO a b -> IO ()
- testVar_ :: Show b => Var IO () b -> IO ()
- testWhile_ :: Show a => (a -> Bool) -> Var IO () a -> IO ()
- vtrace :: (Applicative a, Show b) => Var a b b
- vstrace :: (Applicative a, Show b) => String -> Var a b b
- vftrace :: Applicative a => (b -> String) -> Var a b b
Documentation
The vessel of a varying value. A Var
is a structure that contains a value
that changes over some input. That input could be time (Float, Double, etc)
or Event
s or Char
- whatever.
It's a kind of Mealy machine (an automaton) with effects.
(Applicative m, Monad m) => Category * (Var 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' ( |
(Applicative m, Monad m) => Arrow (Var m) Source |
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 (Var m b) Source | You can transform the sample value of any fmap (*3) $ accumulate (+) 0 Will sum input values and then multiply the sum by 3. |
(Applicative m, Monad m) => Applicative (Var m a) Source |
(,) <$> pure True <*> var "Applicative" |
(Applicative m, Monad m, Floating b) => Floating (Var m a b) Source |
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 (Var m a b) Source |
let v = 2.5 ~> accumulate (+) 0 which will add 2.5 each step. |
(Applicative m, Monad m, Num b) => Num (Var m a b) Source |
let v = 1 ~> accumulate (+) 0 which will sum the natural numbers. |
(Applicative m, Monad m, Monoid b) => Monoid (Var m a b) Source |
let v = var (const "Hello ") `mappend` var (const "World!") |
Creating varying values
You can create a pure varying value by lifting a function (a -> b)
with var
:
addsOne :: Monad m => Var m Int Int addsOne = var (+1)
var
is also equivalent to arr
.
You can create a monadic varying value by lifting a monadic computation
(a -> m b)
using varM
:
getsFile :: Var 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 varying values are stepped and sampled:
delay :: Monad m => b -> Var m a b -> Var m a b delay b v = Var $ a -> return (b, go a v) where go a v' = Var $ a' -> do (b', v'') <- runVar v' a return (b', go a' v'')
var :: Applicative a => (b -> c) -> Var a b c Source
Lift a pure computation into a Var
.
Composing varying values
You can compose varying values together using ~>
and <~
. The "right plug"
(~>
) takes the output from a varying value on the left and "plugs" it
into the input of the varying value on the right. The "left plug" does
the same thing only in the opposite direction. This allows you to write
varying values that read naturally.
(<~) :: Monad m => Var m b c -> Var m a b -> Var m a c infixl 1 Source
Same as ~>
with flipped parameters.
Adjusting and accumulating
accumulate :: Monad m => (c -> b -> c) -> c -> Var m b c Source
Accumulates input values using a folding function and yields that accumulated value each sample.
Sampling varying values (running, entry points)
The easiest way to sample a Var
is to run it in the desired monad with
runVar
. This will give you a sample value and a new Var
bundled up in a
tuple:
do (sample, v') <- runVar v inputValue
Much like Control.Monad.State there are other entry points for running
varying values like evalVar
, execVar
. There are also extra control
structures like loopVar
and whileVar
and more.
loopVar :: Monad m => a -> Var m a a -> m a Source
Loop over a Var
that produces its own next input value.
loopVar_ :: (Functor m, Monad m) => Var m () a -> m () Source
Loop over a Var
that takes no input value.
:: Monad m | |
=> (a -> Bool) | The predicate to evaluate samples. |
-> a | The initial input/sample value. |
-> Var m a a | The |
-> m a | The last sample |
Iterate a Var
that produces its own next input value until the given
predicate fails.
whileVar_ :: Monad m => (a -> Bool) -> Var m () a -> m a Source
Iterate a Var
that requires no input until the given predicate fails.
Testing varying values
vtrace :: (Applicative a, Show b) => Var a b b Source