Monaden in Haskell
Monaden in Haskell
Monaden in Haskell
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>Monaden</strong> <strong>in</strong> <strong>Haskell</strong><br />
Joachim Breitner<br />
16. November 2010<br />
<strong>Haskell</strong> vs. Kategorientheorie<br />
E<strong>in</strong>e Monade <strong>in</strong> <strong>Haskell</strong> ist e<strong>in</strong>e Typklasse mit zwei Methoden:<br />
class Monad m where<br />
(»=) :: m a → (a → m b) → m b<br />
return :: a → m a<br />
wobei die folgenden Beziehungen gelten sollten:<br />
return x »= f ≡ f x<br />
a »= return ≡ a<br />
(a »= f) »= g ≡ a »= (ńx → f x »= g).<br />
E<strong>in</strong>e Formulierung der üblichen <strong>Monaden</strong>-Def<strong>in</strong>ition für <strong>Haskell</strong> wäre<br />
class Monad m where<br />
map :: (a → b) → m a → m b<br />
return :: a → m a<br />
jo<strong>in</strong> :: m (m a) → m a<br />
wobei m Typen auf Typen abbildet, also zusammen mit map e<strong>in</strong>en Funktor Hask → Hask def<strong>in</strong>iert.<br />
Es entspricht weiter return dem ε und jo<strong>in</strong> dem µ.<br />
Aus den Bed<strong>in</strong>gungen dass ε und µ natürliche Transformationen s<strong>in</strong>d, sowie den zwei def<strong>in</strong>ierenden<br />
kommutativen Diagrammen erhalten wir <strong>in</strong> <strong>Haskell</strong>-Schreibweise folgende Eigenschaften:<br />
map g ◦ return ≡ return ◦ g<br />
map g ◦ jo<strong>in</strong> ≡ jo<strong>in</strong> ◦ map (map g)<br />
jo<strong>in</strong> ◦ map jo<strong>in</strong> ≡ jo<strong>in</strong> ◦ jo<strong>in</strong><br />
jo<strong>in</strong> ◦ return ≡ jo<strong>in</strong> ◦ map return ≡ id.<br />
Die beiden Def<strong>in</strong>itionen s<strong>in</strong>d äquivalent. Man kann<br />
map f = (ńa → a »= (return ◦ f))<br />
jo<strong>in</strong> a = a »= id<br />
bzw. a »= f = jo<strong>in</strong> (map f a)<br />
def<strong>in</strong>ieren und nachrechnen, dass die obigen Bed<strong>in</strong>gungen <strong>in</strong>e<strong>in</strong>ander übergehen.<br />
Quellen: http://www.haskell.org/haskellwiki/Category_theory/Monads<br />
http://www.haskell.org/haskellwiki/User:Michiexile/MATH198<br />
http://www.haskell.org/all_about_monads/<br />
http://comonad.com/reader/
E<strong>in</strong> kle<strong>in</strong>er <strong>Monaden</strong>zoo<br />
Im folgenden die bekanntesten <strong>Haskell</strong>-<strong>Monaden</strong>, <strong>in</strong> etwas liberalerer Syntax.<br />
Maybe<br />
(Modelliert: partielle Funktionen, Berechnungen<br />
mit Fehlerzuständen)<br />
data Maybe a = Just a | Noth<strong>in</strong>g<br />
<strong>in</strong>stance Monad Maybe where<br />
return = Just<br />
(Just x) »= k = k x<br />
Noth<strong>in</strong>g »= k = Noth<strong>in</strong>g<br />
Either e<br />
(Modelliert: Berechnungen mit Fehlermeldungen)<br />
data Either e a = Left e | Right a<br />
<strong>in</strong>stance Monad (Either e) where<br />
return = Right<br />
(Left e) »= k = Left e<br />
(Right x) »= k = k x<br />
[]<br />
(Liste. Modelliert: Nichtdeterm<strong>in</strong>ismus)<br />
data [a] = a:[a] | [ ]<br />
<strong>in</strong>stance Monad [ ] where<br />
return x = [x]<br />
[ ] »= k = [ ]<br />
(x:xs) »= k = k x ++ (xs »= k)<br />
Reader r<br />
(Leser-Monade. Modelliert: Kontext<strong>in</strong>formationen)<br />
type Reader r a = r → a<br />
<strong>in</strong>stance Monad (Reader r) where<br />
return x = ńr → x<br />
m »= k = ńr → k (m r) r<br />
Writer m<br />
(Schreiber-Monade. Modelliert: Protokollierung.<br />
(M,e,∗) muss e<strong>in</strong> Monoid se<strong>in</strong>.)<br />
type Writer m a = (m,a)<br />
<strong>in</strong>stance Monoid m ⇒ Monad Writer where<br />
return x = (e, x)<br />
m »= k = let (m, y) = m<br />
(m’, z) = k a<br />
<strong>in</strong> (m ∗ m’, z)<br />
State s<br />
(Zustands-Monade. Modelliert: Berechnungen<br />
mit Zustand)<br />
type State s a = s → (a,s)<br />
<strong>in</strong>stance State s where<br />
return x = ńs → (x,s)<br />
m »= k = ńs → let (y, s’) = m s<br />
<strong>in</strong> k y s’<br />
Cont r<br />
(Fortführungs-Monade. Modelliert Sprünge im<br />
Programmablauf)<br />
type Cont r a = (a → r) → r<br />
<strong>in</strong>stance Monad (Cont r) where<br />
return x = ńc → c x<br />
m »= k = ńc → m (ńa → k a c)<br />
Identity<br />
(Modelliert: re<strong>in</strong>e Funktionen)<br />
type Identity a = a<br />
<strong>in</strong>stance Monad Identity where<br />
return = id<br />
m »= k = k m<br />
IO<br />
(Modelliert: Berechnungen, die mit der „echten<br />
Welt“ kommunizieren, etwa Dateizugriffe.<br />
Implementierung ist Compiler-Geheimnis!)<br />
type IO = ?<br />
<strong>in</strong>stance Monad IO where<br />
return = ?<br />
m »= k = ?<br />
Do-Notation<br />
<strong>Haskell</strong> unterstützt e<strong>in</strong>e spezielle Syntax für<br />
monadische Berechnungen. So steht etwa<br />
ma<strong>in</strong> = do x ← getL<strong>in</strong>e<br />
putStr ("You said " ++ x)<br />
return 3<br />
für<br />
ma<strong>in</strong> = getL<strong>in</strong>e »= (ńx →<br />
(putStr ("You said " ++ x) »= (ń_ →<br />
return 3))).