on develop help sign in
Merge pull request #22 from jeffreyrosenbluth/develop

add switcher function and MonadFix (PushM t) constraint

commit0675c70717ab389bce4e69e5ab2c0e58507516c2 authorRyan Trinkle <ryan.trinkle@gmail.com> dateTue 21 Jul 2015, 21:31 (11 years ago) parent29c426d254c409
1 file changed+10−4
src/Reflex/Class.hs+10−4
src/Reflex/Class.hs+10−4
@@ -27,7 +27,7 @@ import Prelude hiding (mapM, mapM_, sequence, sequence_, foldl)
2727
2828import Debug.Trace (trace)
2929
30−class (MonadHold t (PushM t), MonadSample t (PullM t), Functor (Event t), Functor (Behavior t)) => Reflex t where
30+class (MonadHold t (PushM t), MonadSample t (PullM t), MonadFix (PushM t), Functor (Event t), Functor (Behavior t)) => Reflex t where
3131 -- | A container for a value that can change over time. Behaviors can be sampled at will, but it is not possible to be notified when they change
3232 data Behavior t :: * -> *
3333 -- | A stream of occurrences. During any given frame, an Event is either occurring or not occurring; if it is occurring, it will contain a value of the given type (its "occurrence type")
@@ -46,7 +46,7 @@ class (MonadHold t (PushM t), MonadSample t (PullM t), Functor (Event t), Functo
4646 type PullM t :: * -> *
4747 -- | Merge a collection of events; the resulting Event will only occur if at least one input event is occuring, and will contain all of the input keys that are occurring simultaneously
4848 merge :: GCompare k => DMap (WrapArg (Event t) k) -> Event t (DMap k) --TODO: Generalize to get rid of DMap use --TODO: Provide a type-level guarantee that the result is not empty
49− -- | Efficiently fan-out an event to many destinations. This function should be partially applied, and then the result applied repeatedly to create child events
49+ -- | Efficiently fan-out an event to many destinations. This function should be partially applied, and then the result applied repeatedly to create child events
5050 fan :: GCompare k => Event t (DMap k) -> EventSelector t k --TODO: Can we help enforce the partial application discipline here? The combinator is worthless without it
5151 -- | Create an Event that will occur whenever the currently-selected input Event occurs
5252 switch :: Behavior t (Event t a) -> Event t a
@@ -110,7 +110,7 @@ instance MonadHold t m => MonadHold t (ContT r m) where
110110-- | Create an Event from another Event.
111111-- The provided function can sample 'Behavior's and hold 'Event's.
112112pushAlways :: Reflex t => (a -> PushM t b) -> Event t a -> Event t b
113−pushAlways f e = push (liftM Just . f) e
113+pushAlways f = push (liftM Just . f)
114114
115115-- | Flipped version of 'fmap'.
116116ffor :: Functor f => f a -> (a -> b) -> f b
@@ -298,7 +298,7 @@ dmapToThese m = case (DMap.lookup LeftTag m, DMap.lookup RightTag m) of
298298-- 'Event's occurs. If both occur at the same time they are combined
299299-- using 'mappend'.
300300appendEvents :: (Reflex t, Monoid a) => Event t a -> Event t a -> Event t a
301−appendEvents e1 e2 = fmap (mergeThese mappend) $ align e1 e2
301+appendEvents e1 e2 = mergeThese mappend <$> align e1 e2
302302
303303{-# DEPRECATED sequenceThese "Use bisequenceA or bisequence from the bifunctors package instead" #-}
304304sequenceThese :: Monad m => These (m a) (m b) -> m (These a b)
@@ -358,3 +358,9 @@ instance Reflex t => Align (Event t) where
358358-- occurs and the 'Behavior' is true at the time of occurence.
359359gate :: Reflex t => Behavior t Bool -> Event t a -> Event t a
360360gate = attachWithMaybe $ \allow a -> if allow then Just a else Nothing
361+
362+-- | Create a new behavior given a starting behavior and switch to a the
363+-- behvior carried by the event when it fires.
364+switcher :: (Reflex t, MonadHold t m)
365+ => Behavior t a -> Event t (Behavior t a) -> m (Behavior t a)
366+switcher b eb = pull . (sample <=< sample) <$> hold b eb