on develop help sign in
Adds the `<@>` and `<@` operators.

This is useful for combining several Behaviors or Dynamics together and sampling them with an Event. There is an example in the Haddocks for the typeclass that might help explain further / motivate the addition. These operators are defined for `Behavior` but not `Dynamic`. This removes the need for a typeclass, although it can be added in later if people identify a need for it.

commitf08911e5b2c2fa973ddbc92809ca60e3a5da10f5 authorDave Laing <dave.laing.80@gmail.com> dateWed 28 Sep 2016, 11:59 (10 years ago) parent39301ec
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