Haskell


... [ Programmiersprachen und Sprachsysteme ] ... [ Monaden in anderen Programmiersprachen ] ... [ << Motivation ] ... [ C Sharp >> ] ...


Da Haskell Monaden für die grundlegende Ein- und Ausgabe von Programmen verwendet, sind Monaden vor allem von Haskell bekannt. In diesem Kapitel werden Monaden daher zunächst in Haskell vorgestellt.

Haskell ist eine pure funktionale Programmiersprache und in diesem Sprachen sind Funktionen mathematische Funktionen: Funktionen geben bei gleichen Parametern immer den gleichen Rückgabewert. Um dennoch Nebeneffekte darzustellen, wird ein Status explizit von Funktion zu Funktion weitergereicht, der entsprechend modifiziert wird.


Monaden in Haskell


In Haskell sind Monaden parametrisierbare Typen, die ein spezielles Interface implementieren. Dieses Interface besteht aus zwei Funktionen: unit und bind.

1
2
3
unit :: a -> m a

bind :: m a -> (a -> m b) -> m b


Unit wandelt ein Objekt vom Typ a in ein Objekt vom Typ Monade von a um. Es wird also ein monadisches Objekt konstruiert. In Haskell ist die Funktion unit unter dem Namen return bekannt. Da in C-ähnlichen Sprachen return für den Rückgabewert von Funktionen verwendet wird und als Schlüsselwort gilt, wird im Folgenden nur der Name unit verwendet.

Mit bind können Operationen zusammengebunden werden. In Haskell wird bind als >>= bezeichnet, was in vielen Sprachen kein gültiger Bezeichner ist.


Monadengesetze


Die Implementierungen von unit und bind sind im Grunde frei wählbar, sie müssen aber drei Gesetze erfüllen:

1
2
3
(unit x) `bind` f == f x
x `bind` unit == x
(x `bind` f) `bind` g == x `bind` (\ y -> f y `bind` g)


Die ersten beiden Gesetze sagen aus, dass unit das sowohl rechts- als auch linksneutrale Element für die Bind-Funktion ist. Im dritten Gesetz wird die Assoziativität von bind festgeschrieben. Klammern können daher gesetzt werden, ohne dass sich das Ergebnis ändert.

Diese Infixnotation wird uns in Sprachen wie Ruby und Javascript begegnen, die dafür dann eine objektorientierte Schreibweise verwenden.

In anderen Sprachen müssen diese Gesetze auch gelten, ansonsten wären die entsprechenden Implementierungen unvollständig


Maybe-Monade


Neben der Identitätsmonade ist die Maybe-Monade relativ einfach. Mit ihr können Funktionen zusammengebunden werden, die möglicherweise einen Wert zurückgegeben.

Die Typdefinition von Maybe sieht in Haskell folgendermaßen aus:

1
data Maybe a = Nothing | Just a


Maybe ist ein Typkonstruktor mit den beiden Variablenkonstruktoren Nothing und Just a.

unit und bind sehen dann so aus:

1
2
3
4
5
6
unit :: a -> Maybe a
unit x = Just x

bind :: Maybe a -> (a -> Maybe b) -> Maybe b
bind Nothing f = Nothing
bind (Just x) f = f x


In der Konstruktorfunktion unit wird mit Just genau der eine Wert gekapselt. Bind unterscheidet zwischen dem Fall, dass der Wert vom Typ Maybe von der Ausprägung Just x ist oder nicht. Im Falle von Nothing wird Nothing wieder zurückgegeben.

Mit dieser Monade können Funktionen zusammengebunden werden, die jeweils vielleicht einen Wert zurück geben.

1
2
3
4
5
f :: a -> Maybe b
f x = do
	y <- func1 x
	z <- func2 y
	return z



Do-Notation


Ohne die Do-Notation wird pro Bind-Aufruf oft ein neuer Lambda-Ausdruck benötigt. Aus dem Beispiel für die Maybe-Monade wird ohne Do-Notation:

1
2
3
4
5
f :: a -> Maybe b
f x =
	func1 x `bind` \ y ->
	func2 y `bind` \ z ->
	return z



Haskell hat eine kurze Syntax für Lambda-Ausdrücke, die ohne Schlüsselwörter auskommt. Andere Sprachen benötigen für einen äquivalenten Ausdruck deutlich mehr Zeichen. In Sprachen ohne Lambda-Ausdrücken und Closures ist die Verwendung von Monaden nur sehr eingeschränkt möglich, da jedes Statement in der Do-Notation aus einer benannten Funktion und gegebenenfalls aus einem Tupel von gespeicherten Werten bestehen muss.


... [ Programmiersprachen und Sprachsysteme ] ... [ Monaden in anderen Programmiersprachen ] ... [ << Motivation ] ... [ C Sharp >> ] ...
generated by schmidt-doku-generator (GitHub)