on develop help sign in
Docs for Reflex.Class
commitee8eafb0df91894c2f58f8e1e072fb1948ff7245 authorMoritz Kiefer <moritz.kiefer@purelyfunctional.org> dateWed 29 Apr 2015, 17:40 (11 years ago) parent7dbb590
1 file changed+57−1
src/Reflex/Class.hs+57−1
src/Reflex/Class.hs+57−1
@@ -70,9 +70,12 @@ instance MonadHold t m => MonadHold t (ReaderT r m) where
7070-- Convenience functions
7171--------------------------------------------------------------------------------
7272
73+-- | Create an Event from another Event.
74+-- The provided function can sample 'Behavior's and hold 'Event's.
7375pushAlways :: Reflex t => (a -> PushM t b) -> Event t a -> Event t b
7476pushAlways f e = push (liftM Just . f) e
7577
78+-- | Flipped version of 'fmap'.
7679ffor :: Functor f => f a -> (a -> b) -> f b
7780ffor = flip fmap
7881
@@ -80,12 +83,17 @@ instance Reflex t => Functor (Behavior t) where
8083 fmap f = pull . liftM f . sample
8184
8285--TODO: See if there's a better class in the standard libraries already
86+-- | A class for values that combined filtering and mapping using 'Maybe'.
8387class FunctorMaybe f where
88+ -- | Combined mapping and filtering function.
8489 fmapMaybe :: (a -> Maybe b) -> f a -> f b
8590
91+-- | Flipped version of 'fmapMaybe'.
8692fforMaybe :: FunctorMaybe f => f a -> (a -> Maybe b) -> f b
8793fforMaybe = flip fmapMaybe
8894
95+-- | Filter 'f a' using the provided predicate.
96+-- Relies on 'fforMaybe'.
8997ffilter :: FunctorMaybe f => (a -> Bool) -> f a -> f a
9098ffilter f = fmapMaybe $ \x -> if f x then Just x else Nothing
9199
@@ -95,6 +103,8 @@ instance Reflex t => FunctorMaybe (Event t) where
95103instance Reflex t => Functor (Event t) where
96104 fmap f = fmapMaybe $ Just . f
97105
106+-- | Create a new 'Event' by combining each occurence with the next value
107+-- of the list using the supplied function. Blocks 'Event' when the list is empty.
98108zipListWithEvent :: (Reflex t, MonadHold t m, MonadFix m) => (a -> b -> c) -> [a] -> Event t b -> m (Event t c)
99109zipListWithEvent f l e = do
100110 rec lb <- hold l eTail
@@ -107,22 +117,33 @@ zipListWithEvent f l e = do
107117 lb `seq` eBoth `seq` eTail `seq` return ()
108118 return $ fmap fst eBoth
109119
110−-- | Replace the occurrence value of the Event with the value of the Behavior at the time of the occurrence
120+-- | Replace the occurrence value of the 'Event' with the value of the
121+-- 'Behavior' at the time of the occurrence.
111122tag :: Reflex t => Behavior t b -> Event t a -> Event t b
112123tag b = pushAlways $ \_ -> sample b
113124
125+-- | Create a new 'Event' by combining each occurence with the current
126+-- value of the 'Behavior'. Doesn't occur if the combining function
127+-- returns Nothing
114128attachWithMaybe :: Reflex t => (a -> b -> Maybe c) -> Behavior t a -> Event t b -> Event t c
115129attachWithMaybe f b e = flip push e $ \o -> liftM (flip f o) $ sample b
116130
131+-- | Create a new 'Event' that occurs when the supplied 'Event' occurs
132+-- by combining it with the current value of the 'Behavior'.
117133attachWith :: Reflex t => (a -> b -> c) -> Behavior t a -> Event t b -> Event t c
118134attachWith f = attachWithMaybe $ \a b -> Just $ f a b
119135
136+-- | Create a new 'Event' that combines occurences of supplied 'Event'
137+-- with the current value of the 'Behavior'.
120138attach :: Reflex t => Behavior t a -> Event t b -> Event t (a, b)
121139attach = attachWith (,)
122140
141+-- | Alias for 'headE'
123142onceE :: (Reflex t, MonadHold t m, MonadFix m) => Event t a -> m (Event t a)
124143onceE = headE
125144
145+-- | Create a new 'Event' that only occurs on the first occurence of
146+-- the supplied 'Event'.
126147headE :: (Reflex t, MonadHold t m, MonadFix m) => Event t a -> m (Event t a)
127148headE e = do
128149 rec be <- hold e $ fmap (const never) e'
@@ -130,24 +151,36 @@ headE e = do
130151 e' `seq` return ()
131152 return e'
132153
154+-- | Create a new 'Event' that occurs on all but the first occurence
155+-- of the supplied 'Event'.
133156tailE :: (Reflex t, MonadHold t m, MonadFix m) => Event t a -> m (Event t a)
134157tailE e = liftM snd $ headTailE e
135158
159+-- | Create a tuple of two 'Event's with the first one occuring only
160+-- the first time the supplied 'Event' occurs and the second occuring
161+-- on all but the first occurence.
136162headTailE :: (Reflex t, MonadHold t m, MonadFix m) => Event t a -> m (Event t a, Event t a)
137163headTailE e = do
138164 eHead <- headE e
139165 be <- hold never $ fmap (const e) eHead
140166 return (eHead, switch be)
141167
168+-- | Split the supplied 'Event' into two individual 'Event's occuring
169+-- at the same time with the respective values from the tuple.
142170splitE :: Reflex t => Event t (a, b) -> (Event t a, Event t b)
143171splitE e = (fmap fst e, fmap snd e)
144172
173+-- | Print the supplied 'String' and the value of the 'Event' on each
174+-- occurence. This should /only/ be used for debugging.
145175traceEvent :: (Reflex t, Show a) => String -> Event t a -> Event t a
146176traceEvent s = traceEventWith $ \x -> s <> ": " <> show x
147177
178+-- | Print the output of the supplied function on each occurence of
179+-- the 'Event'. This should /only/ be used for debugging.
148180traceEventWith :: Reflex t => (a -> String) -> Event t a -> Event t a
149181traceEventWith f = push $ \x -> trace (f x) $ return $ Just x
150182
183+-- | Tag type for 'Either' to use it as a 'DSum'.
151184data EitherTag l r a where
152185 LeftTag :: EitherTag l r l
153186 RightTag :: EitherTag l r r
@@ -175,16 +208,19 @@ instance (Show l, Show r) => ShowTag (EitherTag l r) where
175208 LeftTag -> showsPrec n a
176209 RightTag -> showsPrec n a
177210
211+-- | Convert 'Either' to a 'DSum'. Inverse of 'dsumToEither'.
178212eitherToDSum :: Either a b -> DSum (EitherTag a b)
179213eitherToDSum = \case
180214 Left a -> LeftTag :=> a
181215 Right b -> RightTag :=> b
182216
217+-- | Convert 'DSum' to 'Either'. Inverse of 'eitherToDSum'.
183218dsumToEither :: DSum (EitherTag a b) -> Either a b
184219dsumToEither = \case
185220 LeftTag :=> a -> Left a
186221 RightTag :=> b -> Right b
187222
223+-- | Extract the values of a 'DMap' of 'EitherTag's.
188224dmapToThese :: DMap (EitherTag a b) -> Maybe (These a b)
189225dmapToThese m = case (DMap.lookup LeftTag m, DMap.lookup RightTag m) of
190226 (Nothing, Nothing) -> Nothing
@@ -192,9 +228,13 @@ dmapToThese m = case (DMap.lookup LeftTag m, DMap.lookup RightTag m) of
192228 (Nothing, Just b) -> Just $ That b
193229 (Just a, Just b) -> Just $ These a b
194230
231+-- | Create a new 'Event' that occurs if at least one of the supplied
232+-- 'Event's occurs. If both occur at the same time they are combined
233+-- using 'mappend'.
195234appendEvents :: (Reflex t, Monoid a) => Event t a -> Event t a -> Event t a
196235appendEvents e1 e2 = fmap (mergeThese mappend) $ align e1 e2
197236
237+{-# DEPRECATED sequenceThese "Use bisequenceA from the bifunctors package instead" #-}
198238sequenceThese :: Monad m => These (m a) (m b) -> m (These a b)
199239sequenceThese t = case t of
200240 This ma -> liftM This ma
@@ -206,19 +246,33 @@ instance (Semigroup a, Reflex t) => Monoid (Event t a) where
206246 mappend a b = mconcat [a, b]
207247 mconcat = fmap sconcat . mergeList
208248
249+-- | Create a new 'Event' that occurs if at least one of the 'Event's
250+-- in the list occurs. If multiple occur at the same time they are
251+-- folded from the left.
209252mergeWith :: Reflex t => (a -> a -> a) -> [Event t a] -> Event t a
210253mergeWith f es = fmap (Prelude.foldl1 f . map (\(Const2 _ :=> v) -> v) . DMap.toList) $ merge $ DMap.fromList $ map (\(k, v) -> WrapArg (Const2 k) :=> v) $ zip [0 :: Int ..] es
211254
255+-- | Create a new 'Event' that occurs if at least one of the 'Event's
256+-- in the list occurs. If multiple occur at the same time the value is
257+-- the value of the leftmost event.
212258leftmost :: Reflex t => [Event t a] -> Event t a
213259leftmost = mergeWith const
214260
261+-- | Create a new 'Event' that occurs if at least one of the 'Event's
262+-- in the list occurs and has a list of the values of all 'Event's
263+-- occuring at that time.
215264mergeList :: Reflex t => [Event t a] -> Event t (NonEmpty a)
216265mergeList [] = never
217266mergeList es = mergeWith (<>) $ map (fmap (:|[])) es
218267
268+-- | Create a new 'Event' combining the map of 'Event's into an
269+-- 'Event' that occurs if at least one of them occurs and has a map of
270+-- values of all 'Event's occuring at that time.
219271mergeMap :: (Reflex t, Ord k) => Map k (Event t a) -> Event t (Map k a)
220272mergeMap = fmap dmapToMap . merge . mapWithFunctorToDMap
221273
274+-- | Split the event into an 'EventSelector' that allows efficient
275+-- selection of the individual 'Event's.
222276fanMap :: (Reflex t, Ord k) => Event t (Map k a) -> EventSelector t (Const2 k a)
223277fanMap = fan . fmap mapToDMap
224278
@@ -234,5 +288,7 @@ instance Reflex t => Align (Event t) where
234288 nil = never
235289 align ea eb = fmapMaybe dmapToThese $ merge $ DMap.fromList [WrapArg LeftTag :=> ea, WrapArg RightTag :=> eb]
236290
291+-- | Create a new 'Event' that only occurs if the supplied 'Event'
292+-- occurs and the 'Behavior' is true at the time of occurence.
237293gate :: Reflex t => Behavior t Bool -> Event t a -> Event t a
238294gate = attachWithMaybe $ \allow a -> if allow then Just a else Nothing