on develop help sign in
Merge pull request #66 from dalaing/attachapply

Adds the `AttachApply` typeclass.

commit605a47bb4f19e1f6e13ddad49ebb80c7f474b6c9 authorRyan Trinkle <ryan.trinkle@gmail.com> dateWed 19 Apr 2017, 08:43 (9 years ago) parent39301ecf08911e
1 file changed+72
src/Reflex/Class.hs+72
src/Reflex/Class.hs+72
@@ -80,6 +80,8 @@ module Reflex.Class
8080 , mapAccumMaybe_
8181 , mapAccumMaybeM_
8282 , zipListWithEvent
83+ , (<@>)
84+ , (<@)
8385 , headE
8486 , tailE
8587 , headTailE
@@ -916,6 +918,76 @@ zipListWithEvent f l e = do
916918 _ -> (Nothing, Nothing) --TODO: Unsubscribe the event?
917919 mapAccumMaybe_ f' l e
918920
921+infixl 4 <@>
922+
923+-- | This is used to sample the value of a 'Behavior' using an 'Event'.
924+--
925+-- The '<@>' operator is intended to be used in conjunction with
926+-- the 'Applicative' instance for 'Behavior'.
927+--
928+-- This is useful when we want to combine the values of one 'Event' and
929+-- the value of several 'Behavior's at the time the 'Event' is firing.
930+--
931+-- If we have:
932+--
933+-- > f :: a -> b -> c -> d
934+-- > b1 :: Behavior t a
935+-- > b2 :: Behavior t b
936+-- > e :: Event t c
937+--
938+-- then we can do:
939+--
940+-- > f <$> b1 <*> b2 <@> e :: Event t d
941+--
942+-- in order to apply the function 'f' to the relevant values.
943+--
944+-- The alternative would be something like:
945+--
946+-- > attachWith (\(x1, x2) y -> f x1 x2 y) ((,) <$> b1 <*> b2) e :: Event t d
947+--
948+-- or a variation involing a custom data type to hold the combination of
949+-- 'Behavior's even when that combination might only ever be used by 'f'.
950+--
951+-- A more suggestive example might be:
952+--
953+-- > handleMouse <$> bPlayerState <*> bMousePosition <*> eMouseClick :: Event t (GameState -> GameState)
954+--
955+(<@>) :: Reflex t => Behavior t (a -> b) -> Event t a -> Event t b
956+(<@>) b = push $ \x -> do
957+ f <- sample b
958+ return . Just . f $ x
959+
960+infixl 4 <@
961+
962+-- | An version of '<@>' that does not use the value of the 'Event'.
963+--
964+-- Alternatively, it is 'tag' in operator form.
965+--
966+-- This is useful when we want to combine the values of several
967+-- 'Behavior's at particular points in time using an 'Applicative'
968+-- style syntax.
969+--
970+-- If we have:
971+--
972+-- > g :: a -> b -> d
973+-- > b1 :: Behavior t a
974+-- > b2 :: Behavior t b
975+-- > e :: Event t c
976+--
977+-- where 'e' is firing at the points in time of interest.
978+--
979+-- Then we can use '<@':
980+--
981+-- > g <$> b1 <*> b2 <@ e :: Event t d
982+--
983+-- to combine the values of 'b1' and 'b2' at each of those points of time,
984+-- with the function 'g' being used to combine the values.
985+--
986+-- This is the same as '<@>' except that the 'Event' is being used only
987+-- to act as a trigger.
988+(<@) :: (Reflex t) => Behavior t b -> Event t a -> Event t b
989+(<@) = tag
990+
919991-- | A 'Monad' that supports adjustment over time. After an action has been
920992-- run, if the given events fire, it will adjust itself so that its net effect
921993-- is as though it had originally been run with the new value. Note that there