reactive-banana 1.0 monadic API:如何定义递归行为?

时间:2015-10-07 20:19:00

标签: haskell reactive-banana

在反应性香蕉<1.0.0中,这有效:

-- 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)

现在,counter是根据自身定义的。但是在新的monadic API中,accumB是一个monadic函数,这是我不知道如何继续的地方 - Moment没有MonadFix实例,那么它是如何实现的现在工作?

由于显而易见的原因,这不起作用(&#39;不在范围内:计数器&#39;)

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

现在这样做的正确方法是什么?提前谢谢!

1 个答案:

答案 0 :(得分:5)

好的,这是一个愚蠢的错误。我只需要添加MonadFix m作为约束,因为我不直接使用Moment Monad:

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

然后它按预期与mdo一起工作。