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
  • 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

End

7GUIs with Reflex FRP

By Moritz Drexl

7GUIs with Reflex FRP

  • 1,990