Arrows - FH Wedel

Werbung
Arrows
Ein Vortrag von
Mario Rauschenberg, Bjarne Großmann
Agenda
ƒ
ƒ
ƒ
ƒ
Einleitung
Funktionen, Monaden und Arrows
Funktionen, Monaden und Arrows
Arrows im Detail
Beispiel
15.01.2009
Bjarne Großmann, Mario Rauschenberg
2
Einleitung
Was sind eigentlich „Arrows“?
Lediglich eine Verallgemeinerung der Monaden!
???
15.01.2009
Bjarne Großmann, Mario Rauschenberg
3
Einleitung
ƒ Quizfrage: Was ist eine Monade?
a) Abstrakter Datentyp
b) Beschreibung einer einheitlichen Schnittstelle
c) Containerklasse für unterschiedliche Typen
d) Verpackte Berechnungen mit Seiteneffekten
)
g ,
g
e) Strategie, um Berechnungen zu kombinieren
f) Ich hab keine Ahnung
15.01.2009
Bjarne Großmann, Mario Rauschenberg
4
Back to the Roots
Back to
ƒ Funktionen und ihre Komposition
f
g
h
fgh
fgh
:: a ‐> b
>b
:: b ‐> c
:: c ‐> d
:: a > d
:: a ‐> d
= h . g . f
a b
f
15.01.2009
b c
g
c d
h
Bjarne Großmann, Mario Rauschenberg
5
Back to the Roots
Back to
ƒ Komplexere Funktionen
f1,g1,h1
f1
1 h1
f2,g2,h2
f3,g3,h3
f4 g4 h4
f4,g4,h4
:: a ‐> Maybe
>M b b
:: a ‐> (b, s)
:: a ‐> [b]
:: a > (s > (a s))
:: a ‐> (s ‐> (a, s))
fgh = fn . gn . hn ???
a Maybe b
f
15.01.2009
b Maybe c
g
Bjarne Großmann, Mario Rauschenberg
6
Beispiel: Maybe
Beispiel: Maybe
f
g
h
fgh
:: a ::
a ‐>> Maybe b
Maybe b
:: b ‐> Maybe c
:: c ‐> Maybe d
:: a ‐>> Maybe d
:: a Maybe d
a b
fgh
1. Lösungsversuch
fgh
g x = case f x of
Nothing ‐> Nothing
Just y ‐> case g y of
Nothing ‐> Nothing
Just z ‐> h z
15.01.2009
Bjarne Großmann, Mario Rauschenberg
7
Beispiel: Maybe
Beispiel: Maybe
f
g
h
f h
fgh
:: a ‐> Maybe b
:: b ‐> Maybe c
:: c ‐> Maybe d
:: a ‐> Maybe d
b d
(a > Maybe b) (Maybe
(a ‐> Maybe
b)
(Maybe a ‐> Maybe
a > Maybe b)
helper
f f*
2. Lösungsversuch
helper
helper f Nothing
helper f (Just x)
:: (a ::
(a ‐>> Maybe b) Maybe b) ‐>> (Maybe a (Maybe a ‐>> Maybe b)
Maybe b)
= Nothing
= f x
fgh = (helper h) . (helper g) . f
15.01.2009
Bjarne Großmann, Mario Rauschenberg
8
Beispiel: Tupel
Beispiel: Tupel
f
g
h
fgh
:: a ‐> (b, String)
:: b ‐> (c, String)
:: c ‐> (d, String)
:: a ‐> (d, String)
helper
:: (a ‐> (b, String)) ‐> ((a, String) ‐> (b, String))
helper g (fx, fs) = let (gx, gs) = g fx
in (gx, fs++gs)
fgh = (helper h) . (helper g) . f
(
) (
)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
9
Beispiel: Liste
Beispiel: Liste
f
g
h
fgh
:: a ‐> [b]
:: b ‐> [c]
:: c ‐> [d]
:: a ‐> [d]
helper helper f x :: (a ‐> [b]) ‐> ([a] ‐> [b])
= concat (map f x)
fgh = (helper h) . (helper g) . f
15.01.2009
Bjarne Großmann, Mario Rauschenberg
10
Beispiel: Status
Beispiel: Status
f
g
h
fgh
:: a ‐> (s ‐> (b, s))
:: b ‐> (s ‐> (c, s)) :: c ‐> (s ‐> (d, s)) :: a ‐> (s ‐> (d, s)) helper helper g x s :: (a ‐> (s ‐> (b, s))) ‐> ((s ‐> (a, s)) ‐> (s ‐> (b, s)))
= let (x1, s1) = x s
in g x1 s1
fgh = (helper h) . (helper g) . f
(
) (
)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
11
Beispiel: Zusammenfassung
Beispiel: Zusammenfassung
f1
helper1
f2
helper2
f3
helper3
f4
helper :: a ‐> Maybe b
:: (a ‐> Maybe b) ‐> (Maybe a ‐> Maybe b)
:: a ‐> (b, s)
:: (a ‐> (b, s)) ‐> ((a, s) ‐> (b, s))
:: a ‐> [b] :: (a ‐> [b]) ‐> ([a] ‐> [b]) :: a ‐> (s ‐> (d, s)) :: (a ‐> (s ‐> (b, s))) ‐> ((s ‐> (a, s)) ‐> (s ‐> (b, s)))
fgh = (helper hn) . (helper gn) . fn
(
) (
)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
12
Monaden
newtype MyMonad t = M Maybe t
newtype MyMonad t = M (t, String)
newtype MyMonad t = M [t]
newtype MyMonad t = M (s ‐> (t, s))
15.01.2009
f
helper
:: a ‐> M b
:: (a ‐> M b) ‐> (M a ‐> M b)
:: (a ‐> M b) ‐> M a ‐> M b
(a > M b) > M a > M b
:: M a ‐> (a ‐> Mb) ‐> M b
(>>=)
= helper
= helper
fgh x
return
= f x >>= g >>= h
?=? x >>= f >>= g >>= h
?=? x >>= f >>= g >>= h
:: a ‐> M a
fgh x
= return x return x >>= f f >>= g g >>= h
h
Bjarne Großmann, Mario Rauschenberg
13
Monaden
In Haskell:
class Monad m where
return :: a ‐> m a
(>>=) :: m a ‐> (a ‐> m b) ‐> m b
Maybe a
a ‐> b
[a]
s ‐> (a, s)
Either e
Monade
15.01.2009
Bjarne Großmann, Mario Rauschenberg
14
Funktionskomposition
ƒ Funktionen kombinieren
f :: a ‐> b
g :: b ‐> c
ƒ Bisher
ƒ fgfg :: a ‐> c
= f . g
ƒ Funktionen als Parameter
:: (a ‐> b) ‐> (b ‐> c) ‐> (a ‐> c)
ƒ comb
comb h k
= k . h
ƒ (.) für einfache Funktionen
15.01.2009
Bjarne Großmann, Mario Rauschenberg
15
Funktionskomposition
ƒ Funktionen kombinieren
f :: a ‐> m b
g :: b ‐> m c
ƒ Bisher
fg :: a ‐> m c
fg x = (f x) >>= g
ƒ Funktionen als Parameter
comb
comb h k x
:: (a ‐> m b) ‐> (b ‐> m c) ‐> (a ‐> m c)
= (h x) >>= k
ƒ (>>=) für monadische Funktionen?
((>>=) :: m a ‐> (a ‐> m b) ‐> m b
)
(
)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
16
Funktionskomposition
ƒ Abstraktion des Operators
comb newtype Kleisli m a b
mab
(>‐>) K f (>‐>) K g
:: (a ‐> m b) ‐> (b ‐> m c) ‐> (a ‐> m c)
= K { runK
K { runK :: a ‐> m b }
a >mb}
:: Kleisli m a b ‐> Kleisli m b c ‐> Kleisli m a c
= K (\x ‐> f x >>= g)
ƒ Der erste Arrow: Kleisli Arrow!
g
ƒ Anwendung ähnlich wie bei Monaden
f
:: K m a b
g
:: K m b c
fg x = runK (f >‐> g) x
15.01.2009
Bjarne Großmann, Mario Rauschenberg
17
Arrows
ƒ Weitere Abstraktion
ƒ Kleisli Arrow nicht nur für Monaden:
ƒ
f newtype Arrow b c
(>>>)
(>>>) arr
:: b ‐> c
= A ( runA :: b ‐> c)
:: A b c ‐>> A c d :: A b c A c d ‐>> A b d
Abd
:: (b ‐> c) ‐> A b c
ƒ Arrows für beliebige Funktionen
f
:: A a b
g
:: A b c
fg x x = runA
runA (f
(f >>> g) x
>>> g) x
15.01.2009
Bjarne Großmann, Mario Rauschenberg
18
Was sind Arrows?
Was sind Arrows?
ƒ Erklärung von Wikibooks
ƒ Kombination von Funktions
Kombination von Funktions‐Objekten
Objekten (Roboter) mit verschiedenen In‐ und Outputs (Fließbänder)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
19
arr
ƒ Verknüpfung mit In‐ und Output
arr :: Arrow a => (b ‐> c) ‐> a b c
15.01.2009
Bjarne Großmann, Mario Rauschenberg
20
(>>>)
ƒ Output von f als Input von g
(>>>) :: Arrow a => a b c ‐> a c d ‐> a b d
15.01.2009
Bjarne Großmann, Mario Rauschenberg
21
returnA
ƒ Arrow – Identität
returnA :: Arrow a => a b b
Arrow a > a b b
returnA = arr id
15.01.2009
Bjarne Großmann, Mario Rauschenberg
22
Unterschied zu Monaden
Unterschied zu Monaden
ƒ Arrows sind eine Erweiterung von Monaden
ƒ Monaden sind eine Erweiterung von sind eine Erweiterung von
Funktionen
ƒ Also: Arrows
Al A
abstrahieren Funktionen
b
hi
F ki
ƒ Arrows haben expliziten Input
p
p
Funktion
Monade
Arrow
f
m
a
15.01.2009
Bjarne Großmann, Mario Rauschenberg
23
Monaden durch Arrows
Monaden durch Arrows
newtype
yp Kleisli m a b = K (a ‐> m b)
(
)
instance Monad m => Arrow (Kleisli m) where
arr f = K (\b ‐> return f b)
K f >>> K g
= K (\b ‐> f b >>= g)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
24
„The real flexibility with arrows comes with the „The
real flexibility with arrows comes with the
ones that aren't monads, otherwise it's just a clunkier syntax
syntax”
‐ Philippa Cowderoy
15.01.2009
Bjarne Großmann, Mario Rauschenberg
25
first & second
& second
ƒ Mehrere Inputs von denen einer verarbeitet wird.
first :: Arrow a => a b c ‐> a (b, d) (c, d)
second :: Arrow a => a b c ‐> a (d, b) (d, c)
Arrow a > a b c > a (d b) (d c)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
26
( )
(***)
ƒ Zwei Inputs durch jeweils anderes
j
Funktionsobjekt bearbeitet
(***) Arrow a > a b c > a d e > a (b d) (c e)
(***) :: Arrow a => a b c ‐> a d e ‐> a (b,d) (c,e)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
27
(&&&)
ƒ Ein Input wird in beide Funktionen „geklont“.
(&&&) Arrow a > a b c > a b d > a b (c d)
(&&&) :: Arrow a => a b c ‐> a b d ‐> a b (c,d)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
28
Wozu das ganze?
Wozu das ganze?
ƒ Generalisierung von Monaden bzw. g
Funktionen und „Funktionsartigen“
ƒ Größere Flexibilität als bei Monaden
ƒ „Stream‐Prinzip“
S
Pi i “
15.01.2009
Bjarne Großmann, Mario Rauschenberg
29
Funktionen als Arrows
Funktionen als Arrows
instance Arrow (‐>) where
arr f = f
f f
first f = f *** id
second f = id *** f
((***)) f g f g ~(x
(x,y) = (f x, g y)
y) = (f x g y)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
30
Parser Beispiel
Parser‐Beispiel
ƒ Monadischer HTML‐Parser
Input: <xhtml>
Input: <xhtml>
<html>
<body>
<?php>
ƒ Ineffizient!
15.01.2009
fail!
Bjarne Großmann, Mario Rauschenberg
31
Parser Beispiel
Parser‐Beispiel
ƒ Erweiterung von Swierstra und Duponcheel: Vorausschauendes Parsen
Input: <xhtml>
<html>
<body>
<? h >
<?php>
fail!
15.01.2009
Bjarne Großmann, Mario Rauschenberg
32
Parser Beispiel
Parser‐Beispiel
ƒ Monadischer Parser
newtype
yp Parser s a = P ([s] ‐> Maybe
([ ]
y ((a,[s]))
,[ ]))
symbol :: s ‐> Parsers s s
symbol s = P (\xs ‐> case xs of
[ ] ‐> nothing
(x : xs‘) ‐> if x == s
then just (s, xs‘)
else nothing )
15.01.2009
Bjarne Großmann, Mario Rauschenberg
33
Parser Beispiel
Parser‐Beispiel
ƒ Monadische Parser kombinieren
instance MonadPlus Parsers where
P a (+++) P b = P (\s ‐> case a s of
Just (x, s‘) ‐> Just (x, s‘)
Nothing ‐> b s )
ƒ Problem: „Space Leak
Problem: Space Leak“
15.01.2009
Bjarne Großmann, Mario Rauschenberg
34
Parser Beispiel
Parser‐Beispiel
ƒ Erweiterung
data Parser s a b = P (StaticParser
(
s) (DynamicParser
)( y
s a b))
data StaticParser s = SP Bool [s]
newtype DynamicParser s a b = DP ( (a, [s]) ‐> (b, [s]) )
spChar :: Char ‐> StaticParser Char
spChar c = SP False [c]
dpChar :: Char ‐> DynamicParser Char Char Char
d Ch
dpChar c = DP (\
(\ ( _ , x:xs) ‐> (c, xs) )
(
) (
))
simple :: Char ‐> Parser Char Char Char
simple c = P (spChar
i l
P ( Ch c ) (dpChar
) (d Ch c))
15.01.2009
Bjarne Großmann, Mario Rauschenberg
35
Parser Beispiel
Parser‐Beispiel
Instance MonadPlus Parsers where
P (SP empty1 start1) DP (dp1) (+++) P (SP empty2 start2) DP (dp2) = P ( SP (empty1 || empty2) (start1++start2) DP (\xss ‐> case xss of
[ ] = if empty1 then dp1 [] else dp2 []
j@(x:xs) = if x `in` start1 then dp1 j else
if x `in` start2 then dp2 j else
if empty1 then dp1 j else dp2 j
)
)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
36
Parser Beispiel
Parser‐Beispiel
ƒ Bind‐Operator
(>>=) :: Parsers s a ‐> ( a ‐> Parsers s b) ‐> Parsers s b
ƒ … ist nicht möglich, da der statische Teil von a „vergessen“ wird.
“ id
15.01.2009
Bjarne Großmann, Mario Rauschenberg
37
Parser Beispiel
Parser‐Beispiel
ƒ Arrow‐Parser
Instance Arrow (Parser s) where
(
)
arr :: Arrow a => (b ‐> s) ‐> a b s
arr f = P (SP True [ ]) (DP (\ (b,s) ‐> (f b, s) ) )
P (SP empty1 start1) DP (dp1) >>> P (SP empty2 start2) DP (dp2) = P ( SP (empty1 && empty2) (start1 `union` if empty1 then start2 else [ ]) DP (dp1 . dp2)
)
15.01.2009
Bjarne Großmann, Mario Rauschenberg
38
Anwendungsbeispiele von Arrows
Anwendungsbeispiele von Arrows
ƒ Parser (z.B. auch HXT)
ƒ Automaten
ƒ Stream‐Computing
15.01.2009
Bjarne Großmann, Mario Rauschenberg
39
Fazit
ƒ Mächtiges Konzept für funktionsartige g g
Vorgänge
ƒ Allgemeinerer Entwurf als Monaden
ƒ Weg von Pure‐Functions
W
P
F
i
ƒ Verständnis ist „nicht einfach“
„
15.01.2009
Bjarne Großmann, Mario Rauschenberg
40
Quellen (einige)
Quellen (einige)
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
http://www.haskell.org/haskellwiki
h
//
h k ll
/h k ll iki
http://www.wikibooks.org
John Hughes: Generalising Monads to Arrows:
http //www cs chalmers se/~rjmh/Papers/arrows pdf
http://www.cs.chalmers.se/~rjmh/Papers/arrows.pdf
John Hughes: Programming with Arrows:
http://www.cs.chalmers.se/~rjmh/afp‐arrows.pdf
Hudak Courtney Nilsson Peterson: Arrows Robots and Reactive Functional Programming
Hudak, Courtney, Nilsson, Peterson: Arrows, Robots
http://www.haskell.org/yale/papers/oxford02/.oxford02.pdf
Albert Lai: HXT Arrow Lessons:
http://www.vex.net/~trebla/haskell/hxt‐arrow/index.xhtml
p //
/
/
/
/
15.01.2009
Bjarne Großmann, Mario Rauschenberg
41
Herunterladen