module FRP.Rhine.SyncSF where
import Control.Arrow
import qualified Control.Category (id)
import Control.Monad.Trans.Reader
( ReaderT, ask, asks, mapReaderT, withReaderT)
import Data.MonadicStreamFunction
(MSF, liftMSFPurer, liftMSFTrans, arrM, arrM_, sumFrom, delay, feedback)
import Data.VectorSpace
import FRP.Rhine.Clock
import FRP.Rhine.TimeDomain
type SyncSF m cl a b = MSF (ReaderT (TimeInfo cl) m) a b
type Behaviour m td a = forall cl. td ~ TimeDomainOf cl => SyncSF m cl () a
type Behavior m td a = Behaviour m td a
hoistSyncSF
:: (Monad m1, Monad m2)
=> (forall c. m1 c -> m2 c)
-> SyncSF m1 cl a b
-> SyncSF m2 (HoistClock m1 m2 cl) a b
hoistSyncSF hoist = liftMSFPurer $ withReaderT (retag id) . mapReaderT hoist
timeless :: Monad m => MSF m a b -> SyncSF m cl a b
timeless = liftMSFTrans
arrMSync :: Monad m => (a -> m b) -> SyncSF m cl a b
arrMSync = timeless . arrM
arrMSync_ :: Monad m => m b -> SyncSF m cl a b
arrMSync_ = timeless . arrM_
timeInfo :: Monad m => SyncSF m cl a (TimeInfo cl)
timeInfo = arrM_ ask
timeInfoOf :: Monad m => (TimeInfo cl -> b) -> SyncSF m cl a b
timeInfoOf f = arrM_ $ asks f
infixr 4 >->
(>->) :: Monad m
=> SyncSF m cl a b
-> SyncSF m cl b c
-> SyncSF m cl a c
(>->) = (>>>)
infixl 4 <-<
(<-<) :: Monad m
=> SyncSF m cl b c
-> SyncSF m cl a b
-> SyncSF m cl a c
(<-<) = (<<<)
arr_ :: Arrow a => b -> a c b
arr_ = arr . const
syncId :: Monad m => SyncSF m cl a a
syncId = Control.Category.id
integralFrom
:: ( Monad m, VectorSpace v
, Groundfield v ~ Diff (TimeDomainOf cl))
=> v -> SyncSF m cl v v
integralFrom v0 = proc v -> do
_sinceTick <- timeInfoOf sinceTick -< ()
sumFrom v0 -< _sinceTick *^ v
integral
:: ( Monad m, VectorSpace v
, Groundfield v ~ Diff (TimeDomainOf cl))
=> SyncSF m cl v v
integral = integralFrom zeroVector
derivativeFrom
:: ( Monad m, VectorSpace v
, Groundfield v ~ Diff (TimeDomainOf cl))
=> v -> SyncSF m cl v v
derivativeFrom v0 = proc v -> do
vLast <- delay v0 -< v
TimeInfo {..} <- timeInfo -< ()
returnA -< (v ^-^ vLast) ^/ sinceTick
derivative
:: ( Monad m, VectorSpace v
, Groundfield v ~ Diff (TimeDomainOf cl))
=> SyncSF m cl v v
derivative = derivativeFrom zeroVector
averageFrom
:: ( Monad m, VectorSpace v
, Groundfield v ~ Diff (TimeDomainOf cl))
=> v
-> Diff (TimeDomainOf cl)
-> SyncSF m cl v v
averageFrom v0 t = feedback v0 $ proc (v, vAvg) -> do
TimeInfo {..} <- timeInfo -< ()
let vAvg' = (v ^* sinceTick ^+^ vAvg ^* t) ^/ (sinceTick + t)
returnA -< (vAvg', vAvg')
average
:: ( Monad m, VectorSpace v
, Groundfield v ~ Diff (TimeDomainOf cl))
=> Diff (TimeDomainOf cl)
-> SyncSF m cl v v
average = averageFrom zeroVector