In reactive-banana <1.0.0, this worked:
-- takes a start value, minimum and maximum value, flag whether counter is
-- cyclic, an increment and decrement event stream and returns a behavior
mkCounter :: (Enum a,Ord a) => a -> Maybe a -> Maybe a -> Bool
-> Event t b -> Event t c -> Behavior t a
mkCounter start minVal maxVal cyclic incE decE = counter
let incF curr | isNothing maxVal = succ
| Just maxv <- maxVal, curr<maxv = succ
| Just maxv <- maxVal, Just minv <- minVal, cyclic = const minv
| otherwise = id
decF curr | isNothing minVal = pred
| Just minv <- minVal, curr>minv = pred
| Just minv <- minVal, Just maxv <- maxVal, cyclic = const maxv
| otherwise = id
counter = accumB start $ ((incF <$> counter) <@ incE) `union`((decF <$> counter) <@ decE)
Now, counter
is defined in terms of itself. But in the new monadic API, accumB
is a monadic function, and this is where I don't see how to proceed - Moment
has no MonadFix
instance, so how does it work now?
For obvious reasons this does NOT work ('Not in scope: counter')
mkCounter :: (MonadMoment m,Enum a,Ord a) => a -> Maybe a -> Maybe a -> Bool
-> Event b -> Event c -> m (Behavior a)
mkCounter start minVal maxVal cyclic incE decE = do
-- .. same as above ..
counter <- accumB start $ unions [((incF <$> counter) <@ incE)
,((decF <$> counter) <@ decE)]
return counter
What is the correct way to do it now? Thanks in advance!