@@ -21,9 +21,13 @@
21{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
21{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
24−-- | This module contains the Reflex interface, as well as a variety of
28+-- This module contains the Reflex interface, as well as a variety of
25−-- convenience functions for working with 'Event's, 'Behavior's, and other
29+-- convenience functions for working with 'Event's, 'Behavior's, and other
26−-- signals.
30+-- signals.
27module Reflex.Class
31module Reflex.Class
28 ( module Reflex.Patch
32 ( module Reflex.Patch
29 -- * Primitives
33 -- * Primitives
@@ -133,8 +137,10 @@ module Reflex.Class
133 -- * Unsafe functions
137 -- * Unsafe functions
134 , unsafeDynamic
138 , unsafeDynamic
135 , unsafeMapIncremental
139 , unsafeMapIncremental
136− -- * 'FunctorMaybe'
140+ -- * 'Filterable' convenience functions
137− , FunctorMaybe (..)
141+ , FunctorMaybe -- fmapMaybe is purposely not exported from deprecated 'FunctorMaybe' and the new alias is exported instead
142+ , mapMaybe -- Re-exported for convenience
138 , fforMaybe
144 , fforMaybe
139 , ffilter
145 , ffilter
140 , filterLeft
146 , filterLeft
@@ -144,10 +150,11 @@ module Reflex.Class
146 -- * Deprecated functions
152 -- * Deprecated functions
147− , appendEvents
153+ , switchPromptly
148− , onceE
154+ , switchPromptOnly
149− , sequenceThese
155+ -- * "Cheap" functions
150 , fmapMaybeCheap
156 , fmapMaybeCheap
151 , fmapCheap
158 , fmapCheap
152 , fforCheap
159 , fforCheap
153 , fforMaybeCheap
160 , fforMaybeCheap
@@ -155,8 +162,6 @@ module Reflex.Class
155 , tagCheap
162 , tagCheap
156 , mergeWithCheap
163 , mergeWithCheap
157 , mergeWithCheap'
164 , mergeWithCheap'
160 -- * Slow, but general, implementations
165 -- * Slow, but general, implementations
161 , slowHeadE
166 , slowHeadE
@@ -193,7 +198,10 @@ import qualified Data.Some as Some
193import Data.String
198import Data.String
194import Data.These
199import Data.These
195import Data.Type.Coercion
200import Data.Type.Coercion
201+import Data.Witherable (Filterable(..))
202+import qualified Data.Witherable as W
203+import Reflex.FunctorMaybe (FunctorMaybe)
196−import Reflex.FunctorMaybe
204+import qualified Reflex.FunctorMaybe
197import Reflex.Patch
205import Reflex.Patch
198import qualified Reflex.Patch.MapWithMove as PatchMapWithMove
206import qualified Reflex.Patch.MapWithMove as PatchMapWithMove
@@ -256,8 +264,7 @@ class ( MonadHold t (PushM t)
256 -- | Create an 'Event' that will occur whenever the currently-selected input
264 -- | Create an 'Event' that will occur whenever the currently-selected input
257 -- 'Event' occurs
265 -- 'Event' occurs
258 switch :: Behavior t (Event t a) -> Event t a
266 switch :: Behavior t (Event t a) -> Event t a
259− -- | Create an 'Event' that will occur whenever the input event is occurring
267+ -- | Create an 'Event' that will occur whenever the input event is occurring -- and its occurrence value, another 'Event', is also occurring
260− -- and its occurrence value, another 'Event', is also occurring
261 coincidence :: Event t (Event t a) -> Event t a
268 coincidence :: Event t (Event t a) -> Event t a
262 -- | Extract the 'Behavior' of a 'Dynamic'.
269 -- | Extract the 'Behavior' of a 'Dynamic'.
263 current :: Dynamic t a -> Behavior t a
270 current :: Dynamic t a -> Behavior t a
@@ -388,8 +395,8 @@ mapAccumMaybeMIncremental f z e = do
388 return $ case result of
395 return $ case result of
389 (Nothing, Nothing) -> Nothing
396 (Nothing, Nothing) -> Nothing
390 _ -> Just result
397 _ -> Just result
391− d' <- holdIncremental z $ fmapMaybe fst e'
398+ d' <- holdIncremental z $ mapMaybe fst e'
392− return (d', fmapMaybe snd e')
399+ return (d', mapMaybe snd e')
394slowHeadE :: (Reflex t, MonadHold t m, MonadFix m) => Event t a -> m (Event t a)
401slowHeadE :: (Reflex t, MonadHold t m, MonadFix m) => Event t a -> m (Event t a)
395slowHeadE e = do
402slowHeadE e = do
@@ -399,14 +406,14 @@ slowHeadE e = do
400-- | An 'EventSelector' allows you to efficiently 'select' an 'Event' based on a
407-- | An 'EventSelector' allows you to efficiently 'select' an 'Event' based on a
401-- key. This is much more efficient than filtering for each key with
408-- key. This is much more efficient than filtering for each key with
402−-- 'fmapMaybe'.
409+-- 'mapMaybe'.
403newtype EventSelector t k = EventSelector
410newtype EventSelector t k = EventSelector
404 { -- | Retrieve the 'Event' for the given key. The type of the 'Event' is
411 { -- | Retrieve the 'Event' for the given key. The type of the 'Event' is
405 -- determined by the type of the key, so this can be used to fan-out
412 -- determined by the type of the key, so this can be used to fan-out
406 -- 'Event's whose sub-'Event's have different types.
413 -- 'Event's whose sub-'Event's have different types.
408 -- Using 'EventSelector's and the 'fan' primitive is far more efficient than
415 -- Using 'EventSelector's and the 'fan' primitive is far more efficient than
409− -- (but equivalent to) using 'fmapMaybe' to select only the relevant
416+ -- (but equivalent to) using 'mapMaybe' to select only the relevant
410 -- occurrences of an 'Event'.
417 -- occurrences of an 'Event'.
411 select :: forall a. k a -> Event t a
418 select :: forall a. k a -> Event t a
@@ -541,6 +548,15 @@ instance (Reflex t, Num a) => Num (Behavior t a) where
541 negate = fmap negate
548 negate = fmap negate
542 signum = fmap signum
549 signum = fmap signum
551+instance (Num a, Reflex t) => Num (Dynamic t a) where
555+ signum = fmap signum
556+ fromInteger = pure . fromInteger
557+ negate = fmap negate
544instance (Reflex t, Semigroup a) => Semigroup (Behavior t a) where
560instance (Reflex t, Semigroup a) => Semigroup (Behavior t a) where
545 a <> b = pull $ liftM2 (<>) (sample a) (sample b)
561 a <> b = pull $ liftM2 (<>) (sample a) (sample b)
546 sconcat = pull . fmap sconcat . mapM sample
562 sconcat = pull . fmap sconcat . mapM sample
@@ -550,22 +566,25 @@ instance (Reflex t, Semigroup a) => Semigroup (Behavior t a) where
550 times1p n = fmap $ times1p n
566 times1p n = fmap $ times1p n
569+-- | Alias for 'mapMaybe'
570+fmapMaybe :: Filterable f => (a -> Maybe b) -> f a -> f b
553−-- | Flipped version of 'fmapMaybe'.
573+-- | Flipped version of 'mapMaybe'.
554−fforMaybe :: FunctorMaybe f => f a -> (a -> Maybe b) -> f b
574+fforMaybe :: Filterable f => f a -> (a -> Maybe b) -> f b
555−fforMaybe = flip fmapMaybe
575+fforMaybe = flip mapMaybe
557-- | Filter 'f a' using the provided predicate.
577-- | Filter 'f a' using the provided predicate.
558−-- Relies on 'fforMaybe'.
559−ffilter :: FunctorMaybe f => (a -> Bool) -> f a -> f a
578+ffilter :: Filterable f => (a -> Bool) -> f a -> f a
560−ffilter f = fmapMaybe $ \x -> if f x then Just x else Nothing
579+ffilter = W.filter
562-- | Filter 'Left's from 'f (Either a b)' into 'a'.
581-- | Filter 'Left's from 'f (Either a b)' into 'a'.
563−filterLeft :: FunctorMaybe f => f (Either a b) -> f a
582+filterLeft :: Filterable f => f (Either a b) -> f a
564−filterLeft = fmapMaybe (either Just (const Nothing))
583+filterLeft = mapMaybe (either Just (const Nothing))
566-- | Filter 'Right's from 'f (Either a b)' into 'b'.
585-- | Filter 'Right's from 'f (Either a b)' into 'b'.
567−filterRight :: FunctorMaybe f => f (Either a b) -> f b
586+filterRight :: Filterable f => f (Either a b) -> f b
568−filterRight = fmapMaybe (either (const Nothing) Just)
587+filterRight = mapMaybe (either (const Nothing) Just)
570-- | Left-biased event union (prefers left event on simultaneous
589-- | Left-biased event union (prefers left event on simultaneous
571-- occurrence).
590-- occurrence).
@@ -583,13 +602,18 @@ instance Reflex t => Bind (Event t) where
584instance Reflex t => Functor (Event t) where
603instance Reflex t => Functor (Event t) where
585 {-# INLINE fmap #-}
604 {-# INLINE fmap #-}
586− fmap f = fmapMaybe $ Just . f
605+ fmap f = mapMaybe $ Just . f
587 {-# INLINE (<$) #-}
606 {-# INLINE (<$) #-}
588 x <$ e = fmapCheap (const x) e
607 x <$ e = fmapCheap (const x) e
609+-- TODO Remove this instance
590instance Reflex t => FunctorMaybe (Event t) where
610instance Reflex t => FunctorMaybe (Event t) where
591 {-# INLINE fmapMaybe #-}
611 {-# INLINE fmapMaybe #-}
612+ fmapMaybe = mapMaybe
614+instance Reflex t => Filterable (Event t) where
615+ {-# INLINE mapMaybe #-}
592− fmapMaybe f = push $ return . f
616+ mapMaybe f = push $ return . f
594-- | Never: @'zero' = 'never'@.
618-- | Never: @'zero' = 'never'@.
595instance Reflex t => Plus (Event t) where
619instance Reflex t => Plus (Event t) where
@@ -807,7 +831,7 @@ fanEither :: Reflex t => Event t (Either a b) -> (Event t a, Event t b)
807fanEither e =
831fanEither e =
808 let justLeft = either Just (const Nothing)
832 let justLeft = either Just (const Nothing)
809 justRight = either (const Nothing) Just
833 justRight = either (const Nothing) Just
810− in (fmapMaybe justLeft e, fmapMaybe justRight e)
834+ in (mapMaybe justLeft e, mapMaybe justRight e)
812-- | Split the event into separate events for 'This' and 'That' values,
836-- | Split the event into separate events for 'This' and 'That' values,
813-- allowing them to fire simultaneously when the input value is 'These'.
837-- allowing them to fire simultaneously when the input value is 'These'.
@@ -819,7 +843,7 @@ fanThese e =
819 that (That y) = Just y
843 that (That y) = Just y
820 that (These _ y) = Just y
844 that (These _ y) = Just y
821 that _ = Nothing
845 that _ = Nothing
822− in (fmapMaybe this e, fmapMaybe that e)
846+ in (mapMaybe this e, mapMaybe that e)
824-- | Split the event into an 'EventSelector' that allows efficient selection of
848-- | Split the event into an 'EventSelector' that allows efficient selection of
825-- the individual 'Event's.
849-- the individual 'Event's.
@@ -998,14 +1022,16 @@ distributeListOverDynWith f = fmap (f . map (\(Const2 _ :=> Identity v) -> v) .
998difference :: Reflex t => Event t a -> Event t b -> Event t a
1022difference :: Reflex t => Event t a -> Event t b -> Event t a
999difference = alignEventWithMaybe $ \case
1023difference = alignEventWithMaybe $ \case
1000 This a -> Just a
1024 This a -> Just a
1001− _ -> Nothing
1025+ _ -> Nothing
1027+-- | Zips two values by taking the union of their shapes and combining with the provided function.
1028+-- 'Nothing' values are dropped.
1003alignEventWithMaybe :: Reflex t => (These a b -> Maybe c) -> Event t a -> Event t b -> Event t c
1029alignEventWithMaybe :: Reflex t => (These a b -> Maybe c) -> Event t a -> Event t b -> Event t c
1004−alignEventWithMaybe f ea eb =
1030+alignEventWithMaybe f ea eb = mapMaybe (f <=< dmapToThese) $
1005− fmapMaybe (f <=< dmapToThese)
1007− $ DMap.fromList [LeftTag :=> ea, RightTag :=> eb]
1031+ merge $ DMap.fromList [LeftTag :=> ea, RightTag :=> eb]
1033+-- | Produces an 'Event' that fires only when the input event fires with a 'DSum' key that
1034+-- matches the provided key.
1009filterEventKey
1035filterEventKey
1010 :: forall t m k v a.
1036 :: forall t m k v a.
1011 ( Reflex t
1037 ( Reflex t
@@ -1023,7 +1049,10 @@ filterEventKey k kv' = do
1023 Nothing -> Nothing
1049 Nothing -> Nothing
1024 takeWhileJustE f kv'
1050 takeWhileJustE f kv'
1026−
1052+-- | "Factor" the input 'DSum' 'Event' to produce an 'Event' which
1053+-- fires when the 'DSum' key changes and contains both the value of the
1054+-- 'DSum' at switchover and an 'Event' of values produced by subsequent
1055+-- firings of the input 'Event' that do not change the 'DSum' key.
1027factorEvent
1056factorEvent
1028 :: forall t m k v a.
1057 :: forall t m k v a.
1029 ( Reflex t
1058 ( Reflex t
@@ -1073,26 +1102,94 @@ class Reflex t => Accumulator t f | f -> t where
1073 mapAccumMaybe f = mapAccumMaybeM $ \v o -> return $ f v o
1102 mapAccumMaybe f = mapAccumMaybeM $ \v o -> return $ f v o
1074 mapAccumMaybeM :: (MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a, Maybe c)) -> a -> Event t b -> m (f a, Event t c)
1103 mapAccumMaybeM :: (MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a, Maybe c)) -> a -> Event t b -> m (f a, Event t c)
1105+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event'
1106+-- with the provided function. See 'foldDyn'.
1076−accumDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> a) -> a -> Event t b -> m (Dynamic t a)
1108+ :: (Reflex t, MonadHold t m, MonadFix m)
1077accumDyn f = accumMaybeDyn $ \v o -> Just $ f v o
1113accumDyn f = accumMaybeDyn $ \v o -> Just $ f v o
1115+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event'
1116+-- with the provided 'PushM' action.
1078−accumMDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t a) -> a -> Event t b -> m (Dynamic t a)
1118+ :: (Reflex t, MonadHold t m, MonadFix m)
1119+ => (a -> b -> PushM t a)
1079accumMDyn f = accumMaybeMDyn $ \v o -> Just <$> f v o
1123accumMDyn f = accumMaybeMDyn $ \v o -> Just <$> f v o
1125+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event'
1126+-- with the provided function, discarding 'Nothing' results.
1080−accumMaybeDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> Maybe a) -> a -> Event t b -> m (Dynamic t a)
1128+ :: (Reflex t, MonadHold t m, MonadFix m)
1129+ => (a -> b -> Maybe a)
1081accumMaybeDyn f = accumMaybeMDyn $ \v o -> return $ f v o
1133accumMaybeDyn f = accumMaybeMDyn $ \v o -> return $ f v o
1135+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event'
1136+-- with the provided 'PushM' action, discarding 'Nothing' results.
1082−accumMaybeMDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a)) -> a -> Event t b -> m (Dynamic t a)
1138+ :: (Reflex t, MonadHold t m, MonadFix m)
1139+ => (a -> b -> PushM t (Maybe a))
1083accumMaybeMDyn f z e = do
1143accumMaybeMDyn f z e = do
1084 rec let e' = flip push e $ \o -> do
1144 rec let e' = flip push e $ \o -> do
1085 v <- sample $ current d'
1145 v <- sample $ current d'
1087 d' <- holdDyn z e'
1147 d' <- holdDyn z e'
1088 return d'
1148 return d'
1150+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event'
1151+-- with a function that both accumulates and produces a value to fire
1152+-- as an 'Event'. Returns both the accumulated value and an 'Event'.
1089−mapAccumDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> (a, c)) -> a -> Event t b -> m (Dynamic t a, Event t c)
1154+ :: (Reflex t, MonadHold t m, MonadFix m)
1155+ => (a -> b -> (a, c))
1158+ -> m (Dynamic t a, Event t c)
1090mapAccumDyn f = mapAccumMaybeDyn $ \v o -> bimap Just Just $ f v o
1159mapAccumDyn f = mapAccumMaybeDyn $ \v o -> bimap Just Just $ f v o
1161+-- | Similar to 'mapAccumDyn' except that the combining function is a
1091−mapAccumMDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (a, c)) -> a -> Event t b -> m (Dynamic t a, Event t c)
1164+ :: (Reflex t, MonadHold t m, MonadFix m)
1165+ => (a -> b -> PushM t (a, c))
1168+ -> m (Dynamic t a, Event t c)
1092mapAccumMDyn f = mapAccumMaybeMDyn $ \v o -> bimap Just Just <$> f v o
1169mapAccumMDyn f = mapAccumMaybeMDyn $ \v o -> bimap Just Just <$> f v o
1171+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event' with
1172+-- a function that both optionally accumulates and optionally produces
1173+-- a value to fire as a separate output 'Event'.
1174+-- Note that because 'Nothing's are discarded in both cases, the output
1175+-- 'Event' may fire even though the output 'Dynamic' has not changed, and
1176+-- the output 'Dynamic' may update even when the output 'Event' is not firing.
1093−mapAccumMaybeDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> (Maybe a, Maybe c)) -> a -> Event t b -> m (Dynamic t a, Event t c)
1178+ :: (Reflex t, MonadHold t m, MonadFix m)
1179+ => (a -> b -> (Maybe a, Maybe c))
1182+ -> m (Dynamic t a, Event t c)
1094mapAccumMaybeDyn f = mapAccumMaybeMDyn $ \v o -> return $ f v o
1183mapAccumMaybeDyn f = mapAccumMaybeMDyn $ \v o -> return $ f v o
1185+-- | Like 'mapAccumMaybeDyn' except that the combining function is a
1095−mapAccumMaybeMDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a, Maybe c)) -> a -> Event t b -> m (Dynamic t a, Event t c)
1188+ :: (Reflex t, MonadHold t m, MonadFix m)
1189+ => (a -> b -> PushM t (Maybe a, Maybe c))
1192+ -> m (Dynamic t a, Event t c)
1096mapAccumMaybeMDyn f z e = do
1193mapAccumMaybeMDyn f z e = do
1097 rec let e' = flip push e $ \o -> do
1194 rec let e' = flip push e $ \o -> do
1098 v <- sample $ current d'
1195 v <- sample $ current d'
@@ -1100,18 +1197,42 @@ mapAccumMaybeMDyn f z e = do
1100 return $ case result of
1197 return $ case result of
1101 (Nothing, Nothing) -> Nothing
1198 (Nothing, Nothing) -> Nothing
1102 _ -> Just result
1199 _ -> Just result
1103− d' <- holdDyn z $ fmapMaybe fst e'
1200+ d' <- holdDyn z $ mapMaybe fst e'
1104− return (d', fmapMaybe snd e')
1201+ return (d', mapMaybe snd e')
1203+-- | Accumulate a 'Behavior' by folding occurrences of an 'Event'
1204+-- with the provided function.
1106{-# INLINE accumB #-}
1205{-# INLINE accumB #-}
1107−accumB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> a) -> a -> Event t b -> m (Behavior t a)
1207+ :: (Reflex t, MonadHold t m, MonadFix m)
1211+ -> m (Behavior t a)
1108accumB f = accumMaybeB $ \v o -> Just $ f v o
1212accumB f = accumMaybeB $ \v o -> Just $ f v o
1214+-- | Like 'accumB' except that the combining function is a 'PushM' action.
1109{-# INLINE accumMB #-}
1215{-# INLINE accumMB #-}
1110−accumMB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t a) -> a -> Event t b -> m (Behavior t a)
1217+ :: (Reflex t, MonadHold t m, MonadFix m)
1218+ => (a -> b -> PushM t a)
1221+ -> m (Behavior t a)
1111accumMB f = accumMaybeMB $ \v o -> Just <$> f v o
1222accumMB f = accumMaybeMB $ \v o -> Just <$> f v o
1224+-- | Accumulate a 'Behavior' by folding occurrences of an 'Event'
1225+-- with the provided function, discarding 'Nothing' results.
1112{-# INLINE accumMaybeB #-}
1226{-# INLINE accumMaybeB #-}
1113−accumMaybeB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> Maybe a) -> a -> Event t b -> m (Behavior t a)
1228+ :: (Reflex t, MonadHold t m, MonadFix m)
1229+ => (a -> b -> Maybe a)
1232+ -> m (Behavior t a)
1114accumMaybeB f = accumMaybeMB $ \v o -> return $ f v o
1233accumMaybeB f = accumMaybeMB $ \v o -> return $ f v o
1235+-- | Like 'accumMaybeB' except that the combining function is a 'PushM' action.
1115{-# INLINE accumMaybeMB #-}
1236{-# INLINE accumMaybeMB #-}
1116accumMaybeMB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a)) -> a -> Event t b -> m (Behavior t a)
1237accumMaybeMB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a)) -> a -> Event t b -> m (Behavior t a)
1117accumMaybeMB f z e = do
1238accumMaybeMB f z e = do
@@ -1120,16 +1241,42 @@ accumMaybeMB f z e = do
1121 d' <- hold z e'
1242 d' <- hold z e'
1122 return d'
1243 return d'
1245+-- | Accumulate a 'Behavior' by folding occurrences of an 'Event'
1246+-- with a function that both accumulates and produces a value to fire
1247+-- as an 'Event'. Returns both the accumulated value and an 'Event'.
1123{-# INLINE mapAccumB #-}
1248{-# INLINE mapAccumB #-}
1124−mapAccumB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> (a, c)) -> a -> Event t b -> m (Behavior t a, Event t c)
1250+ :: (Reflex t, MonadHold t m, MonadFix m)
1251+ => (a -> b -> (a, c))
1254+ -> m (Behavior t a, Event t c)
1125mapAccumB f = mapAccumMaybeB $ \v o -> bimap Just Just $ f v o
1255mapAccumB f = mapAccumMaybeB $ \v o -> bimap Just Just $ f v o
1257+-- | Like 'mapAccumB' except that the combining function is a 'PushM' action.
1126{-# INLINE mapAccumMB #-}
1258{-# INLINE mapAccumMB #-}
1127−mapAccumMB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (a, c)) -> a -> Event t b -> m (Behavior t a, Event t c)
1260+ :: (Reflex t, MonadHold t m, MonadFix m)
1261+ => (a -> b -> PushM t (a, c))
1264+ -> m (Behavior t a, Event t c)
1128mapAccumMB f = mapAccumMaybeMB $ \v o -> bimap Just Just <$> f v o
1265mapAccumMB f = mapAccumMaybeMB $ \v o -> bimap Just Just <$> f v o
1267+-- | Accumulate a 'Behavior' by folding occurrences of an 'Event' with
1268+-- a function that both optionally accumulates and optionally produces
1269+-- a value to fire as a separate output 'Event'. 'Nothing's are discarded.
1129{-# INLINE mapAccumMaybeB #-}
1270{-# INLINE mapAccumMaybeB #-}
1130−mapAccumMaybeB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> (Maybe a, Maybe c)) -> a -> Event t b -> m (Behavior t a, Event t c)
1272+ :: (Reflex t, MonadHold t m, MonadFix m)
1273+ => (a -> b -> (Maybe a, Maybe c))
1276+ -> m (Behavior t a, Event t c)
1131mapAccumMaybeB f = mapAccumMaybeMB $ \v o -> return $ f v o
1277mapAccumMaybeB f = mapAccumMaybeMB $ \v o -> return $ f v o
1279+-- | LIke 'mapAccumMaybeB' except that the combining function is a 'PushM' action.
1133{-# INLINE mapAccumMaybeMB #-}
1280{-# INLINE mapAccumMaybeMB #-}
1134mapAccumMaybeMB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a, Maybe c)) -> a -> Event t b -> m (Behavior t a, Event t c)
1281mapAccumMaybeMB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a, Maybe c)) -> a -> Event t b -> m (Behavior t a, Event t c)
1135mapAccumMaybeMB f z e = do
1282mapAccumMaybeMB f z e = do
@@ -1139,8 +1286,8 @@ mapAccumMaybeMB f z e = do
1139 return $ case result of
1286 return $ case result of
1140 (Nothing, Nothing) -> Nothing
1287 (Nothing, Nothing) -> Nothing
1141 _ -> Just result
1288 _ -> Just result
1142− d' <- hold z $ fmapMaybe fst e'
1289+ d' <- hold z $ mapMaybe fst e'
1143− return (d', fmapMaybe snd e')
1290+ return (d', mapMaybe snd e')
1145-- | Accumulate occurrences of an 'Event', producing an output occurrence each
1292-- | Accumulate occurrences of an 'Event', producing an output occurrence each
1146-- time. Discard the underlying 'Accumulator'.
1293-- time. Discard the underlying 'Accumulator'.
@@ -1284,38 +1431,53 @@ infixl 4 <@
1284-- Cheap Functions
1431-- Cheap Functions
1285------------------
1432------------------
1434+-- | A "cheap" version of 'pushAlways'. See the performance note on 'pushCheap'.
1287{-# INLINE pushAlwaysCheap #-}
1435{-# INLINE pushAlwaysCheap #-}
1288pushAlwaysCheap :: Reflex t => (a -> PushM t b) -> Event t a -> Event t b
1436pushAlwaysCheap :: Reflex t => (a -> PushM t b) -> Event t a -> Event t b
1289pushAlwaysCheap f = pushCheap (fmap Just . f)
1437pushAlwaysCheap f = pushCheap (fmap Just . f)
1439+-- | A "cheap" version of 'mapMaybe'. See the performance note on 'pushCheap'.
1440+{-# INLINE mapMaybeCheap #-}
1441+mapMaybeCheap :: Reflex t => (a -> Maybe b) -> Event t a -> Event t b
1442+mapMaybeCheap f = pushCheap $ return . f
1444+-- | An alias for 'mapMaybeCheap'
1291{-# INLINE fmapMaybeCheap #-}
1445{-# INLINE fmapMaybeCheap #-}
1292fmapMaybeCheap :: Reflex t => (a -> Maybe b) -> Event t a -> Event t b
1446fmapMaybeCheap :: Reflex t => (a -> Maybe b) -> Event t a -> Event t b
1293−fmapMaybeCheap f = pushCheap $ return . f
1447+fmapMaybeCheap = mapMaybeCheap
1450+-- | A "cheap" version of 'fforMaybe'. See the performance note on 'pushCheap'.
1295{-# INLINE fforMaybeCheap #-}
1451{-# INLINE fforMaybeCheap #-}
1296fforMaybeCheap :: Reflex t => Event t a -> (a -> Maybe b) -> Event t b
1452fforMaybeCheap :: Reflex t => Event t a -> (a -> Maybe b) -> Event t b
1297−fforMaybeCheap = flip fmapMaybeCheap
1453+fforMaybeCheap = flip mapMaybeCheap
1455+-- | A "cheap" version of 'ffor'. See the performance note on 'pushCheap'.
1299{-# INLINE fforCheap #-}
1456{-# INLINE fforCheap #-}
1300fforCheap :: Reflex t => Event t a -> (a -> b) -> Event t b
1457fforCheap :: Reflex t => Event t a -> (a -> b) -> Event t b
1301fforCheap = flip fmapCheap
1458fforCheap = flip fmapCheap
1460+-- | A "cheap" version of 'fmap'. See the performance note on 'pushCheap'.
1303{-# INLINE fmapCheap #-}
1461{-# INLINE fmapCheap #-}
1304fmapCheap :: Reflex t => (a -> b) -> Event t a -> Event t b
1462fmapCheap :: Reflex t => (a -> b) -> Event t a -> Event t b
1305fmapCheap f = pushCheap $ return . Just . f
1463fmapCheap f = pushCheap $ return . Just . f
1465+-- | A "cheap" version of 'tag'. See the performance note on 'pushCheap'.
1307{-# INLINE tagCheap #-}
1466{-# INLINE tagCheap #-}
1308tagCheap :: Reflex t => Behavior t b -> Event t a -> Event t b
1467tagCheap :: Reflex t => Behavior t b -> Event t a -> Event t b
1309tagCheap b = pushAlwaysCheap $ \_ -> sample b
1468tagCheap b = pushAlwaysCheap $ \_ -> sample b
1470+-- | A "cheap" version of 'mergeWithCheap'. See the performance note on 'pushCheap'.
1311{-# INLINE mergeWithCheap #-}
1471{-# INLINE mergeWithCheap #-}
1312mergeWithCheap :: Reflex t => (a -> a -> a) -> [Event t a] -> Event t a
1472mergeWithCheap :: Reflex t => (a -> a -> a) -> [Event t a] -> Event t a
1313mergeWithCheap = mergeWithCheap' id
1473mergeWithCheap = mergeWithCheap' id
1475+-- | A "cheap" version of 'mergeWithCheap''. See the performance note on 'pushCheap'.
1315{-# INLINE mergeWithCheap' #-}
1476{-# INLINE mergeWithCheap' #-}
1316mergeWithCheap' :: Reflex t => (a -> b) -> (b -> b -> b) -> [Event t a] -> Event t b
1477mergeWithCheap' :: Reflex t => (a -> b) -> (b -> b -> b) -> [Event t a] -> Event t b
1317mergeWithCheap' f g = mergeWithFoldCheap' $ foldl1 g . fmap f
1478mergeWithCheap' f g = mergeWithFoldCheap' $ foldl1 g . fmap f
1480+-- | A "cheap" version of 'mergeWithFoldCheap''. See the performance note on 'pushCheap'.
1319{-# INLINE mergeWithFoldCheap' #-}
1481{-# INLINE mergeWithFoldCheap' #-}
1320mergeWithFoldCheap' :: Reflex t => (NonEmpty a -> b) -> [Event t a] -> Event t b
1482mergeWithFoldCheap' :: Reflex t => (NonEmpty a -> b) -> [Event t a] -> Event t b
1321mergeWithFoldCheap' f es =
1483mergeWithFoldCheap' f es =
@@ -1328,28 +1490,6 @@ mergeWithFoldCheap' f es =
1328-- Deprecated functions
1490-- Deprecated functions
1329--------------------------------------------------------------------------------
1491--------------------------------------------------------------------------------
1331−-- | Create a new 'Event' that occurs if at least one of the supplied 'Event's
1332−-- occurs. If both occur at the same time they are combined using 'mappend'.
1333−{-# DEPRECATED appendEvents "If a 'Semigroup a' instance is available, use 'mappend'; otherwise, use 'alignWith (mergeThese mappend)' instead" #-}
1334−appendEvents :: (Reflex t, Monoid a) => Event t a -> Event t a -> Event t a
1335−appendEvents = alignWith $ mergeThese mappend
1337−-- | Alias for 'headE'
1338−{-# DEPRECATED onceE "Use 'headE' instead" #-}
1339−onceE :: MonadHold t m => Event t a -> m (Event t a)
1342−-- | Run both sides of a 'These' monadically, combining the results.
1343−{-# DEPRECATED sequenceThese "Use bisequenceA or bisequence from the bifunctors package instead" #-}
1344−#ifdef USE_TEMPLATE_HASKELL
1345−{-# ANN sequenceThese "HLint: ignore Use fmap" #-}
1347−sequenceThese :: Monad m => These (m a) (m b) -> m (These a b)
1348−sequenceThese t = case t of
1349− This ma -> fmap This ma
1350− These ma mb -> liftM2 These ma mb
1351− That mb -> fmap That mb
1353{-# DEPRECATED switchPromptly "Use 'switchHoldPromptly' instead. The 'switchHold*' naming convention was chosen because those functions are more closely related to each other than they are to 'switch'. " #-}
1493{-# DEPRECATED switchPromptly "Use 'switchHoldPromptly' instead. The 'switchHold*' naming convention was chosen because those functions are more closely related to each other than they are to 'switch'. " #-}
1354switchPromptly :: (Reflex t, MonadHold t m) => Event t a -> Event t (Event t a) -> m (Event t a)
1494switchPromptly :: (Reflex t, MonadHold t m) => Event t a -> Event t (Event t a) -> m (Event t a)
1355switchPromptly = switchHoldPromptly
1495switchPromptly = switchHoldPromptly