@@ -25,6 +25,7 @@ import Data.Functor.Compose
2525import Data.Functor.Constant
2626import Data.Foldable
2727import Data.Maybe
28+import Data.Bifunctor
2829
2930-- Note: must come last to silence warnings due to AMP on GHC < 7.10
3031import Prelude hiding (mapM, mapM_, sequence, sequence_, foldl)
@@ -254,21 +255,6 @@ instance Reflex t => FunctorMaybe (Event t) where
254255instance Reflex t => Functor (Event t) where
255256 fmap f = fmapMaybe $ Just . f
256257
257−-- | Create a new 'Event' by combining each occurence with the next value
258−-- of the list using the supplied function. If the list runs out of items,
259−-- all subsequent 'Event' occurrences will be ignored.
260−zipListWithEvent :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> c) -> [a] -> Event t b -> m (Event t c)
261−zipListWithEvent f l e = do
262− rec lb <- hold l eTail
263− let eBoth = flip push e $ \o -> do
264− l' <- sample lb
265− return $ case l' of
266− (h : t) -> Just (f h o, t)
267− [] -> Nothing
268− let eTail = fmap snd eBoth
269− lb `seq` eBoth `seq` eTail `seq` return ()
270− return $ fmap fst eBoth
271−
272258-- | Replace each occurrence value of the 'Event' with the value of the
273259-- 'Behavior' at the time of that occurrence.
274260tag :: Reflex t => Behavior t b -> Event t a -> Event t b
@@ -501,3 +487,74 @@ distributeDMapOverDynPure dm = case DMap.toList dm of
501487 olds <- sample $ current result
502488 return $ DMap.unionWithKey (\_ _ new -> new) olds news
503489 in result
490+
491+class Reflex t => Accumulator t f | f -> t where
492+ accum :: (MonadHold t m, MonadFix m) => (a -> b -> a) -> a -> Event t b -> m (f a)
493+ accum f = accumMaybe $ \v o -> Just $ f v o
494+ accumM :: (MonadHold t m, MonadFix m) => (a -> b -> PushM t a) -> a -> Event t b -> m (f a)
495+ accumM f = accumMaybeM $ \v o -> Just <$> f v o
496+ accumMaybe :: (MonadHold t m, MonadFix m) => (a -> b -> Maybe a) -> a -> Event t b -> m (f a)
497+ accumMaybe f = accumMaybeM $ \v o -> return $ f v o
498+ accumMaybeM :: (MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a)) -> a -> Event t b -> m (f a)
499+ mapAccum :: (MonadHold t m, MonadFix m) => (a -> b -> (a, c)) -> a -> Event t b -> m (f a, Event t c)
500+ mapAccum f = mapAccumMaybe $ \v o -> bimap Just Just $ f v o
501+ mapAccumM :: (MonadHold t m, MonadFix m) => (a -> b -> PushM t (a, c)) -> a -> Event t b -> m (f a, Event t c)
502+ mapAccumM f = mapAccumMaybeM $ \v o -> bimap Just Just <$> f v o
503+ mapAccumMaybe :: (MonadHold t m, MonadFix m) => (a -> b -> (Maybe a, Maybe c)) -> a -> Event t b -> m (f a, Event t c)
504+ mapAccumMaybe f = mapAccumMaybeM $ \v o -> return $ f v o
505+ mapAccumMaybeM :: (MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a, Maybe c)) -> a -> Event t b -> m (f a, Event t c)
506+
507+mapAccum_ :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> (a, c)) -> a -> Event t b -> m (Event t c)
508+mapAccum_ f z e = do
509+ (_ :: Behavior t a, result) <- mapAccum f z e
510+ return result
511+
512+mapAccumMaybe_ :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> (Maybe a, Maybe c)) -> a -> Event t b -> m (Event t c)
513+mapAccumMaybe_ f z e = do
514+ (_ :: Behavior t a, result) <- mapAccumMaybe f z e
515+ return result
516+
517+mapAccumM_ :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (a, c)) -> a -> Event t b -> m (Event t c)
518+mapAccumM_ f z e = do
519+ (_ :: Behavior t a, result) <- mapAccumM f z e
520+ return result
521+
522+mapAccumMaybeM_ :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a, Maybe c)) -> a -> Event t b -> m (Event t c)
523+mapAccumMaybeM_ f z e = do
524+ (_ :: Behavior t a, result) <- mapAccumMaybeM f z e
525+ return result
526+
527+instance Reflex t => Accumulator t (Dynamic t) where
528+ accumMaybeM f z e = do
529+ rec let e' = flip push e $ \o -> do
530+ v <- sample $ current d'
531+ f v o
532+ d' <- holdDyn z e'
533+ return d'
534+ mapAccumMaybeM f z e = do
535+ rec let e' = flip push e $ \o -> do
536+ v <- sample $ current d'
537+ result <- f v o
538+ return $ case result of
539+ (Nothing, Nothing) -> Nothing
540+ _ -> Just result
541+ d' <- holdDyn z $ fmapMaybe fst e'
542+ return (d', fmapMaybe snd e')
543+
544+instance Reflex t => Accumulator t (Behavior t) where
545+ accumMaybeM f z e = current <$> accumMaybeM f z e
546+ mapAccumMaybeM f z e = first current <$> mapAccumMaybeM f z e
547+
548+instance Reflex t => Accumulator t (Event t) where
549+ accumMaybeM f z e = updated <$> accumMaybeM f z e
550+ mapAccumMaybeM f z e = first updated <$> mapAccumMaybeM f z e
551+
552+-- | Create a new 'Event' by combining each occurence with the next value
553+-- of the list using the supplied function. If the list runs out of items,
554+-- all subsequent 'Event' occurrences will be ignored.
555+zipListWithEvent :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> c) -> [a] -> Event t b -> m (Event t c)
556+zipListWithEvent f l e = do
557+ let f' a b = case a of
558+ h:t -> (Just t, Just $ f h b)
559+ _ -> (Nothing, Nothing) --TODO: Unsubscribe the event?
560+ mapAccumMaybe_ f' l e