Monaden - Universität Magdeburg

Werbung
Monaden
Funktionale Programmierung
Monaden
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
c
Sommer 2014, 16. Mai 2014, 2011-14
D.Rösner
D. Rösner FP 2014 . . .
1
Monaden
Gliederung
1
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
D. Rösner FP 2014 . . .
2
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Monaden in Haskell
Verallgemeinerung der Prinzipien von I/O
Möglichkeit zum Sequentialisieren von Berechnungen
drei relevante Klassen:
die Klasse Functor (aus dem Standard Prelude)
die Klasse Monad (aus dem Standard Prelude)
die Klasse MonadPlus (aus Bibliothek Monad)
D. Rösner FP 2014 . . .
4
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Die Klasse Monad
die Signatur umfasst vier Grundoperationen
class Monad m
return ::
(>>=) ::
(>>)
::
fail
::
where
a -> m
m a ->
m a ->
String
a
(a -> m b) -> m b
m b -> m b
-> m a
D. Rösner FP 2014 . . .
5
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Die Klasse Monad cont.
für (>>) (sprich: sequence) und fail gibt es
Default-Implementationen:
p >> q
fail s
= p >>= \ _ -> q
= error s
für Instanzen reicht es meist aus, (>>=) (sprich: bind
oder then) und return zu definieren
D. Rösner FP 2014 . . .
6
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Die Klasse Monad cont.
zur Verwendung der vier Grundoperationen:
mit return wird ein Wert als monadischer Wert ohne
weitere Aktion zurückgegeben
mit (>>=) werden Berechnungen sequentialisiert, wobei
ein Wert von der einen zur anderen Berechnung
weitergereicht wird
mit (>>) werden Berechnungen sequentialisiert, wobei die
zweite den Wert der ersten Berechnung nicht benötigt
fail s ist eine Berechnung, die fehlschlägt und die
Fehlermeldung s liefert
D. Rösner FP 2014 . . .
7
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Die Klasse Monad cont.
Instanzen der Klasse Monad müssen bestimmten
Gesetzen genügen
mit dem abgeleiteten Operator >@> (sog.
Kleisli-Komposition) lauten diese:
M1:
M2:
M3:
return >@> f = f
f >@> return = f
(f >@> g) >@> h = f >@> (g >@> h)
m.a.W.:
return ist ein neutrales Element (oder Identität) für >@>
(M1, M2) und
>@> ist assoziativ (M3)
D. Rösner FP 2014 . . .
8
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Die Klasse Monad cont.
Definition des abgeleiteten Operator >@> (sog.
Kleisli-Komposition):
(>@>) :: Monad m
=> (a -> m b) -> (b -> m c) -> (a -> m c)
f >@> g = \x -> (f x) >>= g
Verallgemeinerung der Funktionskomposition
D. Rösner FP 2014 . . .
9
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Die Klasse Monad cont.
mit (»=) lauten die Monadengesetze wie folgt:
M1’:
M2’:
M3’:
return a >>= k = k a
m >>= return = m
(m >>= k) >>= h = m >>= (\x -> k x >>= h)
Interpretation
M1’: return schickt seinen Wert an die nächste Aktion
M2’: wenn eine Aktion direkt von einem return gefolgt, dann
kann auch die Aktion selbst den Wert zurückgeben
M3’: eine Form von Assoziativität von (»=)
D. Rösner FP 2014 . . .
10
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Beziehung zwischen Monaden und do-Notation
die do-Notation ist nur eine Kurzschreibweise für die
Anwendung der monadischen Operatoren
einige der dabei geltenden Übersetzungsregeln:
do e1
==> e1
do e1; e2; ...; eN
==> e1 >> do e2; ...; eN
do x <- e1; e2; ...; eN
==> e1 >>= \x -> do e2; ...; eN
D. Rösner FP 2014 . . .
11
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Beziehung zwischen Monaden und do-Notation
die Monadengesetze nehmen dann die folgende Gestalt
an (vgl. [Hud00]):
M1”:
M2”:
M3”:
do x <- return a; k x
=
k a
do x <- m; return x
=
m
do x <- m; y <- k x; h y
= do y <- (do x <- m; k x); h y
dem Assoziativgesetz für (>>) entspricht:
do m1; m2; m3
=
do (do m1; m2); m3
D. Rösner FP 2014 . . .
12
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Instanzen der Klasse Monad
generell gilt: Elemente einer Monade m a sind
Berechnungen, die gewisse Aktionen ausführen können,
bevor sie einen Wert vom Typ a zurückgeben (vgl. [Tho99],
p. 404])
für unterschiedliche Instanzen der Klasse Monad sind
anzugeben:
Definitionen für zumindest (>>=) und return (die den
Monadengesetzen genügen),
die spezialisierten Typen dieser Operationen,
eine Interpretation der besonderen Eigenschaften der
Monade als Berechnung.
D. Rösner FP 2014 . . .
13
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Anwendung von Monad auf Bäume [cf. [Tho99], Ch.
18.9]
binäre Bäume als rekursive Datentypen
data Tree a = Nil | Node a (Tree a) (Tree a)
deriving (Eq, Ord, Show, Read)
ein Beispiel eines Baumes:
tree1 = Node "Moon"
(Node "Ahmet" Nil Nil)
(Node "Dweezil"
(Node "Ahmet" Nil Nil)
(Node "Moon" Nil Nil))
D. Rösner FP 2014 . . .
15
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Aufgabe: Nummerieren eines beliebigen Baumes
Aufgabe numTree: ersetze die Knoten eines beliebigen
Baumes durch Zahlen; dabei sollen identische Knoten
jeweils durch dieselbe Zahl ersetzt werden (cf. [Tho99], pp.
409)
D. Rösner FP 2014 . . .
16
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Aufgabe: Nummerieren eines beliebigen Baumes
eine mögliche Lösung:
traversiere den Baum und kreiere dabei eine Tabelle, die
Knoten mit ganzen Zahlen assoziiiert
traversiere den Baum erneut mit dieser Tabelle und ersetze
jeden Knoten durch die assoziiierte Zahl
Nachteil dieser Lösung: Baum wird zweimal traversiert
D. Rösner FP 2014 . . .
17
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Details der direkten Lösung
-- a Table associates elements with zero-based positions
type Table a = [a]
-- traverse a tree and return the Table of its elements
tree2table (Node root left right)
= t2t right (t2t left [root])
where
t2t tree table
= case tree of
Nil -> table
(Node root1 l1 r1)
-> t2t r1 (t2t l1 (update root1 table))
D. Rösner FP 2014 . . .
18
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Details der direkten Lösung
Aktualisieren der Tabelle, falls neuer Knoten gefunden:
update node table = if elem node table
then table
else table ++ [node]
Anwendung:
Main> tree2table tree1
["Moon","Ahmet","Dweezil"]
D. Rösner FP 2014 . . .
19
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Details der Lösung
-- a direct implementation of numTree
numTree’ tree
= convert tree (tree2table tree)
where
convert tree table
= case tree of
Nil -> Nil
(Node root1 l1 r1)
-> (Node (lookup’ root1 table)
(convert l1 table)
(convert r1 table))
D. Rösner FP 2014 . . .
20
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Details der direkten Lösung
-- lookup is in Prelude.hs
lookup’ elem tableG -- for the error message (cf. below)
= look elem tableG 0
where
look elem table pos
= case table of
[] -> error ("from lookup’: table "
++ show tableG ++
" does not contain elem "
++ show elem)
x:xs -> if x == elem then pos
else look elem xs (pos + 1)
D. Rösner FP 2014 . . .
21
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Details der direkten Lösung
Main> tree1
Node "Moon" (Node "Ahmet" Nil Nil)
(Node "Dweezil"
(Node "Ahmet" Nil Nil)
(Node "Moon" Nil Nil))
Main> numTree’ tree1
Node 0 (Node 1 Nil Nil)
(Node 2
(Node 1 Nil Nil)
(Node 0 Nil Nil))
D. Rösner FP 2014 . . .
22
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Eine monadische Lösung [cf. [Tho99], Ch. 18.9]
Grundidee:
ein Zustand enthält eine Funktion, die einer Tabelle (mit
Werten vom Typ a) ein Paar zuordnet aus einer
möglicherweise veränderten Tabelle und einem
Ergebniswert (vom Typ b)
data State a b = State (Table a -> (Table a, b))
instance Monad (State a) where
return x = State (\tab -> (tab,x))
(State st) >>= f
= State (\tab -> let (newTab,y) = st tab
(State trans) = f y
in trans newTab)
D. Rösner FP 2014 . . .
23
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Eine monadische Lösung
ein Objekt x wird in eine Monadeninstanz als Funktion
\tab -> (tab,x) eingebracht
return x = State (\tab -> (tab,x))
Erläuterung zur Definition von >>=
die Anwendung der Funktion st aus (State st) auf eine
Tabelle tab liefert ein Paar (newTab,y)
wird f auf y angewendet, so ergibt dies eine
Monadeninstanz (State trans)
die Funktion trans aus dieser Monade wird dann auf
newTab angewendet
D. Rösner FP 2014 . . .
24
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Eine monadische Lösung
numberNode x = State (nNode x)
nNode x table
| elem x table = (table
, lookup’ x table)
| otherwise
= (table++[x], length table)
Main> :t numberNode
numberNode :: (Show a, Eq a) => a -> State a Int
Main> :t nNode
nNode :: (Eq a, Show a) => a -> [a] -> ([a],Int)
D. Rösner FP 2014 . . .
25
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Eine monadische Lösung
numberTree Nil = return Nil
numberTree (Node x t1 t2) = do num <nt1 <nt2 <return
numberNode x
numberTree t1
numberTree t2
(Node num nt1 nt2)
Main> :t numberTree
numberTree :: (Eq a, Show a) => Tree a -> State a (Tree Int)
D. Rösner FP 2014 . . .
26
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Eine monadische Lösung
Frage: wie lässt sich
do num <nt1 <nt2 <return
numberNode x
numberTree t1
numberTree t2
(Node num nt1 nt2)
schreiben mit Operator >>= ?
D. Rösner FP 2014 . . .
27
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Eine monadische Lösung
den Rückgabewert erhält man, indem man
die im Zustand (State st) enthaltene Funktion st auf
eine leere Tabelle anwendet;
dies liefert ein Paar aus (veränderter) Tabelle und dem
Rückgabewert als zweites Element
extract (State st) = snd (st [])
numTree :: (Show a, Eq a) => Tree a -> Tree Int
numTree = extract . numberTree
D. Rösner FP 2014 . . .
28
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Eine monadische Lösung
Verwendung:
Main> numTree tree1
Node 0 (Node 1 Nil Nil)
(Node 2 (Node 1 Nil Nil) (Node 0 Nil Nil))
D. Rösner FP 2014 . . .
29
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Variante: gleichzeitig Baum nummerieren und
spiegeln
numberAndMirrorTree Nil = return Nil
numberAndMirrorTree (Node x t1 t2)
= do num <- numberNode x
nt1 <- numberAndMirrorTree t1
nt2 <- numberAndMirrorTree t2
return (Node num nt2 nt1) -- mirroring!
numAndMirrorTree :: (Show a, Eq a) => Tree a -> Tree Int
numAndMirrorTree = extract . numberAndMirrorTree
D. Rösner FP 2014 . . .
30
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Variante: gleichzeitig Baum nummerieren und
spiegeln
Main> numAndMirrorTree tree1
Node 0 (Node 2 (Node 0 Nil Nil) (Node 1 Nil Nil))
(Node 1 Nil Nil)
Main> tree1
Node "Moon" (Node "Ahmet" Nil Nil)
(Node "Dweezil" (Node "Ahmet" Nil Nil)
(Node "Moon" Nil Nil))
Main> numTree tree1
Node 0 (Node 1 Nil Nil)
(Node 2 (Node 1 Nil Nil) (Node 0 Nil Nil))
D. Rösner FP 2014 . . .
31
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
numTree: Vergleich mit Lösung ohne Monaden
numTree’’ tree
= ntree
where
(ntree, table) = traverseConvert (tree,[])
traverseConvert pair
= case pair of
(Nil, table) -> (Nil, table)
((Node root1 l1 r1), table)
-> ((Node (lookup’ root1 tabler1) nl1 nr1), tabler1)
where
(nl1, tablel1) = traverseConvert
(l1, (update root1 table))
(nr1, tabler1) = traverseConvert (r1, tablel1)
D. Rösner FP 2014 . . .
32
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Lösung ohne Monaden
Wie ist numTree” abzuändern für eine nonmonadische
Lösung für numAndMirrorTree?
D. Rösner FP 2014 . . .
33
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Zusammenfassung
die monadische Lösung erlaubt es, die Behandlung der
Tabelle in den Zuständen und den Zustandsübergängen zu
‘verbergen’
ohne Monaden müssen die Zustände explizit zusammen
mit der eigentlichen Aufgabenstellung bearbeitet werden
m.a.W.: Monaden als Mittel zur Abstraktion und
Modularisierung
D. Rösner FP 2014 . . .
34
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Maybe als Instanz der Klasse Monad
Elemente der Monade Maybe a sind Berechnungen, die
entweder einen Wert vom Typ a haben oder einen Fehler
produzieren können
aus dem Standard Prelude:
instance Monad Maybe where
Just x >>= k = k x
Nothing >>= k = Nothing
return
= Just
fail s
= Nothing
D. Rösner FP 2014 . . .
36
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Maybe als Monad cont.
wollte man zwei Funktionen f :: a -> b und g :: b
-> c hintereinander ausführen, bei denen jeweils auch
Fehler auftreten können und daher die Resultate mit dem
Datentyp Maybe angegeben werden, so wäre ohne
monadische Operatoren die Fehlerbehandlung bei
g (f x) z.B. wie folgt (vgl. [Hud00], p. 256):
case (f x) of
Nothing -> Nothing
Just y -> case (g y) of
Nothing -> Nothing
Just z -> z
D. Rösner FP 2014 . . .
37
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Maybe als Monad cont.
mit monadischen Operatoren vereinfacht sich dies zu:
f x >>= \y -> g y >>= \z -> return z
in do-Notation:
do y <- f x; z <- g y; return z
D. Rösner FP 2014 . . .
38
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Maybe als Monad cont.
Vereinfachungen (vgl. [Hud00], pp. 256/257):
f x >>= \y -> g y >>= \z -> return z
sog. ’currying simplication’
f x >>= \y -> g y >>= return
Monadengesetz für return
f x >>= \y -> g y
erneut ’currying simplication’
f x >>= g
D. Rösner FP 2014 . . .
39
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Maybe als Monad cont.
m.a.W.: aus g(f x) wurde f x >>= g
weitere Abstraktion als monadischer Kompositionsoperator
(vgl. [Hud00], p. 257):
composeM :: Monad m =>
(b -> mc) -> (a -> mb) -> (a -> mc)
(g ‘composeM‘ f) x = f x >>= g
D. Rösner FP 2014 . . .
40
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Datentyp Liste als Instanz von Monad
aus dem Standard Prelude:
instance Monad [ ] where
(x:xs) >>= f = f x ++ (xs >>= f)
[]
>>= f = []
return x
= [x]
fail s
= []
gleichwertige Definition:
xs >>= f = concat (map f xs)
D. Rösner FP 2014 . . .
42
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Datentyp Liste als Instanz von Monad
die Typen der monadischen Operatoren sind dann:
(>>=) :: [a] -> (a -> [b]) -> [b]
return :: a -> [a]
die Monade [] lässt sich als Realisation
nichtdeterministischer Berechnungen sehen:
ein Element von [a] repräsentiert alle Ergebnisse einer
Berechnung
Fehlschlag ergibt eine leere Resultatliste
D. Rösner FP 2014 . . .
43
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Datentyp Liste als Instanz von Monad
die folgenden Darstellungen sind damit gleichwertig:
do x <- [1,2,3]; y <- [4,5,6]; return (x,y)
[1,2,3] >>= (\x -> [4,5,6] >>= (\y -> return (x,y)))
[(x,y) | x <- [1,2,3], y <- [4,5,6]]
D. Rösner FP 2014 . . .
44
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Motivation: Umgang mit Alternativen
Beispiel: simple DB mit Telefonnummern von Personen (cf.
[OGS09], Ch. 15)
-- file: ch15/VCard.hs
data Context = Home | Mobile | Business
deriving (Eq, Show)
type Phone = String
albulena = [(Home, "+355-652-55512")]
nils = [(Mobile, "+47-922-55-512"), (Business, "+47-922-12-121"),
(Home, "+47-925-55-121"), (Business, "+47-922-25-551")]
twalumba = [(Business, "+260-02-55-5121")]
D. Rösner FP 2014 . . .
46
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Motivation: Umgang mit Alternativen
Annahme: für persönliches Telefonat die private ode
mobile Nummer gesucht, nicht aber die geschäftliche
-- file: ch15/VCard.hs
onePersonalPhone :: [(Context, Phone)] -> Maybe Phone
onePersonalPhone ps = case lookup Home ps of
Nothing -> lookup Mobile ps
Just n -> Just n
cf. [OGS09], Ch. 15
D. Rösner FP 2014 . . .
47
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Motivation: Umgang mit Alternativen
Verwendung von Liste, um mehrere Nummern
zurückgeben zu können
-- file: ch15/VCard.hs
allBusinessPhones :: [(Context, Phone)] -> [Phone]
allBusinessPhones ps = map snd numbers
where numbers = case filter (contextIs Business) ps of
[] -> filter (contextIs Mobile) ps
ns -> ns
contextIs a (b, _) = a == b
cf. [OGS09], Ch. 15
D. Rösner FP 2014 . . .
48
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Motivation: Umgang mit Alternativen
beide Funktionen haben gleiche Struktur im case:
zuerst leeres Resultat behandeln,
dann nicht-leeres Resultat
Verwendung:
ghci> onePersonalPhone twalumba
Nothing
ghci> onePersonalPhone albulena
Just "+355-652-55512"
ghci> allBusinessPhones nils
["+47-922-12-121","+47-922-25-551"]
cf. [OGS09], Ch. 15
D. Rösner FP 2014 . . .
49
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Motivation: Umgang mit Alternativen
Definitionen von [] und Maybe als Instanzen von
MonadPlus (cf. [OGS09], Ch. 15)
-- file:
instance
mzero
mplus
ch15/VCard.hs
MonadPlus [] where
= []
= (++)
instance MonadPlus Maybe where
mzero = Nothing
Nothing ‘mplus‘ ys = ys
xs
‘mplus‘ _ = xs
D. Rösner FP 2014 . . .
50
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Motivation: Umgang mit Alternativen
Redefinition:
-- file: ch15/VCard.hs
oneBusinessPhone :: [(Context, Phone)] -> Maybe Phone
oneBusinessPhone ps = lookup Business ps ‘mplus‘ lookup Mobile ps
allPersonalPhones :: [(Context, Phone)] -> [Phone]
allPersonalPhones ps = map snd $ filter (contextIs Home) ps ‘mplus
filter (contextIs Mobile) ps
cf. [OGS09], Ch. 15
D. Rösner FP 2014 . . .
51
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Motivation: Umgang mit Alternativen
normales lookup:
-- file: ch15/VCard.hs
lookup :: (Eq a) => a -> [(a, b)] -> Maybe b
lookup _ []
= Nothing
lookup k ((x,y):xys) | x == k
= Just y
| otherwise = lookup k xys
cf. [OGS09], Ch. 15
D. Rösner FP 2014 . . .
52
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Motivation: Umgang mit Alternativen
Redefinition als lookupM für beliebige Instanzen von
MonadPlus:
-- file: ch15/VCard.hs
lookupM :: (MonadPlus m, Eq a) => a -> [(a, b)] -> m b
lookupM _ []
= mzero
lookupM k ((x,y):xys)
| x == k
= return y ‘mplus‘ lookupM k xys
| otherwise = lookupM k xys
cf. [OGS09], Ch. 15
D. Rösner FP 2014 . . .
53
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Motivation: Umgang mit Alternativen
Beachte: mplus ist nicht immer eine ’Addition’
Prelude> import Control.Monad
Prelude Control.Monad> [1,2,3] ‘mplus‘ [4,5,6]
[1,2,3,4,5,6]
Prelude Control.Monad> Just 1 ‘mplus‘ Just 2
Just 1
cf. [OGS09], Ch. 15
D. Rösner FP 2014 . . .
54
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Die Klasse MonadPlus
manche Monaden besitzen eine Operation mplus, mit der
monadische Werte aus getrennten Berechnungen in einen
monadischen Wert kombiniert werden können, und ein
neutrales Element mzero für diesen Operator
es müssen dann die folgenden zusätzlichen Gesetze
gelten:
M+1:
M+2:
M+3:
M+1:
mzero >>= f = mzero
m >>= (\x -> mzero) = mzero
mzero ‘mplus‘ m = m
m ‘mplus‘ mzero = m
D. Rösner FP 2014 . . .
55
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Die Klasse MonadPlus
Monaden mit mplus und mzero sollten als Instanzen der
Klasse MonadPlus deklariert werden
Definition: (aus Monad.hs)
class Monad m => MonadPlus m where
mzero :: m a
mplus :: m a -> m a -> m a
D. Rösner FP 2014 . . .
56
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Instanzen der Klasse MonadPlus
Maybe wird zur Instanz der Klasse MonadPlus durch:
instance MonadPlus Maybe
mzero
=
Nothing ‘mplus‘ ys =
xs
‘mplus‘ ys =
where
Nothing
ys
xs
m.a.W. ’Addieren’ zweier Werte vom Typ Maybe ergibt den
ersten Wert, der nicht Nothing, oder Nothing, falls beide
Werte Nothing
D. Rösner FP 2014 . . .
57
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Instanzen der Klasse MonadPlus
bei der Monade für Listen ist mzero die leere Liste und die
’Addition’ mplus ist die Listenkonkatenation
Definition:
instance MonadPlus [ ] where
mzero = []
mplus = (++)
D. Rösner FP 2014 . . .
58
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Literatur: I
Paul Hudak.
The Haskell School of Expression – Learning Functional
Programming through Multimedia.
Cambridge University Press, Cambridge, UK, 2000.
ISBN 0-521-64338-4.
Bryan O’Sullivan, John Goerzen, and Don Stewart.
Real World Haskell.
O’Reilly Media, Sebastopol, CA 95472, 2009.
ISBN 978-0-596-51498-3; online available at
http://book.realworldhaskell.org/.
D. Rösner FP 2014 . . .
59
Monaden
Klasse Monad
Tree
Maybe
Liste
MonadPlus
Literatur: II
Simon Thompson.
Haskell - The Craft of Functional Programming.
Addison Wesley Longman Ltd., Essex, 1999.
2nd edition, ISBN 0-201-34275-8; Accompanying Web site:
http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e.
D. Rösner FP 2014 . . .
60
Herunterladen