{- |
Collect and process all incoming values statefully and with time stamps.
-}

{-# LANGUAGE RecordWildCards #-}
module FRP.Rhine.ResamplingBuffer.MSF where

-- dunai
import Data.MonadicStreamFunction.InternalCore

-- rhine
import FRP.Rhine.ResamplingBuffer

-- | Given a monadic stream function that accepts
--   a varying number of inputs (a list),
--   a `ResamplingBuffer` can be formed
--   that collects all input in a timestamped list.
msfBuffer
  :: Monad m
  => MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
  -- ^ The monadic stream function that consumes
  --   a single time stamp for the moment when an output value is required,
  --   and a list of timestamped inputs,
  --   and outputs a single value.
  --   The list will contain the /newest/ element in the head.
  -> ResamplingBuffer m cl1 cl2 a b
msfBuffer :: MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
-> ResamplingBuffer m cl1 cl2 a b
msfBuffer = [(TimeInfo cl1, a)]
-> MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
-> ResamplingBuffer m cl1 cl2 a b
forall (m :: Type -> Type) cl1 a cl2 b.
Monad m =>
[(TimeInfo cl1, a)]
-> MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
-> ResamplingBuffer m cl1 cl2 a b
msfBuffer' []
  where
    msfBuffer'
      :: Monad m
      => [(TimeInfo cl1, a)]
      -> MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
      -> ResamplingBuffer m cl1 cl2 a b
    msfBuffer' :: [(TimeInfo cl1, a)]
-> MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
-> ResamplingBuffer m cl1 cl2 a b
msfBuffer' [(TimeInfo cl1, a)]
as MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
msf = ResamplingBuffer :: forall (m :: Type -> Type) cla clb a b.
(TimeInfo cla -> a -> m (ResamplingBuffer m cla clb a b))
-> (TimeInfo clb -> m (b, ResamplingBuffer m cla clb a b))
-> ResamplingBuffer m cla clb a b
ResamplingBuffer {TimeInfo cl1 -> a -> m (ResamplingBuffer m cl1 cl2 a b)
TimeInfo cl2 -> m (b, ResamplingBuffer m cl1 cl2 a b)
forall (m :: Type -> Type).
Monad m =>
TimeInfo cl1 -> a -> m (ResamplingBuffer m cl1 cl2 a b)
get :: TimeInfo cl2 -> m (b, ResamplingBuffer m cl1 cl2 a b)
put :: TimeInfo cl1 -> a -> m (ResamplingBuffer m cl1 cl2 a b)
get :: TimeInfo cl2 -> m (b, ResamplingBuffer m cl1 cl2 a b)
put :: forall (m :: Type -> Type).
Monad m =>
TimeInfo cl1 -> a -> m (ResamplingBuffer m cl1 cl2 a b)
..}
      where
        put :: TimeInfo cl1 -> a -> m (ResamplingBuffer m cl1 cl2 a b)
put TimeInfo cl1
ti1 a
a = ResamplingBuffer m cl1 cl2 a b
-> m (ResamplingBuffer m cl1 cl2 a b)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (ResamplingBuffer m cl1 cl2 a b
 -> m (ResamplingBuffer m cl1 cl2 a b))
-> ResamplingBuffer m cl1 cl2 a b
-> m (ResamplingBuffer m cl1 cl2 a b)
forall a b. (a -> b) -> a -> b
$ [(TimeInfo cl1, a)]
-> MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
-> ResamplingBuffer m cl1 cl2 a b
forall (m :: Type -> Type) cl1 a cl2 b.
Monad m =>
[(TimeInfo cl1, a)]
-> MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
-> ResamplingBuffer m cl1 cl2 a b
msfBuffer' ((TimeInfo cl1
ti1, a
a) (TimeInfo cl1, a) -> [(TimeInfo cl1, a)] -> [(TimeInfo cl1, a)]
forall a. a -> [a] -> [a]
: [(TimeInfo cl1, a)]
as) MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
msf
        get :: TimeInfo cl2 -> m (b, ResamplingBuffer m cl1 cl2 a b)
get TimeInfo cl2
ti2   = do
          (b
b, MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
msf') <- MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
-> (TimeInfo cl2, [(TimeInfo cl1, a)])
-> m (b, MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b)
forall (m :: Type -> Type) a b. MSF m a b -> a -> m (b, MSF m a b)
unMSF MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
msf (TimeInfo cl2
ti2, [(TimeInfo cl1, a)]
as)
          (b, ResamplingBuffer m cl1 cl2 a b)
-> m (b, ResamplingBuffer m cl1 cl2 a b)
forall (m :: Type -> Type) a. Monad m => a -> m a
return (b
b, MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
-> ResamplingBuffer m cl1 cl2 a b
forall (m :: Type -> Type) cl2 cl1 a b.
Monad m =>
MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
-> ResamplingBuffer m cl1 cl2 a b
msfBuffer MSF m (TimeInfo cl2, [(TimeInfo cl1, a)]) b
msf')