rhine-0.1.0.0: src/FRP/Rhine/ResamplingBuffer.hs
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
module FRP.Rhine.ResamplingBuffer where
-- rhine
import FRP.Rhine.Clock
-- base
import Control.Arrow (second)
-- A quick note on naming conventions, to whoever cares:
-- . Call a single clock cl.
-- . Call several clocks cl1, cl2 etc. in most situations.
-- . Call it cla, clb etc. when they are Leftmost or Rightmost clocks,
-- i.e. associated to particular boundary types a, b etc.,
{- | A stateful buffer from which one may 'get' a value,
or to which one may 'put' a value,
depending on the clocks.
`ResamplingBuffer`s can be clock-polymorphic,
or specific to certain clocks.
* 'm': Monad in which the 'ResamplingBuffer' may have side effects
* 'cla': The clock at which data enters the buffer
* 'clb': The clock at which data leaves the buffer
* 'a': The input type
* 'b': The output type
-}
data ResamplingBuffer m cla clb a b = ResamplingBuffer
{ put
:: TimeInfo cla
-> a
-> m ( ResamplingBuffer m cla clb a b)
-- ^ Store one input value of type 'a' at a given time stamp,
-- and return a continuation.
, get
:: TimeInfo clb
-> m (b, ResamplingBuffer m cla clb a b)
-- ^ Retrieve one output value of type 'b' at a given time stamp,
-- and a continuation.
}
-- | Hoist a 'ResamplingBuffer' along a monad morphism.
hoistResamplingBuffer
:: (Monad m1, Monad m2)
=> (forall c. m1 c -> m2 c)
-> ResamplingBuffer m1 cla clb a b
-> ResamplingBuffer m2 cla clb a b
hoistResamplingBuffer hoist ResamplingBuffer {..} = ResamplingBuffer
{ put = (((hoistResamplingBuffer hoist <$>) . hoist) .) . put
, get = (second (hoistResamplingBuffer hoist) <$>) . hoist . get
}