3

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!

apirogov
  • 1,296
  • 1
  • 12
  • 22
  • 1
    so you did end up giving 1.0 a try? – Erik Kaplun Oct 07 '15 at 20:25
  • 3
    "`Moment` has no `MonadFix` instance" -- In the current *master* [it does](https://github.com/HeinrichApfelmus/reactive-banana/blob/3ac2dfc54e09ee9ce72d241fb434af10c7477d1b/reactive-banana/src/Reactive/Banana/Types.hs#L102). – duplode Oct 07 '15 at 20:30
  • 1
    @ErikAllik Yes, I decided to get the newest version from github instead of wasting time with the old API :) – apirogov Oct 07 '15 at 21:07
  • @duplode oh, I see, I did a stupid mistake... problem solved! – apirogov Oct 07 '15 at 21:07

1 Answers1

4

Ok, this was a stupid mistake. I just needed to add MonadFix m as a constraint, as I am not working with the Moment Monad directly:

mkCounter :: (MonadFix m,MonadMoment m,Enum a,Ord a) => a -> Maybe a -> Maybe a -> Bool
          -> Event b -> Event c -> m (Behavior a)

Then it works as expected with mdo.

apirogov
  • 1,296
  • 1
  • 12
  • 22