varying: Automaton based varying values, event streams and tweening.

[ control, frp, library, mit, program ] [ Propose Tags ]

Varying is another FRP or LSP library aimed at providing a simple way to describe discrete or continuously varying values. It is capable of tweening out of the box and provides a small, well documented API.


[Skip to Readme]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1.0.0, 0.1.0.1, 0.1.0.2, 0.1.0.3, 0.1.1.0, 0.1.1.1, 0.1.1.2, 0.1.2.0, 0.1.3.0, 0.1.4.0, 0.1.5.0, 0.2.0.0, 0.3.0.0, 0.3.0.1, 0.4.0.0, 0.5.0.0, 0.5.0.2, 0.5.0.3, 0.6.0.0, 0.7.0.0, 0.7.0.1, 0.7.0.2, 0.7.0.3, 0.7.1.0, 0.7.1.1, 0.8.0.0, 0.8.1.0 (info)
Dependencies base (>=4.8 && <4.9), time (>=1.5 && <1.6) [details]
License MIT
Author Schell Scivally
Maintainer schell.scivally@synapsegroup.com
Category Control
Home page https://github.com/schell/varying
Source repo head: git clone https://github.com/schell/varying.git
Uploaded by SchellScivally at 2015-07-30T20:39:25Z
Distributions LTSHaskell:0.8.1.0, NixOS:0.8.1.0, Stackage:0.8.1.0
Reverse Dependencies 2 direct, 1 indirect [details]
Executables varying-example
Downloads 15753 total (68 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for varying-0.1.0.3

[back to package description]

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 and 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

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