-- | -- Module : FRP.Yampa.Scan -- Copyright : (c) Ivan Perez, 2014-2023 -- (c) George Giorgidze, 2007-2012 -- (c) Henrik Nilsson, 2005-2006 -- (c) Antony Courtney and Henrik Nilsson, Yale University, 2003-2004 -- License : BSD-style (see the LICENSE file in the distribution) -- -- Maintainer : ivan.perez@keera.co.uk -- Stability : provisional -- Portability : non-portable (GHC extensions) -- -- Simple, stateful signal processing. -- -- Scanning implements elementary, step-based accumulating over signal functions -- by means of an auxiliary function applied to each input and to an -- accumulator. For comparison with other FRP libraries and with stream -- processing abstractions, think of fold. module FRP.BearRiver.Scan ( sscan , sscanPrim ) where -- Internal imports (dunai) import Data.MonadicStreamFunction.InternalCore (MSF (..)) -- Internal imports import FRP.BearRiver.InternalCore (SF (..)) -- * Simple, stateful signal processing -- | Applies a function point-wise, using the last output as next input. This -- creates a well-formed loop based on a pure, auxiliary function. sscan :: Monad m => (b -> a -> b) -> b -> SF m a b sscan f bInit = sscanPrim f' bInit bInit where f' b a = Just (b', b') where b' = f b a -- | Generic version of 'sscan', in which the auxiliary function produces an -- internal accumulator and an "held" output. -- -- Applies a function point-wise, using the last known 'Just' output to form the -- output, and next input accumulator. If the output is 'Nothing', the last -- known accumulators are used. This creates a well-formed loop based on a pure, -- auxiliary function. sscanPrim :: Monad m => (c -> a -> Maybe (c, b)) -> c -> b -> SF m a b sscanPrim f cInit bInit = MSF $ \a -> do let o = f cInit a case o of Nothing -> return (bInit, sscanPrim f cInit bInit) Just (c', b') -> return (b', sscanPrim f c' b')