netwire-1.2.0: FRP/NetWire/Calculus.hs
-- |
-- Module: FRP.NetWire.Calculus
-- Copyright: (c) 2011 Ertugrul Soeylemez
-- License: BSD3
-- Maintainer: Ertugrul Soeylemez <es@ertes.de>
--
-- Calculus functions.
module FRP.NetWire.Calculus
( -- * Calculus over time
derivative,
derivativeFrom,
integral
)
where
import Control.DeepSeq
import Data.VectorSpace
import FRP.NetWire.Wire
-- | Differentiate over time.
--
-- Inhibits at first instant.
derivative :: (Monad m, NFData v, VectorSpace v, Scalar v ~ Double) => Wire m v v
derivative =
mkGen $ \_ y2 ->
return (Left (inhibitEx "Derivative at first instant"),
derivativeFrom y2)
-- | Differentiate over time. The argument is the value before the
-- first instant.
--
-- Never inhibits. Direct feedback.
derivativeFrom ::
forall m v. (Monad m, NFData v, VectorSpace v, Scalar v ~ Double) =>
v -> Wire m v v
derivativeFrom y1 = derivativeFrom' zeroV y1
where
derivativeFrom' :: v -> v -> Wire m v v
derivativeFrom' dy' y1 =
mkGen $ \(wsDTime -> dt) y2 -> do
let dy = (y2 ^-^ y1) ^/ dt
dy' `deepseq` return (Right dy', derivativeFrom' dy y2)
-- | Integrate over time. The argument is the integration constant.
--
-- Never inhibits. Direct feedback.
integral :: (Monad m, NFData v, VectorSpace v, Scalar v ~ Double) => v -> Wire m v v
integral x1 =
mkGen $ \ws dx -> do
let dt = wsDTime ws
x2 = x1 ^+^ dt *^ dx
x1 `deepseq` return (Right x1, integral x2)