bearriver 0.14.8 → 0.14.9
raw patch · 3 files changed
+104/−5 lines, 3 filesdep ~dunaidep ~transformersPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: dunai, transformers
API changes (from Hackage documentation)
- FRP.BearRiver.Hybrid: mapEventS :: Monad m => SF m a b -> SF m (Event a) (Event b)
- FRP.Yampa: mapEventS :: Monad m => SF m a b -> SF m (Event a) (Event b)
+ FRP.BearRiver.Hybrid: accum :: Monad m => a -> SF m (Event (a -> a)) (Event a)
+ FRP.BearRiver.Hybrid: accumFilter :: Monad m => (c -> a -> (c, Maybe b)) -> c -> SF m (Event a) (Event b)
+ FRP.BearRiver.Hybrid: accumHold :: Monad m => a -> SF m (Event (a -> a)) a
+ FRP.BearRiver.Hybrid: dAccumHold :: Monad m => a -> SF m (Event (a -> a)) a
+ FRP.BearRiver.Hybrid: dAccumHoldBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) b
+ FRP.BearRiver.Hybrid: dHold :: Monad m => a -> SF m (Event a) a
+ FRP.BearRiver.Hybrid: dTrackAndHold :: Monad m => a -> SF m (Maybe a) a
+ FRP.BearRiver.Hybrid: trackAndHold :: Monad m => a -> SF m (Maybe a) a
+ FRP.Yampa: accum :: Monad m => a -> SF m (Event (a -> a)) (Event a)
+ FRP.Yampa: accumFilter :: Monad m => (c -> a -> (c, Maybe b)) -> c -> SF m (Event a) (Event b)
+ FRP.Yampa: accumHold :: Monad m => a -> SF m (Event (a -> a)) a
+ FRP.Yampa: dAccumHold :: Monad m => a -> SF m (Event (a -> a)) a
+ FRP.Yampa: dAccumHoldBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) b
+ FRP.Yampa: dHold :: Monad m => a -> SF m (Event a) a
+ FRP.Yampa: dTrackAndHold :: Monad m => a -> SF m (Maybe a) a
+ FRP.Yampa: trackAndHold :: Monad m => a -> SF m (Maybe a) a
Files
- CHANGELOG +4/−0
- bearriver.cabal +3/−3
- src/FRP/BearRiver/Hybrid.hs +97/−2
CHANGELOG view
@@ -1,3 +1,7 @@+2024-06-21 Ivan Perez <ivan.perez@keera.co.uk>+ * Version bump (0.14.9) (#420).+ * Offer all definitions from FRP.Yampa.Hybrid (#419).+ 2024-04-23 Ivan Perez <ivan.perez@keera.co.uk> * Version bump (0.14.8) (#411). * Offer all definitions from FRP.Yampa.Loop (#407).
bearriver.cabal view
@@ -30,7 +30,7 @@ build-type: Simple name: bearriver-version: 0.14.8+version: 0.14.9 author: Ivan Perez, Manuel Bärenz maintainer: ivan.perez@keera.co.uk homepage: https://github.com/ivanperez-keera/dunai@@ -99,11 +99,11 @@ build-depends: base >= 4.6 && <5 , deepseq >= 1.3.0.0 && < 1.6- , dunai >= 0.6.0 && < 0.13+ , dunai >= 0.6.0 && < 0.14 , MonadRandom >= 0.2 && < 0.7 , mtl >= 2.1.2 && < 2.3 , simple-affine-space >= 0.1 && < 0.3- , transformers >= 0.3 && < 0.6+ , transformers >= 0.3 && < 0.7 default-language: Haskell2010
src/FRP/BearRiver/Hybrid.hs view
@@ -6,16 +6,34 @@ -- Maintainer : ivan.perez@keera.co.uk -- -- Discrete to continuous-time signal functions.-module FRP.BearRiver.Hybrid where+module FRP.BearRiver.Hybrid+ (+ -- * Wave-form generation+ hold+ , dHold+ , trackAndHold+ , dTrackAndHold + -- * Accumulators+ , accum+ , accumHold+ , dAccumHold+ , accumBy+ , accumHoldBy+ , dAccumHoldBy+ , accumFilter+ )+ where+ -- External imports-import Control.Arrow (arr, returnA, (<<<))+import Control.Arrow (arr, returnA, (<<<), (>>>)) -- Internal imports (dunai) import Data.MonadicStreamFunction (accumulateWith, feedback) -- Internal imports (bearriver) import FRP.BearRiver.Arrow (dup)+import FRP.BearRiver.Delays (iPre) import FRP.BearRiver.Event (Event (..), event) import FRP.BearRiver.InternalCore (SF) @@ -36,8 +54,66 @@ hold a = feedback a $ arr $ \(e, a') -> dup (event a' id e) +-- | Zero-order hold with a delay.+--+-- Converts a discrete-time signal into a continuous-time signal, by holding the+-- last value until it changes in the input signal. The given parameter is used+-- for time zero (until the first event occurs in the input signal), so 'dHold'+-- shifts the discrete input by an infinitesimal delay.+--+-- >>> embed (dHold 1) (deltaEncode 0.1 [NoEvent, NoEvent, Event 2, NoEvent, Event 3, NoEvent])+-- [1,1,1,2,2,3]+dHold :: Monad m => a -> SF m (Event a) a+dHold a0 = hold a0 >>> iPre a0++-- | Tracks input signal when available, holding the last value when the input+-- is 'Nothing'.+--+-- This behaves similarly to 'hold', but there is a conceptual difference, as it+-- takes a signal of input @Maybe a@ (for some @a@) and not @Event@.+--+-- >>> embed (trackAndHold 1) (deltaEncode 0.1 [Nothing, Nothing, Just 2, Nothing, Just 3, Nothing])+-- [1,1,2,2,3,3]+trackAndHold :: Monad m => a -> SF m (Maybe a) a+trackAndHold aInit = arr (maybe NoEvent Event) >>> hold aInit++-- | Tracks input signal when available, holding the last value when the input+-- is 'Nothing', with a delay.+--+-- This behaves similarly to 'hold', but there is a conceptual difference, as it+-- takes a signal of input @Maybe a@ (for some @a@) and not @Event@.+--+-- >>> embed (dTrackAndHold 1) (deltaEncode 0.1 [Nothing, Nothing, Just 2, Nothing, Just 3, Nothing])+-- [1,1,1,2,2,3]+dTrackAndHold :: Monad m => a -> SF m (Maybe a) a+dTrackAndHold aInit = trackAndHold aInit >>> iPre aInit+ -- ** Accumulators +-- | Given an initial value in an accumulator, it returns a signal function that+-- processes an event carrying transformation functions. Every time an 'Event'+-- is received, the function inside it is applied to the accumulator, whose new+-- value is outputted in an 'Event'.+accum :: Monad m => a -> SF m (Event (a -> a)) (Event a)+accum aInit = feedback aInit $ arr $ \(f, a) -> case f of+ NoEvent -> (NoEvent, a)+ Event f' -> let a' = f' a+ in (Event a', a')++-- | Zero-order hold accumulator (always produces the last outputted value until+-- an event arrives).+accumHold :: Monad m => a -> SF m (Event (a -> a)) a+accumHold aInit = feedback aInit $ arr $ \(f, a) -> case f of+ NoEvent -> (a, a)+ Event f' -> let a' = f' a+ in (a', a')++-- | Zero-order hold accumulator with delayed initialization (always produces+-- the last outputted value until an event arrives, but the very initial output+-- is always the given accumulator).+dAccumHold :: Monad m => a -> SF m (Event (a -> a)) a+dAccumHold aInit = accumHold aInit >>> iPre aInit+ -- | Accumulator parameterized by the accumulation function. accumBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) (Event b) accumBy f b = mapEventS $ accumulateWith (flip f) b@@ -47,6 +123,25 @@ accumHoldBy f b = feedback b $ arr $ \(a, b') -> let b'' = event b' (f b') a in (b'', b'')++-- | Zero-order hold accumulator parameterized by the accumulation function with+-- delayed initialization (initial output sample is always the given+-- accumulator).+dAccumHoldBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) b+dAccumHoldBy f aInit = accumHoldBy f aInit >>> iPre aInit++-- | Accumulator parameterized by the accumulator function with filtering,+-- possibly discarding some of the input events based on whether the second+-- component of the result of applying the accumulation function is 'Nothing' or+-- 'Just' x for some x.+accumFilter :: Monad m+ => (c -> a -> (c, Maybe b)) -> c -> SF m (Event a) (Event b)+accumFilter g cInit = feedback cInit $ arr $ \(a, c) ->+ case a of+ NoEvent -> (NoEvent, c)+ Event a' -> case g c a' of+ (c', Nothing) -> (NoEvent, c')+ (c', Just b) -> (Event b, c') -- * Events