Und dann: Monaden ...
Wir haben bislang Haskell vom rein funktionalen Standpunkt aus betrachtet, also großen Wert darauf gelegt, daß die referentielle Transparenz, die dem funktionalen Zugang zugrunde liegt, zur Konstruktion durchsichtiger Programme ausgenutzt wurde. Die einzige Ausnahme, die wir diskutieren mußten, betraf die Interaktion mit der Außenwelt. Hier war es nicht möglich, einen zustandsfreien Zugang zu wählen, weil die referentielle Transparenz nicht gewährleistet sein kann, wie wir gesehen haben. Das hat dann dazu geführt, daß für die Behandlung der Ein-/Ausgabe eine Sonderbehandlung nötig war. Diese Sonderbehandlung zeichnete sich u. A. dadurch aus, daß wir den nicht-funktionalen Teil sorgfältig verkapseln konnten. In gewisser Hinsicht hat dieser nicht-funktionale Teil die Herrschaft über den Ablauf eines Programms übernommen: Wenn wir einmal die Kontrolle an die Ein-/Ausgabe abgegeben hatten, so konnten wir zwar die Funktionen aufrufen, aber eine Interaktion, wie es etwa in Java oder C++ zwischen Ein-/Ausgabe und dem Rest des Programms stattfand, war hier nicht möglich. Diese Eigenschaft werden wir im Folgenden an der einen oder anderen Stelle noch weiter beobachten.
Aber weiter zu den grundsätzlichen Überlegungen: Stellte sich schon die Ein-/Ausgabe als Sonderfall bei der Diskussion von Haskell heraus, so kam ein weiteres Phänomen hinzu, das implizit in allen Funktionen aufscheint. Die einzige Kontrollstruktur, die wir in Haskell zur Verfügung haben, um Berechnungen voranzutreiben, ist die Rekursion, Analogien zum sequentiellen Ablauf von Programmen mußten stets durch die Rekursion beim Aufruf von Funktionen modelliert werden. Es war bislang nicht möglich, Aktionen sequentiell so hintereinander auszuführen, wie das bei sequentiellen Programmen in etwa Java oder C++ möglich ist. Das bedeutet insbesondere, daß wir beim Ablauf von Berechnungen eingeschränkt sind: Wir können nur über die genannten Mechanismen das Resultat einer Berechnung als Eingabe für eine weitere Berechnung benutzen. Dies wurde besonders bei der Diskussion von Faltungen sichtbar, die wir dazu benutzt haben, das Resultat einer partiellen Berechnung entlang einer Liste an das rechte oder das linke Ende zu verschieben.
In diesem abschließenden Kapitel werden Monaden diskutiert, eine weitreichende Möglichkeit, die Beschränkungen, mit denen wir bislang in Haskell gearbeitet haben, zu umgehen. Dieser Zugang zeichnet sich durch theoretische Klarheit aus, er beruht im Wesentlichen auf mathematischen Vorschlägen von Eugenio Moggi, der vorgeschlagen hat, wie man in Datentypen rechnen kann, nämlich mit dem kategorientheoretischen Hilfsmittel der Monaden (philosophisch sind Monaden als Bezeichnung für individuelle, beseelte Individuen mit Namen wie Pythagoras, Platon, Gionardo Bruno oder Leibniz verbunden; sie werden gern als Gegensatz zu den bei Epikur diskutierten und von Lukrez besungenen Atomen gesehen. Monaden werden als in sich abgeschlossene Entitäten betrachtet: Das werden wir auch zu spüren bekommen). Diese Konstruktionen sind in der Mathematik und der Theoretischen Informatik wohlbekannt, es gibt meterweise Literatur zu diesem Ansatz, glücklicherweise ist es aber für den \Haskell-Programmier nicht notwendig, sich in diese kategorientheoretischen Tiefen zu versenken, um Nutzen aus diesen Konstruktionen zu ziehen.
In diesem Kapitel führen wir Monaden mit ihren Operationen und Gesetzen formal ein und besprechen einige Beispiele. Die Zustandsmonade spielt eine wichtige Rolle bei der monadischen Lösung des Acht Damen Problems, sie ist auch hilfreich bei der Diskussion eines monadischen Parsers.
Wir haben bislang Haskell vom rein funktionalen Standpunkt aus betrachtet, also großen Wert darauf gelegt, daß die referentielle Transparenz, die dem funktionalen Zugang zugrunde liegt, zur Konstruktion durchsichtiger Programme ausgenutzt wurde. Die einzige Ausnahme, die wir diskutieren mußten, betraf die Interaktion mit der Außenwelt. Hier war es nicht möglich, einen zustandsfreien Zugang zu wählen, weil die referentielle Transparenz nicht gewährleistet sein kann, wie wir gesehen haben. Das hat dann dazu geführt, daß für die Behandlung der Ein-/Ausgabe eine Sonderbehandlung nötig war. Diese Sonderbehandlung zeichnete sich u. A. dadurch aus, daß wir den nicht-funktionalen Teil sorgfältig verkapseln konnten. In gewisser Hinsicht hat dieser nicht-funktionale Teil die Herrschaft über den Ablauf eines Programms übernommen: Wenn wir einmal die Kontrolle an die Ein-/Ausgabe abgegeben hatten, so konnten wir zwar die Funktionen aufrufen, aber eine Interaktion, wie es etwa in Java oder C++ zwischen Ein-/Ausgabe und dem Rest des Programms stattfand, war hier nicht möglich. Diese Eigenschaft werden wir im Folgenden an der einen oder anderen Stelle noch weiter beobachten.
Aber weiter zu den grundsätzlichen Überlegungen: Stellte sich schon die Ein-/Ausgabe als Sonderfall bei der Diskussion von Haskell heraus, so kam ein weiteres Phänomen hinzu, das implizit in allen Funktionen aufscheint. Die einzige Kontrollstruktur, die wir in Haskell zur Verfügung haben, um Berechnungen voranzutreiben, ist die Rekursion, Analogien zum sequentiellen Ablauf von Programmen mußten stets durch die Rekursion beim Aufruf von Funktionen modelliert werden. Es war bislang nicht möglich, Aktionen sequentiell so hintereinander auszuführen, wie das bei sequentiellen Programmen in etwa Java oder C++ möglich ist. Das bedeutet insbesondere, daß wir beim Ablauf von Berechnungen eingeschränkt sind: Wir können nur über die genannten Mechanismen das Resultat einer Berechnung als Eingabe für eine weitere Berechnung benutzen. Dies wurde besonders bei der Diskussion von Faltungen sichtbar, die wir dazu benutzt haben, das Resultat einer partiellen Berechnung entlang einer Liste an das rechte oder das linke Ende zu verschieben.
In diesem abschließenden Kapitel werden Monaden diskutiert, eine weitreichende Möglichkeit, die Beschränkungen, mit denen wir bislang in Haskell gearbeitet haben, zu umgehen. Dieser Zugang zeichnet sich durch theoretische Klarheit aus, er beruht im Wesentlichen auf mathematischen Vorschlägen von Eugenio Moggi, der vorgeschlagen hat, wie man in Datentypen rechnen kann, nämlich mit dem kategorientheoretischen Hilfsmittel der Monaden (philosophisch sind Monaden als Bezeichnung für individuelle, beseelte Individuen mit Namen wie Pythagoras, Platon, Gionardo Bruno oder Leibniz verbunden; sie werden gern als Gegensatz zu den bei Epikur diskutierten und von Lukrez besungenen Atomen gesehen. Monaden werden als in sich abgeschlossene Entitäten betrachtet: Das werden wir auch zu spüren bekommen). Diese Konstruktionen sind in der Mathematik und der Theoretischen Informatik wohlbekannt, es gibt meterweise Literatur zu diesem Ansatz, glücklicherweise ist es aber für den \Haskell-Programmier nicht notwendig, sich in diese kategorientheoretischen Tiefen zu versenken, um Nutzen aus diesen Konstruktionen zu ziehen.
In diesem Kapitel führen wir Monaden mit ihren Operationen und Gesetzen formal ein und besprechen einige Beispiele. Die Zustandsmonade spielt eine wichtige Rolle bei der monadischen Lösung des Acht Damen Problems, sie ist auch hilfreich bei der Diskussion eines monadischen Parsers.