varying-0.1.1.2: README.md
# varying
[](https://travis-ci.org/schell/varying)
This library provides automaton based varying values useful for both functional
reactive programming (FRP) and locally stateful programming (LSP). It is
influenced by the [netwire](http://hackage.haskell.org/package/netwire) and
[auto](http://hackage.haskell.org/package/auto) packages. Unlike netwire the
concepts of inhibition and time are explicit (through `Control.Varying.Event`
and `Control.Varying.Time`) and the library aims at being minimal and well
documented with a small API.
Depending on your types and values varying can provide discrete or continuous
time semantics.
## Getting started
```haskell
module Main where
import Control.Varying
import Control.Varying.Time as Time -- time is not auto-exported
import Text.Printf
-- | A simple 2d point type.
data Point = Point { x :: Float
, y :: Float
} deriving (Show, Eq)
-- | Our Point value that varies over time continuously in x and y.
backAndForth :: Var IO a Point
backAndForth =
-- Here we use Applicative to construct a varying Point that takes time
-- as an input.
(Point <$> tweenx <*> tweeny)
-- Here we feed the varying Point a time signal using the 'plug left'
-- function. We could similarly use the 'plug right' (~>) function
-- and put the time signal before the Point. This is needed because the
-- tweens take time as an input.
<~ time
-- An exponential tween back and forth from 0 to 100 over 2 seconds.
tweenx :: Monad m => Var m Float Float
tweenx =
-- Tweens only happen for a certain duration and so their sample
-- values have the type (Ord t, Fractional t => Event t). After construction
-- a tween's full type will be
-- (Ord t, Fractional t, Monad m) => Var m t (Event t).
tween easeOutExpo 0 100 1
-- We can chain another tween back to the starting position using
-- `andThenE`, which will sample the first tween until it ends and then
-- switch to sampling the next tween.
`andThenE`
-- Tween back to the starting position.
tween easeOutExpo 100 0 1
-- At this point our resulting sample values will still have the
-- type (Event Float). The tween as a whole will be an event
-- stream. The tween also only runs back and forth once. We'd
-- like the tween to loop forever so that our point cycles back
-- and forth between 0 and 100 indefinitely.
-- We can accomplish this with recursion and the `andThen`
-- combinator, which samples an event stream until it
-- inhibits and then switches to a normal value stream (a
-- varying value). Put succinctly, it disolves our events into
-- values.
`andThen` tweenx
-- A quadratic tween back and forth from 0 to 100 over 2 seconds.
tweeny :: Monad m => Var m Float Float
tweeny =
tween easeOutQuad 0 100 1 `andThenE` tween easeOutQuad 100 0 1 `andThen` tweeny
-- Our time signal.
time :: Var IO a Float
time = deltaUTC
main :: IO ()
main = do
putStrLn "Varying Values"
loop backAndForth
where loop :: Var IO () Point -> IO ()
loop v = do (point, vNext) <- runVar v ()
printf "\nPoint %03.1f %03.1f" (x point) (y point)
loop vNext
```