1# Reflex / Reflex-Dom Quick(ish) Reference
5Many Reflex functions operate in monadic context `X a`, where the monadic type X supports various additional typeclasses such as MonadWidget, MonadHold, or MonadSample in addition to Monad itself. For Reflex-Dom users, the type X will generally be `Widget Spider (Gui Spider (WithWebView SpiderHost) (HostFrame Spider))`, from the Reflex-Dom main entry point:
8mainWidget :: Widget Spider (Gui Spider (WithWebView SpiderHost) (HostFrame Spider)) () -> IO ()
11The 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.
13Functions annotated with "[ ]" are *pure*: They operate on Events, Behaviors, or Dynamics uniformly without regard to the "current time".
15Other functions must operate in some monadic context, because they produce a result "as of now". The annotations are:
18[S] -- Function runs in any monad supporting MonadSample
19[H] -- Function runs in any monad supporting MonadHold
20[W] -- Function runs in any monad supporting MonadWidget
23Since MonadWidget depends on MonadHold and MonadHold depends on MonadSample, any [S] function also runs in [H] or [W] context, and any [H] function also runs in [W].
27### Functions producing Event
33-- Extract Event from Dynamic
34[ ] updated :: Dynamic a -> Event a
36-- Transform Event to Event using function
37[ ] fmap :: (a -> b) -> Event a -> Event b
38[ ] fmapMaybe :: (a -> Maybe b) -> Event a -> Event b
39[ ] ffilter :: (a -> Bool) -> Event a -> Event a
40[ ] ffor :: Event a -> (a -> b) -> Event b
41[ ] fforMaybe :: Event a -> (a -> Maybe b) -> Event b
42[ ] splitE :: Event (a, b) -> (Event a, Event b)
44-- Event to identical Event with debug trace.
45[ ] traceEvent :: Show a => String -> Event a -> Event a
46[ ] traceEventWith :: (a -> String) -> Event a -> Event a
48-- Transform Event to Event by sampling Behavior or Dynamic
49[ ] gate :: Behavior Bool -> Event a -> Event a
50[ ] tag :: Behavior a -> Event b -> Event a
51[ ] tagDyn :: Dynamic a -> Event b -> Event a
52[ ] attach :: Behavior a -> Event b -> Event (a, b)
53[ ] attachDyn :: Dynamic a -> Event b -> Event (a, b)
54[ ] attachWith :: (a -> b -> c) -> Behavior a -> Event b -> Event c
55[ ] attachDynWith :: (a -> b -> c) -> Dynamic a -> Event b -> Event c
56[ ] attachWithMaybe :: (a -> b -> Maybe c) -> Behavior a -> Event b -> Event c
57[ ] attachDynWithMaybe :: (a -> b -> Maybe c) -> Dynamic a -> Event b -> Event c
59-- Combine multiple Events
60[ ] <> :: Monoid a => Event a -> Event a -> Event a
61[ ] mergeWith :: (a -> a -> a) -> [Event a] -> Event a
62[ ] leftmost :: [Event a] -> Event a
63[ ] mergeList :: [Event a] -> Event (NonEmpty a)
64[ ] merge :: GCompare k => DMap (WrapArg Event k) -> Event (DMap k)
65[ ] mergeMap :: Ord k => Map k (Event a) -> Event (Map k a)
67-- Efficient one-to-many fanout
68[ ] fanMap :: Ord k => Event (Map k a) -> EventSelector (Const2 k a)
69[ ] fan :: GCompare k => Event (DMap k) -> EventSelector k
70[ ] select :: EventSelector k -> k a -> Event a
72-- Event to Event via monadic function
73[ ] push :: (a -> m (Maybe b)) -> Event a -> Event b
74[ ] pushAlways :: (a -> m b ) -> Event a -> Event b
75 -- Note supplied function operates in [H] context
77-- Event to monadic Event
78[H] headE :: Event a -> m (Event a)
79[H] tailE :: Event a -> m (Event a)
80[H] headTailE :: Event a -> m (Event a, Event a)
83### Event flattening functions
85These functions flatten Event-of-Event, Behavior-of-Event, or Dynamic-of-Event into Event, where the returned Event fires whenever the latest Event supplied by the wrapper fires. There are subtle differences in how they 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.
88-- Flatten Event-of-Event to monadic Event. New Event is used immediately.
89[H] switchPromptly :: Event a -> Event (Event a) -> m (Event a)
91-- Flatten Behavior-of-Event to Event. Old Event is used during switchover.
92[ ] switch :: Behavior (Event a) -> Event a
94-- Flatten Dyanmic-of-Event to Event. New Event is used immediately.
95[ ] switchPromptlyDyn :: Dynamic (Event a) -> Event a
97-- Flatten Event-of-Event to Event that fires when both wrapper and new Event fire.
98[ ] coincidence :: Event (Event a) -> Event a
100-- Flatten Dynamic-of-Dynamic to Dynamic. New Dynamic is used immediately.
101-- Output updated whenever inner or outer Dynamic updates.
102[ ] joinDyn :: Dynamic (Dynamic a) -> Dynamic a
103[ ] joinDynThroughMap :: Ord k => Dynamic (Map k (Dynamic a)) -> Dynamic (Map k a)
105-- Flatten Event-of-Behavior to monadic Behavior
106[H] switcher :: Behavior a -> Event (Behavior a) -> m (Behavior a)
109### Functions producing Behavior
113[ ] constant :: a -> Behavior a
115-- Extract Behavior from Dynamic
116[ ] current :: Dynamic a -> Behavior a
118-- Event to monadic Behavior
119[H] hold :: a -> Event a -> m (Behavior a)
121-- Transform Behavior to Behavior using function
122[ ] fmap :: (a -> b) -> Behavior a -> Behavior b
123[ ] ffor :: Behavior a -> (a -> b) -> Behavior b
124[ ] <*> :: Behavior (a -> b) -> Behavior a -> Behavior b
125[ ] >>= :: Behavior a -> (a -> Behavior b) -> Behavior b
126[ ] <> :: Monoid a => Behavior a -> Behavior a -> Behavior a
127-- ... plus many more due to typeclass membership
129-- Behavior to Behavior via monadic value
130[S] sample :: Behavior a -> m a
131[ ] pull :: m a -> Behavior a
132 -- Note supplied value is in [S] context
135### Functions producing Dynamic
139[ ] constDyn :: a -> Dynamic a
141-- Construct Dynamic from Event
142[H] holdDyn :: a -> Event a -> m (Dynamic a)
143[H] foldDyn :: (a -> b -> b) -> b -> Event a -> m (Dynamic b)
144[H] foldDynM :: (a -> b -> m' b) -> b -> Event a -> m (Dynamic b)
145 -- Note supplied function operates in [H] context
146[H] count :: Num b => Event a -> m (Dynamic b)
147[H] toggle :: Bool -> Event a -> m (Dynamic Bool)
149-- Transform Dynamic to Dynamic using function
150[H] forDyn :: Dynamic a -> (a -> b) -> m (Dynamic b)
151[H] mapDyn :: (a -> b) -> Dynamic a -> m (Dynamic b)
152[H] mapDynM :: (a -> m' b) -> Dynamic a -> m (Dynamic b)
153 -- Note supplied function runs in [S] context
154[H] splitDyn :: Dynamic (a, b) -> m (Dynamic a, Dynamic b)
156-- Combine multiple Dynamics
157[H] mconcatDyn :: Monoid a => [Dynamic a] -> m (Dynamic a)
158[H] distributeDMapOverDyn :: GCompare k => DMap (WrapArg Dynamic k) -> m (Dynamic (DMap k))
159[H] combineDyn :: (a -> b -> c) -> Dynamic a -> Dynamic b -> m (Dynamic c)
161-- Efficient one-to-many fanout
162[ ] demux :: Ord k => Dynamic k -> Demux k
163[H] getDemuxed :: Eq k => Demux k -> k -> m (Dynamic Bool)
165-- Dynamic to Dynamic, removing updates w/o value change
166[ ] nubDyn :: Eq a => Dynamic a -> Dynamic a
168-- Dynamic to identical Dynamic with debug trace.
169[ ] traceDyn :: Show a => String -> Dynamic a -> Dynamic a
170[ ] traceDynWith :: (a -> String) -> Dynamic a -> Dynamic a
175### Creating widgets (DOM elements hooked into the FRP system)
179These functions generally take an element tag (such as "div", "h1", etc) and a child widget, and produce a widget of the given type containing the child. Some of these functions return data of type `El`, which is a handle to the created DOM element along with a set of potential Events that might occur on that element.
181Widgets may return any type (this is 'a' in many of the functions below). Often this will be an Event carrying user interactions with the widget.
184-- Simplest form. Create a widget of given type containing the given child.
185-- Return whatever the child returns.
186[W] el :: String -> m a -> m a
188-- This version returns the 'El' as well.
189[W] el' :: String -> m a -> m (El, a)
191-- These two additionally apply attributes to the element, such as ("class" =: "blah")
192[W] elAttr :: String -> Map String String -> m a -> m a
193[W] elAttr' :: String -> Map String String -> m a -> m (El, a)
195-- As above, but now the attribute map is Dynamic
196[W] elDynAttr :: String -> Dynamic (Map String String) -> m a -> m a
197[W] elDynAttr' :: String -> Dynamic (Map String String) -> m a -> m (El, a)
199-- Shortcut for elAttr when you only want to set the "class" attribute.
200[W] elClass :: String -> String -> m a -> m a
202-- Even shorter-cut for above when element type is "div". Create a div of given class.
203[W] divClass :: String -> m a -> m a
205-- Create a widget of given type with arbitrary, Dymamic HTML inside.
206[W] elDynHtml' :: String -> Dynamic String -> m El
207[W] elDynHtmlAttr' :: String -> Map String String -> Dynamic String -> m El
209-- Shortcut for elDynHtml' where the type is "div" and you don't need the 'El'.
210[W] dynHtml :: Dynamic String -> m ()
212-- Create a static text element
213[W] text :: String -> m ()
215-- Create a dynamic text element
216[W] dynText :: Dynamic String -> m ()
217[W] display :: Show a => Dynamic a -> m ()
219-- Create a "button" element with given label, return onClick Event
220[W] button :: String -> m (Event ())
228In the Dynamic cases above, the *content* of a widget is dynamic but the *definition* of the widget is static. The functions below enable the definition and/or structure of the widget itself to change over time.
230Note the "list" functions do not imply particular HTML tags (ul, li, etc), though the widgets they create can have those tags if you construct them appropriately.
233-- Given a Dynamic of widget-creating actions, create a widget that is redefined
234-- whenever the Dynamic updates. The returned Event of widget results occurs when
235-- the Dynamic does. Note that if type 'a' is an Event, the return value is an
236-- Event-of-Events that would typically be flattened.
237[W] dyn :: Dynamic (m a) -> m (Event a)
239-- Same as dyn, but takes initial value and an update Event instead of a Dynamic.
240[W] widgetHold :: m a -> Event (m a) -> m (Dynamic a)
242-- Given a Dynamic key/value map and a function to create a widget for a given
243-- key & Dynamic value, create a bunch of widgets. Widgets will be created,
244-- destroyed, and updated appropriately as the map changes. Returns Dynamic map
245-- from keys to widget results.
246[W] listWithKey :: Ord k =>
247 Dynamic (Map k v) -> (k -> Dynamic v -> m a ) -> m (Dynamic (Map k a))
249-- Same as above where the widget constructor doesn't care about the key.
251 Dynamic (Map k v) -> ( Dynamic v -> m a ) -> m (Dynamic (Map k a))
253-- Even simpler version where there are no keys and we just use a list.
255 Dynamic [v] -> ( Dynamic v -> m a ) -> m (Dynamic [a])
257-- Like listWithKey specialized for widgets returning (Event a). listWithKey would
258-- return 'Dynamic (Map k (Event a))' in this scenario, but listViewWithKey flattens
259-- this to 'Event (Map k a)' via 'switch'.
260[W] listViewWithKey :: Ord k =>
261 Dynamic (Map k v) -> (k -> Dynamic v -> m (Event a)) -> m (Event (Map k a))
263-- As above, but there is a "current key", and the widget constructor gets a
264-- Dynamic Bool indicating if that widget is currently selected. The returned
265-- Event fires when any of the widgets' returned Events fire, and returns the key
266-- of an arbitrary firing widget.
267[W] selectViewListWithKey_ :: Ord k => Dynamic k ->
268 Dynamic (Map k v) -> (k -> Dynamic v -> Dynamic Bool -> m (Event a)) -> m (Event k)
270-- Same as listWithKey, but takes initial values and an updates Event instead of a Dynamic.
271[W] listWithKey' :: Ord k =>
272 Map k v -> Event (Map k (Maybe v)) -> (k -> v -> Event v -> m a) -> m (Dynamic (Map k a))
280### Connecting to the real world (I/O)
282#### Connecting to DOM events
285-- Extract the specified Event from an 'El'. The allowable event names, and their
286-- corresponding data types, are listed in Reflex/Dom/Widget/Basic.hs
287[ ] domEvent :: EventName en -> El -> Event (EventResultType en)
290#### Performing arbitrary I/O in response to Events
293-- Run side-effecting actions in Event when it occurs; returned Event contains
294-- results. Side effects run in (WidgetHost m) monad, which includes [S] and [H]
295-- and can also do I/O via liftIO
296[W] performEvent :: Event ( WidgetHost m a) -> m (Event a)
298-- Just run side-effects; no return Event
299[W] performEvent_ :: Event ( WidgetHost m ()) -> m ()
301-- Actions run asynchronously; actions are given a callback to send return values
302[W] performEventAsync :: Event ((a -> IO ()) -> WidgetHost m ()) -> m (Event a)
308-- Reflex-Dom entry point. Takes a monadic widget-building action of lengthy
309-- type and turns it into an IO action.
311 Widget Spider (Gui Spider (WithWebView SpiderHost) (HostFrame Spider)) () -> IO ()
312[I] mainWidgetWithHead ::
313 Widget Spider (Gui Spider (WithWebView SpiderHost) (HostFrame Spider)) () ->
314 Widget Spider (Gui Spider (WithWebView SpiderHost) (HostFrame Spider)) () -> IO ()
315[I] mainWidgetWithCss ::
317 Widget Spider (Gui Spider (WithWebView SpiderHost) (HostFrame Spider)) () -> IO ()
319-- One-shot Event that is triggered once all initial widgets are built
320[W] getPostBuild :: m (Event ())
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list