@@ -21,9 +21,13 @@
2121{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
2222#endif
2323
24−-- | This module contains the Reflex interface, as well as a variety of
25−-- convenience functions for working with 'Event's, 'Behavior's, and other
26−-- signals.
24+-- |
25+-- Module:
26+-- Reflex.Class
27+-- Description:
28+-- This module contains the Reflex interface, as well as a variety of
29+-- convenience functions for working with 'Event's, 'Behavior's, and other
30+-- signals.
2731module Reflex.Class
2832 ( module Reflex.Patch
2933 -- * Primitives
@@ -145,11 +149,11 @@ module Reflex.Class
145149 , ffor2
146150 , ffor3
147151 -- * Deprecated functions
148− , appendEvents
149− , onceE
150− , sequenceThese
151− , mapMaybeCheap
152+ , switchPromptly
153+ , switchPromptOnly
154+ -- * "Cheap" functions
152155 , fmapMaybeCheap
156+ , mapMaybeCheap
153157 , fmapCheap
154158 , fforCheap
155159 , fforMaybeCheap
@@ -157,8 +161,6 @@ module Reflex.Class
157161 , tagCheap
158162 , mergeWithCheap
159163 , mergeWithCheap'
160− , switchPromptly
161− , switchPromptOnly
162164 -- * Slow, but general, implementations
163165 , slowHeadE
164166 ) where
@@ -261,8 +263,7 @@ class ( MonadHold t (PushM t)
261263 -- | Create an 'Event' that will occur whenever the currently-selected input
262264 -- 'Event' occurs
263265 switch :: Behavior t (Event t a) -> Event t a
264− -- | Create an 'Event' that will occur whenever the input event is occurring
265− -- and its occurrence value, another 'Event', is also occurring
266+ -- | Create an 'Event' that will occur whenever the input event is occurring -- and its occurrence value, another 'Event', is also occurring
266267 coincidence :: Event t (Event t a) -> Event t a
267268 -- | Extract the 'Behavior' of a 'Dynamic'.
268269 current :: Dynamic t a -> Behavior t a
@@ -1011,16 +1012,16 @@ distributeListOverDynWith f = fmap (f . map (\(Const2 _ :=> Identity v) -> v) .
10111012difference :: Reflex t => Event t a -> Event t b -> Event t a
10121013difference = alignEventWithMaybe $ \case
10131014 This a -> Just a
1014− _ -> Nothing
1015+ _ -> Nothing
10151016
1017+-- | Zips two values by taking the union of their shapes and combining with the provided function.
1018+-- 'Nothing' values are dropped.
10161019alignEventWithMaybe :: Reflex t => (These a b -> Maybe c) -> Event t a -> Event t b -> Event t c
1017−alignEventWithMaybe f ea eb =
1018− mapMaybe (f <=< dmapToThese)
1019− $ merge
1020− $ DMap.fromList [LeftTag :=> ea, RightTag :=> eb]
10211020alignEventWithMaybe f ea eb = mapMaybe (f <=< dmapToThese) $
10221021 merge $ DMap.fromList [LeftTag :=> ea, RightTag :=> eb]
10231022
1023+-- | Produces an 'Event' that fires only when the input event fires with a 'DSum' key that
1024+-- matches the provided key.
10241025filterEventKey
10251026 :: forall t m k v a.
10261027 ( Reflex t
@@ -1038,7 +1039,10 @@ filterEventKey k kv' = do
10381039 Nothing -> Nothing
10391040 takeWhileJustE f kv'
10401041
1041−
1042+-- | "Factor" the input 'DSum' 'Event' to produce an 'Event' which
1043+-- fires when the 'DSum' key changes and contains both the value of the
1044+-- 'DSum' at switchover and an 'Event' of values produced by subsequent
1045+-- firings of the input 'Event' that do not change the 'DSum' key.
10421046factorEvent
10431047 :: forall t m k v a.
10441048 ( Reflex t
@@ -1088,26 +1092,94 @@ class Reflex t => Accumulator t f | f -> t where
10881092 mapAccumMaybe f = mapAccumMaybeM $ \v o -> return $ f v o
10891093 mapAccumMaybeM :: (MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a, Maybe c)) -> a -> Event t b -> m (f a, Event t c)
10901094
1091−accumDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> a) -> a -> Event t b -> m (Dynamic t a)
1095+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event'
1096+-- with the provided function. See 'foldDyn'.
1097+accumDyn
1098+ :: (Reflex t, MonadHold t m, MonadFix m)
1099+ => (a -> b -> a)
1100+ -> a
1101+ -> Event t b
1102+ -> m (Dynamic t a)
10921103accumDyn f = accumMaybeDyn $ \v o -> Just $ f v o
1093−accumMDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t a) -> a -> Event t b -> m (Dynamic t a)
1104+
1105+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event'
1106+-- with the provided 'PushM' action.
1107+accumMDyn
1108+ :: (Reflex t, MonadHold t m, MonadFix m)
1109+ => (a -> b -> PushM t a)
1110+ -> a
1111+ -> Event t b
1112+ -> m (Dynamic t a)
10941113accumMDyn f = accumMaybeMDyn $ \v o -> Just <$> f v o
1095−accumMaybeDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> Maybe a) -> a -> Event t b -> m (Dynamic t a)
1114+
1115+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event'
1116+-- with the provided function, discarding 'Nothing' results.
1117+accumMaybeDyn
1118+ :: (Reflex t, MonadHold t m, MonadFix m)
1119+ => (a -> b -> Maybe a)
1120+ -> a
1121+ -> Event t b
1122+ -> m (Dynamic t a)
10961123accumMaybeDyn f = accumMaybeMDyn $ \v o -> return $ f v o
1097−accumMaybeMDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a)) -> a -> Event t b -> m (Dynamic t a)
1124+
1125+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event'
1126+-- with the provided 'PushM' action, discarding 'Nothing' results.
1127+accumMaybeMDyn
1128+ :: (Reflex t, MonadHold t m, MonadFix m)
1129+ => (a -> b -> PushM t (Maybe a))
1130+ -> a
1131+ -> Event t b
1132+ -> m (Dynamic t a)
10981133accumMaybeMDyn f z e = do
10991134 rec let e' = flip push e $ \o -> do
11001135 v <- sample $ current d'
11011136 f v o
11021137 d' <- holdDyn z e'
11031138 return d'
1104−mapAccumDyn :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> (a, c)) -> a -> Event t b -> m (Dynamic t a, Event t c)
1139+
1140+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event'
1141+-- with a function that both accumulates and produces a value to fire
1142+-- as an 'Event'. Returns both the accumulated value and an 'Event'.
1143+mapAccumDyn
1144+ :: (Reflex t, MonadHold t m, MonadFix m)
1145+ => (a -> b -> (a, c))
1146+ -> a
1147+ -> Event t b
1148+ -> m (Dynamic t a, Event t c)
11051149mapAccumDyn f = mapAccumMaybeDyn $ \v o -> bimap Just Just $ f v o
1106−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)
1150+
1151+-- | Similar to 'mapAccumDyn' except that the combining function is a
1152+-- 'PushM' action.
1153+mapAccumMDyn
1154+ :: (Reflex t, MonadHold t m, MonadFix m)
1155+ => (a -> b -> PushM t (a, c))
1156+ -> a
1157+ -> Event t b
1158+ -> m (Dynamic t a, Event t c)
11071159mapAccumMDyn f = mapAccumMaybeMDyn $ \v o -> bimap Just Just <$> f v o
1108−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)
1160+
1161+-- | Accumulate a 'Dynamic' by folding occurrences of an 'Event' with
1162+-- a function that both optionally accumulates and optionally produces
1163+-- a value to fire as a separate output 'Event'.
1164+-- Note that because 'Nothing's are discarded in both cases, the output
1165+-- 'Event' may fire even though the output 'Dynamic' has not changed, and
1166+-- the output 'Dynamic' may update even when the output 'Event' is not firing.
1167+mapAccumMaybeDyn
1168+ :: (Reflex t, MonadHold t m, MonadFix m)
1169+ => (a -> b -> (Maybe a, Maybe c))
1170+ -> a
1171+ -> Event t b
1172+ -> m (Dynamic t a, Event t c)
11091173mapAccumMaybeDyn f = mapAccumMaybeMDyn $ \v o -> return $ f v o
1110−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)
1174+
1175+-- | Like 'mapAccumMaybeDyn' except that the combining function is a
1176+-- 'PushM' action.
1177+mapAccumMaybeMDyn
1178+ :: (Reflex t, MonadHold t m, MonadFix m)
1179+ => (a -> b -> PushM t (Maybe a, Maybe c))
1180+ -> a
1181+ -> Event t b
1182+ -> m (Dynamic t a, Event t c)
11111183mapAccumMaybeMDyn f z e = do
11121184 rec let e' = flip push e $ \o -> do
11131185 v <- sample $ current d'
@@ -1118,15 +1190,39 @@ mapAccumMaybeMDyn f z e = do
11181190 d' <- holdDyn z $ mapMaybe fst e'
11191191 return (d', mapMaybe snd e')
11201192
1193+-- | Accumulate a 'Behavior' by folding occurrences of an 'Event'
1194+-- with the provided function.
11211195{-# INLINE accumB #-}
1122−accumB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> a) -> a -> Event t b -> m (Behavior t a)
1196+accumB
1197+ :: (Reflex t, MonadHold t m, MonadFix m)
1198+ => (a -> b -> a)
1199+ -> a
1200+ -> Event t b
1201+ -> m (Behavior t a)
11231202accumB f = accumMaybeB $ \v o -> Just $ f v o
1203+
1204+-- | Like 'accumB' except that the combining function is a 'PushM' action.
11241205{-# INLINE accumMB #-}
1125−accumMB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t a) -> a -> Event t b -> m (Behavior t a)
1206+accumMB
1207+ :: (Reflex t, MonadHold t m, MonadFix m)
1208+ => (a -> b -> PushM t a)
1209+ -> a
1210+ -> Event t b
1211+ -> m (Behavior t a)
11261212accumMB f = accumMaybeMB $ \v o -> Just <$> f v o
1213+
1214+-- | Accumulate a 'Behavior' by folding occurrences of an 'Event'
1215+-- with the provided function, discarding 'Nothing' results.
11271216{-# INLINE accumMaybeB #-}
1128−accumMaybeB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> Maybe a) -> a -> Event t b -> m (Behavior t a)
1217+accumMaybeB
1218+ :: (Reflex t, MonadHold t m, MonadFix m)
1219+ => (a -> b -> Maybe a)
1220+ -> a
1221+ -> Event t b
1222+ -> m (Behavior t a)
11291223accumMaybeB f = accumMaybeMB $ \v o -> return $ f v o
1224+
1225+-- | Like 'accumMaybeB' except that the combining function is a 'PushM' action.
11301226{-# INLINE accumMaybeMB #-}
11311227accumMaybeMB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> PushM t (Maybe a)) -> a -> Event t b -> m (Behavior t a)
11321228accumMaybeMB f z e = do
@@ -1135,16 +1231,42 @@ accumMaybeMB f z e = do
11351231 f v o
11361232 d' <- hold z e'
11371233 return d'
1234+
1235+-- | Accumulate a 'Behavior' by folding occurrences of an 'Event'
1236+-- with a function that both accumulates and produces a value to fire
1237+-- as an 'Event'. Returns both the accumulated value and an 'Event'.
11381238{-# INLINE mapAccumB #-}
1139−mapAccumB :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> (a, c)) -> a -> Event t b -> m (Behavior t a, Event t c)
1239+mapAccumB
1240+ :: (Reflex t, MonadHold t m, MonadFix m)
1241+ => (a -> b -> (a, c))
1242+ -> a
1243+ -> Event t b
1244+ -> m (Behavior t a, Event t c)
11401245mapAccumB f = mapAccumMaybeB $ \v o -> bimap Just Just $ f v o
1246+
1247+-- | Like 'mapAccumB' except that the combining function is a 'PushM' action.
11411248{-# INLINE mapAccumMB #-}
1142−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)
1249+mapAccumMB
1250+ :: (Reflex t, MonadHold t m, MonadFix m)
1251+ => (a -> b -> PushM t (a, c))
1252+ -> a
1253+ -> Event t b
1254+ -> m (Behavior t a, Event t c)
11431255mapAccumMB f = mapAccumMaybeMB $ \v o -> bimap Just Just <$> f v o
1256+
1257+-- | Accumulate a 'Behavior' by folding occurrences of an 'Event' with
1258+-- a function that both optionally accumulates and optionally produces
1259+-- a value to fire as a separate output 'Event'. 'Nothing's are discarded.
11441260{-# INLINE mapAccumMaybeB #-}
1145−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)
1261+mapAccumMaybeB
1262+ :: (Reflex t, MonadHold t m, MonadFix m)
1263+ => (a -> b -> (Maybe a, Maybe c))
1264+ -> a
1265+ -> Event t b
1266+ -> m (Behavior t a, Event t c)
11461267mapAccumMaybeB f = mapAccumMaybeMB $ \v o -> return $ f v o
11471268
1269+-- | LIke 'mapAccumMaybeB' except that the combining function is a 'PushM' action.
11481270{-# INLINE mapAccumMaybeMB #-}
11491271mapAccumMaybeMB :: (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)
11501272mapAccumMaybeMB f z e = do
@@ -1299,10 +1421,12 @@ infixl 4 <@
12991421-- Cheap Functions
13001422------------------
13011423
1424+-- | A "cheap" version of 'pushAlways'. See the performance note on 'pushCheap'.
13021425{-# INLINE pushAlwaysCheap #-}
13031426pushAlwaysCheap :: Reflex t => (a -> PushM t b) -> Event t a -> Event t b
13041427pushAlwaysCheap f = pushCheap (fmap Just . f)
13051428
1429+-- | A "cheap" version of 'mapMaybe'. See the performance note on 'pushCheap'.
13061430{-# INLINE mapMaybeCheap #-}
13071431mapMaybeCheap :: Reflex t => (a -> Maybe b) -> Event t a -> Event t b
13081432mapMaybeCheap f = pushCheap $ return . f
@@ -1313,30 +1437,37 @@ fmapMaybeCheap :: Reflex t => (a -> Maybe b) -> Event t a -> Event t b
13131437fmapMaybeCheap = mapMaybeCheap
13141438
13151439
1440+-- | A "cheap" version of 'fforMaybe'. See the performance note on 'pushCheap'.
13161441{-# INLINE fforMaybeCheap #-}
13171442fforMaybeCheap :: Reflex t => Event t a -> (a -> Maybe b) -> Event t b
13181443fforMaybeCheap = flip mapMaybeCheap
13191444
1445+-- | A "cheap" version of 'ffor'. See the performance note on 'pushCheap'.
13201446{-# INLINE fforCheap #-}
13211447fforCheap :: Reflex t => Event t a -> (a -> b) -> Event t b
13221448fforCheap = flip fmapCheap
13231449
1450+-- | A "cheap" version of 'fmap'. See the performance note on 'pushCheap'.
13241451{-# INLINE fmapCheap #-}
13251452fmapCheap :: Reflex t => (a -> b) -> Event t a -> Event t b
13261453fmapCheap f = pushCheap $ return . Just . f
13271454
1455+-- | A "cheap" version of 'tag'. See the performance note on 'pushCheap'.
13281456{-# INLINE tagCheap #-}
13291457tagCheap :: Reflex t => Behavior t b -> Event t a -> Event t b
13301458tagCheap b = pushAlwaysCheap $ \_ -> sample b
13311459
1460+-- | A "cheap" version of 'mergeWithCheap'. See the performance note on 'pushCheap'.
13321461{-# INLINE mergeWithCheap #-}
13331462mergeWithCheap :: Reflex t => (a -> a -> a) -> [Event t a] -> Event t a
13341463mergeWithCheap = mergeWithCheap' id
13351464
1465+-- | A "cheap" version of 'mergeWithCheap''. See the performance note on 'pushCheap'.
13361466{-# INLINE mergeWithCheap' #-}
13371467mergeWithCheap' :: Reflex t => (a -> b) -> (b -> b -> b) -> [Event t a] -> Event t b
13381468mergeWithCheap' f g = mergeWithFoldCheap' $ foldl1 g . fmap f
13391469
1470+-- | A "cheap" version of 'mergeWithFoldCheap''. See the performance note on 'pushCheap'.
13401471{-# INLINE mergeWithFoldCheap' #-}
13411472mergeWithFoldCheap' :: Reflex t => (NonEmpty a -> b) -> [Event t a] -> Event t b
13421473mergeWithFoldCheap' f es =
@@ -1349,28 +1480,6 @@ mergeWithFoldCheap' f es =
13491480-- Deprecated functions
13501481--------------------------------------------------------------------------------
13511482
1352−-- | Create a new 'Event' that occurs if at least one of the supplied 'Event's
1353−-- occurs. If both occur at the same time they are combined using 'mappend'.
1354−{-# DEPRECATED appendEvents "If a 'Semigroup a' instance is available, use 'mappend'; otherwise, use 'alignWith (mergeThese mappend)' instead" #-}
1355−appendEvents :: (Reflex t, Monoid a) => Event t a -> Event t a -> Event t a
1356−appendEvents = alignWith $ mergeThese mappend
1357−
1358−-- | Alias for 'headE'
1359−{-# DEPRECATED onceE "Use 'headE' instead" #-}
1360−onceE :: MonadHold t m => Event t a -> m (Event t a)
1361−onceE = headE
1362−
1363−-- | Run both sides of a 'These' monadically, combining the results.
1364−{-# DEPRECATED sequenceThese "Use bisequenceA or bisequence from the bifunctors package instead" #-}
1365−#ifdef USE_TEMPLATE_HASKELL
1366−{-# ANN sequenceThese "HLint: ignore Use fmap" #-}
1367−#endif
1368−sequenceThese :: Monad m => These (m a) (m b) -> m (These a b)
1369−sequenceThese t = case t of
1370− This ma -> fmap This ma
1371− These ma mb -> liftM2 These ma mb
1372− That mb -> fmap That mb
1373−
13741483{-# 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'. " #-}
13751484switchPromptly :: (Reflex t, MonadHold t m) => Event t a -> Event t (Event t a) -> m (Event t a)
13761485switchPromptly = switchHoldPromptly