{- | Resampling buffers from asynchronous Mealy machines. These are used in many other modules implementing 'ResamplingBuffer's. -} {-# LANGUAGE RecordWildCards #-} module FRP.Rhine.ResamplingBuffer.Timeless where import FRP.Rhine.ResamplingBuffer -- | An asynchronous, effectful Mealy machine description. -- (Input and output do not happen simultaneously.) -- It can be used to create 'ResamplingBuffer's. data AsyncMealy m s a b = AsyncMealy { amPut :: s -> a -> m s -- ^ Given the previous state and an input value, return the new state. , amGet :: s -> m (b, s) -- ^ Given the previous state, return an output value and a new state. } -- | A resampling buffer that is unaware of the time information of the clock, -- and thus clock-polymorphic. -- It is built from an asynchronous Mealy machine description. -- Whenever 'get' is called on @timelessResamplingBuffer machine s@, -- the method 'amGet' is called on @machine@ with state @s@, -- discarding the time stamp. Analogously for 'put'. timelessResamplingBuffer :: Monad m => AsyncMealy m s a b -- The asynchronous Mealy machine from which the buffer is built -> s -- ^ The initial state -> ResamplingBuffer m cl1 cl2 a b timelessResamplingBuffer AsyncMealy {..} = go where go s = let put _ a = go <$> amPut s a get _ = do (b, s') <- amGet s return (b, go s') in ResamplingBuffer {..} -- | A resampling buffer that only accepts and emits units. trivialResamplingBuffer :: Monad m => ResamplingBuffer m cl1 cl2 () () trivialResamplingBuffer = timelessResamplingBuffer AsyncMealy { amPut = const (const (return ())) , amGet = const (return ((), ())) } ()