Download C18 - FRP

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
[Faculty of Science
Information and Computing Sciences]
Applied Functional Programming
USCS 2015
Atze Dijkstra
Department of Information and Computing Sciences
Utrecht University
July 6-17, 2015
C18. Functional Reactive Programming (FRP)
[Faculty of Science
Information and Computing Sciences]
C18-1
Functional Reactive Programming (FRP)
I
Pure (functional) programming: value of computation
always the same (guarantee of absence of side effect)
I
Impure, side effectful programming: value of compuation
depends on arbitrary ’outside’ influence
Middle way: value of computation depends on time:
Behavior a = Time→a
I
I
I
I
Reactive: changes in Behavior a as a result of (reaction
on) external Events occurring at a certain Time
Functional (1): description of reactive dependencies in a
(functional) declarative way
Functional (2): implementation runs in a functional
language setting (which it need not be)
[Faculty of Science
Information and Computing Sciences]
C18-2
Functional Reactive Programming (FRP)
The model in its purest form
type Time
= ...
-- e.g. Int
type Behavior a = Time→a -- aka Signal
Most libraries also distinguish between continuous time (pulling)
behavior and discrete timed (pushing) events
type Event a = [(Time, a)]
(Conal Elliot, Push-pull functional reactive programming, 2009)
[Faculty of Science
Information and Computing Sciences]
C18-3
Functional Reactive Programming (FRP)
The model is just a model, the reality is different...
I
Implementations leave Time implicit
I
Don’t implement Event as a stream but as an IO
triggered from “outside”
I
Dependency of output on input is maintained explicitly in a
graph
I
Events trigger recalculation, caching (statefully) only
current values
I
Cached values are returned by Behavior
Many different implementations: yampa, fran, reactive,
reactive-banana, sodium, elm, elerea, netwire, ...
[Faculty of Science
Information and Computing Sciences]
C18-4
FRP: Events
No event occurrence
never :: Event a
Stop propagation
filterJust :: Event (Maybe a)→Event a
filterE :: (a→Bool )→Event a→Event a -- derived
Combine event occurrences
union :: Event a→Event a→Event a
Mapping
instance Functor Event
[Faculty of Science
Information and Computing Sciences]
C18-5
FRP: Event & Behavior
Hold/accumulate initial & subsequent event values
stepper :: a→Event a
→Behavior a
accumE :: a→Event (a→a)→Event a
-- derived
accumB :: a→Event (a→a)→Behavior a -- derived
Snapshot behavior at event occurrence
applyE :: Behavior (a→b)→Event a→Event b
Lifting
instance Applicative Behavior
[Faculty of Science
Information and Computing Sciences]
C18-6
FRP: derived
Syntactic sugar
(h@i) :: Behavior (a→b)→Event a→Event b -- derived
b h@i e = applyE b e
(h@) :: Behavior b→Event a→Event b
b h@ e = applyE (const h$i b) e
-- derived
[Faculty of Science
Information and Computing Sciences]
C18-7
FRP: examples
Count arbitrary events
counter :: Event a→Event Int
counter e = bcounter h@ e
where bcounter = accumB 0 $ fmap (\ → (+1)) e
Add up event values (like sum)
integral :: Int→Event Int→Event Int
integral x e = bintegral h@ e
where bintegral = accumB x $ fmap (+) e
Calling structure declarative specifies network (graph) of event
& behavior dependencies
[Faculty of Science
Information and Computing Sciences]
C18-8
FRP: interpretation
How do we observe?
Use a model for ‘running’ a network
type Event
a = [Maybe a ]
data Behavior a = StepperB ! a (Event a)
type Time
= Int
I
Event: stream of values, indexed by Time, Just means
event occurrence, Nothing absence
I
Behavior : continuous observation changing with events
never :: Event a
never = repeat Nothing
(see package reactive-banana)
C18-9
[Faculty of Science
Information and Computing Sciences]
FRP: interpretation
union :: Event a→Event a→Event a
union (e1) (e2) = zipWith g e1 e2
where
g (Just x) (Just ) = Just x -- left biased
g (Just x) Nothing = Just x
g Nothing (Just y) = Just y
g Nothing Nothing = Nothing
[Faculty of Science
Information and Computing Sciences]
C18-10
FRP: interpretation
accumE: Function iteration when event happens
accumE :: a→Event (a→a)→Event a
accumE x ([ ])
= []
accumE x (Nothing : fs) = Nothing : accumE x (fs)
accumE x (Just f : fs) = let y = f x
in y ‘seq‘ Just y : accumE y (fs)
accumB :: a→Event (a→a)→Behavior a
accumB acc e = acc ‘StepperB ‘ (accumE acc e)
[Faculty of Science
Information and Computing Sciences]
C18-11
FRP: interpretation
Running: feed events
interpret :: (Event a→Event b)→[Maybe a ]→[Maybe b ]
interpret f e = f (e)
testModel0 :: [a ]→(Event a→Event b)→[Maybe b ]
testModel0 es f = interpret f $ map Just es
testModel = testModel0 [1 . . 8 :: Int ]
Examples
Maini testModel0 (replicate 8 ()) counter
01234567
Maini testModel (integral 0)
0 1 3 6 10 15 21 28
[Faculty of Science
Information and Computing Sciences]
C18-12
FRP: Event switching
Dynamicity: over time new events arise or disappear
switchE :: Event (Moment (Event a)) →Event a
switchB :: Behavior a→
Event (Moment (Behavior a))→Behavior a
Higher-order
Cannot be done arbitrarily as the structure of dependencies
changes in concrete implementations
Requires therefore a (usually) monadic structure (Moment)
‘between’ first order and higher order events which ’instantiates’
its argument at a certain time
[Faculty of Science
Information and Computing Sciences]
C18-13
FRP & Wx: example
Two counters
Libraries: wx, reactive-banana, reactive-banana-wx
[Faculty of Science
Information and Computing Sciences]
C18-14
FRP & Wx: example
Widget & layout setup
main = start $ do
f
← frame [text := "Two Counters"]
bup ← button f [text := "Up"]
bdw ← button f [text := "Down"]
bsw ← button f [text := "Switch Counters"]
out1 ← staticText f [text := "0"]
out2 ← staticText f [text := "0"]
set f [layout := margin 10 $
column 5 [row 5 [widget bup, widget bdw, widget bsw],
grid 5 5 [[label "First Counter:", widget out1]
, [label "Second Counter:", widget out2]
[Faculty of Science
Information and Computing Sciences]
C18-15
FRP & Wx: example
Logic expressed in Wx
...
c1 ← variable [value := 0]
c2 ← variable [value := 0]
is1 ← variable [value := True ]
set bsw [on command := set is1 [value :∼ not]]
set bup [on command := do {f ← get is1 value
; up f (c1, c2, out1, out2)}]
set bdw [on command := do {f ← get is1 value
; dw f (c1, c2, out1, out2)}]
...
[Faculty of Science
Information and Computing Sciences]
C18-16
FRP & Wx: example
...
where
up left (c1, c2, o1, o2) =
(if left then upd o1 c1 else upd o2 c2) (+1)
dw left (c1, c2, o1, o2) =
(if left then upd o1 c1 else upd o2 c2) (+(−1))
upd t c f = do
set c [value :∼ f ]
v ← get c value
set t [text := show v]
[Faculty of Science
Information and Computing Sciences]
C18-17
FRP & Wx: example
Logic expressed in FRP style
let networkDescription :: ∀t.Frameworks t ⇒ Moment t ()
networkDescription = do
-- externally triggered
eup ← event0 bup command
edw ← event0 bdw command
esw ← event0 bsw command
-- FRP network
let -- do we act on the left button?
is1 :: Behavior t Bool
is1 = accumB True $ not h$ esw
...
[Faculty of Science
Information and Computing Sciences]
C18-18
FRP & Wx: example
let . . . do . . .
let . . .
-- joined state of the two counters
counters :: Behavior t (Int, Int)
counters = accumB (0, 0) $
union ((up h$i is1) h@i eup)
((dw h$i is1) h@i edw)
up left (x, y) = if left then (x + 1, y) else (x, y + 1)
dw left (x, y) = if left then (x − 1, y) else (x, y − 1)
-- externally rendered
sink out1 [text :== show ◦ fst h$i counters]
sink out2 [text :== show ◦ snd h$i counters]
network ← compile networkDescription
actuate network
[Faculty of Science
Information and Computing Sciences]
C18-19
FRP: summary
Building GUIs with Haskell
I
With wx, gtk, ...
I
Imperative
I
With logic expressed as (functional) reactive network
I
Immature (still)
FRP elsewhere (outside the Haskell universe)
I
elm: functional language targeting javascript, html, ...
I
RxJS, Bacon.js: javascript FRP extensions
[Faculty of Science
Information and Computing Sciences]
C18-20
Related documents