7GUIs with Reflex FRP
Moritz Drexl
Hamburg Haskell Meetup
April 27, 2016
mdrexl@fastmail.fm
Reflex FRP
Higher order, fully deterministic, practical FRP framework
- Is an FRP framework
- Written in Haskell
- Has a DOM backend
- Works with GHCJS
- Is "practical" (more later)
Developed by Ryan Trinkle
Intro: Motivation
- Want to use Haskell power for GUIs
- GHCJS > PureScript
-
Same codebase for frontend and backend
- APIs and Protocols
- Flexible when moving business (eg, validation)
- Typecheck accross whole stack
- Everybody can work on everything
-
Same codebase for frontend and backend
-
Components approach (eg, React) has problems
- Tied to DOM tree ➡ communication difficult
- Components not lightweight enough
FP (Haskell) is good for programming batch systems:
Input
Processing
Output
pure
Interactive System:
Input
Input
Output
Output
Input
Output
?
Intro: Batch vs Interactive
Classic: Callbacks
Alternative: FRP
Intro: Callbacks vs FRP
A
B
A
B
componentA.on("input", function (e) {
componentB.doStuff(e);
};
(e :: Event a) <- componentA
componentB e
var input = [1, 2, 3];
var output = new Array(3);
for (i = 0; i < input.length; i++) {
output[i] = input[i] * 2;
}
input = [1, 2, 3]
output = map (*2) input
Imperative
Functional
Batch
Interactive
textArea.on("input", function (e) {
textBox.set(e.value + "!");
});
value <- textArea
textBox $ fmap (++ "!") value
FRP
FRP: An Analogy
FRP: Promise
- Describe what the system does instead of manipulating state
-
Have similar advantages as in FP
- A component is only determined by its "arguments" (input events)
- A component only produces a value (output events)
- Abstracted as easily as functions (FRP "circuit")
- Future: FRP will also be used for backends
A way of coding interactive systems in a purely functional way
Reflex: Properties
-
Higher order: can have events of events
- Dynamic data flow
- Create / destroy components
-
Efficient
- Propagation time not affected by system size
- Fully garbage collected
- No need for virtual-dom
- Deterministic
- Comprehensible (idiomatic Haskell)
- Expressive
➡ Practical
Reflex: Basics
t
v
t
v
Behavior
t
v
Dynamic
Event
push
pull/sample
Reflex: Basics
Event
Behavior
Dynamic
never :: Event a
fmapMaybe :: (a -> Maybe b) -> Event a -> Event b
tag :: Behavior a -> Event b -> Event a
-- Merging events:
mergeWith :: (a -> a -> a) -> [Event a] -> Event a
leftmost :: [Event a] -> Event a
constant :: a -> Behavior a
current :: Dynamic a -> Behavior a
hold :: a -> Event a -> m (Behavior a)
constDyn :: a -> Dynamic a
foldDyn :: (a -> b -> b) -> b -> Event a -> m (Dynamic b)
mapDyn :: (a -> b) -> Dynamic a -> m (Dynamic b)
switch :: Behavior (Event a) -> Event a
coincidence :: Event (Event a) -> Event a
Flattening
Code: The 7GUIs
Resources
- Ryan Trinkle at Boston Haskell Meetup: youtube.com/watch?v=dOy7zIk3IUI
- GitHub:
github.com/reflex-frp/reflex - Tutorial:
github.com/reflex-frp/reflex-platform#reflex-platform - Hackage:
hackage.haskell.org/package/reflex - Cheat Sheet:
github.com/reflex-frp/reflex/blob/develop/Quickref.md
End
7GUIs with Reflex FRP
By Moritz Drexl
7GUIs with Reflex FRP
- 2,013