on develop help sign in
reflex/Quickref.md
315 lines 15 kB history raw
1# Reflex Quick(ish) Reference
3## Typeclasses
5Many Reflex functions operate in monadic context `m a`, where the monad 'm' supports various additional typeclasses such as MonadWidget, MonadHold, or MonadSample in addition to Monad itself. The actual 'm' in use will be determined by the top-level entry point of the FRP host (such as Reflex-Dom -- see the bottom of the Reflex-Dom quick reference for details).
7The function signatures here have been simplified by removing many typeclass constraints and adding simple annotations to each function. Also the ubiquitous 't' type parameter has been removed.
9Some of these functions are *pure*: They operate on Events, Behaviors, or Dynamics uniformly without regard to the "current time". Other functions must operate in some monadic context, because they produce a result "as of now" (e.g., any function that takes an "initial" value, or returns a "current" value). Annotations are used to distinguish these cases:
11```haskell
12[ ] -- Pure function
13[S] -- Function runs in any monad supporting MonadSample
14[H] -- Function runs in any monad supporting MonadHold
15```
16Since MonadHold depends on MonadSample, any [S] function also runs in [H] context.
18## Functions producing Event
20```haskell
21-- Trivial Event
22[ ] never :: Event a
24-- Extract Event from Dynamic
25[ ] updated :: Dynamic a -> Event a
27-- Transform Event to Event using function
28[ ] fmap :: (a -> b) -> Event a -> Event b
29[ ] fmapMaybe :: (a -> Maybe b) -> Event a -> Event b
30[ ] ffilter :: (a -> Bool) -> Event a -> Event a
31[ ] ffor :: Event a -> (a -> b) -> Event b
32[ ] fforMaybe :: Event a -> (a -> Maybe b) -> Event b
33[ ] <$ :: a -> Event b -> Event a
35-- Event to identical Event with debug trace. (Only prints if Event is ultimately used.)
36[ ] traceEvent :: Show a => String -> Event a -> Event a
37[ ] traceEventWith :: (a -> String) -> Event a -> Event a
39-- Transform Event to Event by sampling Behavior or Dynamic
40[ ] gate :: Behavior Bool -> Event a -> Event a
41[ ] tag :: Behavior a -> Event b -> Event a
42[ ] tagPromptlyDyn :: Dynamic a -> Event b -> Event a
43[ ] attach :: Behavior a -> Event b -> Event (a, b)
44[ ] attachPromptlyDyn :: Dynamic a -> Event b -> Event (a, b)
45[ ] attachWith :: (a -> b -> c) -> Behavior a -> Event b -> Event c
46[ ] attachPromptlyDynWith :: (a -> b -> c) -> Dynamic a -> Event b -> Event c
47[ ] attachWithMaybe :: (a -> b -> Maybe c) -> Behavior a -> Event b -> Event c
48[ ] attachPromptlyDynWithMaybe :: (a -> b -> Maybe c) -> Dynamic a -> Event b -> Event c
49[ ] <@> :: Behavior (a -> b) -> Event a -> Event b
50[ ] <@ :: Behavior a -> Event b -> Event a
52-- Combine multiple Events
53[ ] <> :: Semigroup a => Event a -> Event a -> Event a
54[ ] difference :: Event a -> Event b -> Event a
55[ ] align :: Event a -> Event b -> Event (These a b)
56[ ] alignWith :: (These a b -> c) -> Event a -> Event b -> Event c
57 -- Note align functions from Data.Align in semialign package
58[ ] mergeWith :: (a -> a -> a) -> [Event a] -> Event a
59[ ] leftmost :: [Event a] -> Event a
60[ ] mergeList :: [Event a] -> Event (NonEmpty a)
61[ ] merge :: GCompare k => DMap k Event -> Event (DMap k Identity)
62[ ] mergeMap :: Ord k => Map k (Event a) -> Event (Map k a)
64-- Efficient one-to-many fanout
65[ ] fanMap :: Ord k => Event (Map k a) -> EventSelector (Const2 k a)
66[ ] fan :: GCompare k => Event (DMap k Identity) -> EventSelector k
67[ ] select :: EventSelector k -> k a -> Event a
68[ ] fanEither :: Event (Either a b) -> (Event a, Event b)
69[ ] fanThese :: Event (These a b) -> (Event a, Event b)
71-- Event to Event via function that can sample current values
72[ ] push :: (a -> m (Maybe b)) -> Event a -> Event b
73[ ] pushAlways :: (a -> m b ) -> Event a -> Event b
74 -- Note supplied function operates in [H] context
76-- Split Event into next occurrence and all other future occurrences, as of now.
77[H] headE :: Event a -> m (Event a)
78[H] tailE :: Event a -> m (Event a)
79[H] headTailE :: Event a -> m (Event a, Event a)
80```
82## Functions producing Behavior
84```haskell
85-- Trivial Behavior
86[ ] constant :: a -> Behavior a
88-- Extract Behavior from Dynamic
89[ ] current :: Dynamic a -> Behavior a
91-- Create Behavior with given initial value, updated when the Event fires.
92[H] hold :: a -> Event a -> m (Behavior a)
94-- Transform Behavior to Behavior using function
95[ ] fmap :: (a -> b) -> Behavior a -> Behavior b
96[ ] ffor :: Behavior a -> (a -> b) -> Behavior b
97[ ] <*> :: Behavior (a -> b) -> Behavior a -> Behavior b
98[ ] >>= :: Behavior a -> (a -> Behavior b) -> Behavior b
99[ ] <> :: Monoid a => Behavior a -> Behavior a -> Behavior a
100-- ... plus many more due to typeclass membership
102-- Combine multiple behaviors via applicative instance
103[ ] ffor2 :: Behavior a -> Behavior b -> (a -> b -> c) -> Behavior c
104[ ] ffor3 :: Behavior a -> Behavior b -> Behavior c -> (a -> b -> c -> d) -> Behavior d
106-- Behavior to Behavior by sampling current values
107[S] sample :: Behavior a -> m a
108[ ] pull :: m a -> Behavior a
109 -- Note supplied value is in [S] context
110```
112## Functions producing Dynamic
114```haskell
115-- Trivial Dynamic
116[ ] constDyn :: a -> Dynamic a
118-- Create Dynamic with given initial value, updated (various ways) when the Event fires.
119[H] holdDyn :: a -> Event a -> m (Dynamic a)
120[H] foldDyn :: (a -> b -> b ) -> b -> Event a -> m (Dynamic b)
121[H] foldDynMaybe :: (a -> b -> Maybe b ) -> b -> Event a -> m (Dynamic b)
122[H] foldDynM :: (a -> b -> m' b ) -> b -> Event a -> m (Dynamic b)
123[H] foldDynMaybeM :: (a -> b -> m' (Maybe b)) -> b -> Event a -> m (Dynamic b)
124 -- Note m' supplies [H] context
126-- Initial value is 0; counts Event firings from now.
127[H] count :: Num b => Event a -> m (Dynamic b)
128-- Initial Bool value is supplied; toggles at each Event firing.
129[H] toggle :: Bool -> Event a -> m (Dynamic Bool)
131-- Transform Dynamic to Dynamic using function
132[ ] ffor :: Dynamic a -> (a -> b) -> Dynamic b
133[ ] fmap :: (a -> b) -> Dynamic a -> Dynamic b
134[ ] splitDynPure :: Dynamic (a, b) -> (Dynamic a, Dynamic b)
136-- Combine multiple Dynamics
137[ ] mconcat :: Monoid a => [Dynamic a] -> Dynamic a
138[ ] distributeDMapOverDynPure :: GCompare k => DMap (WrapArg Dynamic k) -> Dynamic (DMap k)
139[ ] <*> :: Dynamic (a -> b) -> Dynamic a -> Dynamic b
140[ ] >>= :: Dynamic a -> (a -> Dynamic b) -> Dynamic b
141[ ] zipDynWith :: (a -> b -> c) -> Dynamic a -> Dynamic b -> Dynamic c
143-- Combine multiple dynamics via applicative instance
144[ ] ffor2 :: Dynamic a -> Dynamic b -> (a -> b -> c) -> Dynamic c
145[ ] ffor3 :: Dynamic a -> Dynamic b -> Dynamic c -> (a -> b -> c -> d) -> Dynamic d
147-- Efficient one-to-many fanout
148[ ] demux :: Ord k => Dynamic k -> Demux k
149[ ] demuxed :: Eq k => Demux k -> k -> Dynamic Bool
151-- Dynamic to Dynamic, removing updates w/o value change
152[H] holdUniqDyn :: Eq a => Dynamic a -> m (Dynamic a)
153[H] holdUniqDynBy :: (a -> a -> Bool) -> Dynamic t a -> m (Dynamic t a)
155-- Dynamic to identical Dynamic with debug trace. (Only prints if Dynamic is ultimately used.)
156[ ] traceDyn :: Show a => String -> Dynamic a -> Dynamic a
157[ ] traceDynWith :: (a -> String) -> Dynamic a -> Dynamic a
158```
160## Flattening functions
162These functions flatten nested types such as Event-of-Event, Behavior-of-Event, Event-of-Behavior etc, removing the outer wrapper.
164For Events, the returned Event fires whenever the latest Event supplied by the wrapper fires. There are differences in how the functions handle *coincidences* -- situations where the old or new Event fires at the same instant that we switch from old to new. In some cases, the output Event tracks the old Event at the instant of switchover, while in other cases it tracks the new Event.
166```haskell
167-- Flatten Behavior-of-Event to Event. Old Event is used during switchover.
168[ ] switch :: Behavior (Event a) -> Event a
170-- Flatten Dynamic-of-Event to Event. New Event is used immediately.
171[ ] switchDyn :: Dynamic (Event a) -> Event a
173-- Flatten Event-of-Event to Event that fires when both wrapper AND new Event fire.
174[ ] coincidence :: Event (Event a) -> Event a
176-- Flatten Behavior-of-Behavior to Behavior. Behavior is an instance of Monad,
177-- so the 'join' function from 'Control.Monad' suffices. The output of 'join' is
178-- a Behavior whose value is equal to the current value of the current value of
179-- the input.
180[ ] join :: Behavior (Behavior a) -> Behavior a
183-- Flatten Dynamic-of-Dynamic to Dynamic. New Dynamic is used immediately.
184-- Output updated whenever inner OR outer Dynamic updates.
185[ ] join :: Dynamic (Dynamic a) -> Dynamic a
186[ ] joinDynThroughMap :: Ord k => Dynamic (Map k (Dynamic a)) -> Dynamic (Map k a)
188-- Analogous to 'hold': Create a Behavior that is initially identical to the
189-- supplied Behavior. Updated to track a new Behavior whenever the Event fires.
190[H] switcher :: Behavior a -> Event (Behavior a) -> m (Behavior a)
192-- Similar to above, for Events. Created Event initially tracks the first argument.
193-- At switchover, the output Event immediately tracks the new Event.
194[H] switchHold :: Event a -> Event (Event a) -> m (Event a)
195```
197## Typeclasses to introspect and modify an FRP network.
199The functions mentioned above are used to create a static FRP network.
200There are additional typeclasses that can be used to modify the FRP network, to have it interact with IO action, or to introspect the building of the network.
202The typeclasses and their associated annotations include:
204- `PostBuild`
205 Fire an Event when an FRP network has been set up.
206 ```haskell
207 [B] -- Function runs in any monad supporting PostBuild
208 ```
210- `Adjustable`
211 Use Events to add or remove pieces of an FRP network.
212 ```haskell
213 [A] -- Function runs in any monad supporting Adjustable
214 ```
216- `TriggerEvent`
217 Create new externally-fired Events from within an FRP network.
218 ```haskell
219 [T] -- Function runs in any monad supporting TriggerEvent
220 ```
222- `PerformEvent`
223 Use Events to trigger IO actions and to collect their results.
224 ```haskell
225 [P] -- Function runs in any monad supporting PerformEvent
226 ```
228## Startup
230```haskell
231-- One-shot Event that is triggered once the FRP network has been built
232[B] getPostBuild :: m (Event ())
233```
235## Collection management functions
237```haskell
238-- Turn a Dynamic key/value map into a set of dynamically-changing widgets.
239[H,A,B] listWithKey :: Ord k =>
240 Dynamic (Map k v) -> (k -> Dynamic v -> m a ) -> m (Dynamic (Map k a))
242-- Same as above where the widget constructor doesn't care about the key.
243[H,A,B] list :: Ord k =>
244 Dynamic (Map k v) -> ( Dynamic v -> m a ) -> m (Dynamic (Map k a))
246-- Even simpler version where there are no keys and we just use a list.
247[H,A,B] simpleList ::
248 Dynamic [v] -> ( Dynamic v -> m a ) -> m (Dynamic [a])
250-- Like listWithKey specialized for widgets returning (Event a).
251[H,A,B] listViewWithKey :: Ord k =>
252 Dynamic (Map k v) -> (k -> Dynamic v -> m (Event a)) -> m (Event (Map k a))
254-- Create a dynamically-changing set of widgets, one of which is selected at any time.
255[H,A,B] selectViewListWithKey_ :: Ord k => Dynamic k ->
256 Dynamic (Map k v) -> (k -> Dynamic v -> Dynamic Bool -> m (Event a)) -> m (Event k)
258-- Same as listWithKey, but takes initial values and an updates Event instead of a Dynamic.
259[H,A] listWithKeyShallowDiff :: Ord k =>
260 Map k v -> Event (Map k (Maybe v)) -> (k -> v -> Event v -> m a) -> m (Dynamic (Map k a))
261```
263## Creating new events from within an FRP network.
265```haskell
266-- Create a new Event and a function that will cause the Event to fire, from within an FRP network
267[T] newTriggerEvent :: m (Event a, a -> IO ())
268```
270## Connecting to the real world (I/O)
272```haskell
273-- Run side-effecting actions in Event when it occurs; returned Event contains
274-- results. Side effects run in the (Performable m) monad which is associated with
275-- the (PerformEvent t m) typeclass constraint.
276-- This allows for working with IO when a ((MonadIO (Performable m)) constraint is available.
277[P] performEvent :: Event (Performable m a ) -> m (Event a)
279-- Just run side-effects; no return Event
280[P] performEvent_ :: Event (Performable m ()) -> m ()
282-- Actions run asynchronously; actions are given a callback to send return values
283[P,T] performEventAsync :: Event ((a -> IO ()) -> Performable m ()) -> m (Event a)
284```
286### Time
288```haskell
289-- Create Event at given interval with given basis time.
290[P,T] tickLossy :: NominalDiffTime -> UTCTime -> m (Event t TickInfo)
292-- Delay an Event's occurrences by a given amount in seconds.
293[P,T] delay :: NominalDiffTime -> Event t a -> m (Event t a)
294```
296## Networks
298```haskell
299-- Functions from Reflex.Adjustable / Reflex.Network used to deal with Dynamics/Events carrying (m a)
301[A] runWithReplace :: m a -> Event t (m b) -> m (a, Event t b)
303-- Given a Dynamic of network-creating actions, create a network that is recreated whenever the Dynamic updates.
304-- The returned Event of network results occurs when the Dynamic does. Note: Often, the type a is an Event,
305-- in which case the return value is an Event-of-Events that would typically be flattened (via switchHold).
306[P,A] networkView :: Dynamic (m a) -> m (Event a)
308-- Given an initial network and an Event of network-creating actions, create a network that is recreated whenever the
309-- Event fires. The returned Dynamic of network results occurs when the Event does. Note: Often, the type a is an
310-- Event, in which case the return value is a Dynamic-of-Events that would typically be flattened.
311[H,A] networkHold :: m a -> Event (m a) -> m (Dynamic a)
313-- Render a placeholder network to be shown while another network is not yet done building
314[P,A] untilReady :: m a -> m b -> m (a, Event b)
315```