Wenn Sie interessiert sind, hier einige Gedanken eines Nicht-Experten zur Rolle von Monaden und Zusätzen in Programmiersprachen:
Erstens gibt es für eine bestimmte Monade T
eine einzigartige Ergänzung zur Kategorie Kleisli von T
. In Haskell beschränkt sich die Verwendung von Monaden hauptsächlich auf Operationen in dieser Kategorie (die im Wesentlichen eine Kategorie von freien Algebren ohne Quotienten ist). Tatsächlich kann man mit einer Haskell-Monade nur einige Kleisli-Morphismen des Typs a->T b
unter Verwendung von do-Ausdrücken (>>=)
usw. zusammensetzen, um einen neuen Morphismus zu erzeugen. In diesem Zusammenhang beschränkt sich die Rolle von Monaden nur auf die Ökonomie der Notation. Man nutzt die Assoziativität von Morphismen, um schreiben zu können (sagen wir), [0,1,2]
anstatt (Cons 0 (Cons 1 (Cons 2 Nil)))
, dass Sie Sequenz als Sequenz schreiben können, nicht als Baum.
Selbst die Verwendung von E / A-Monaden ist nicht unbedingt erforderlich, da das derzeitige System vom Typ Haskell leistungsfähig genug ist, um die Datenkapselung (existenzielle Typen) zu realisieren.
Dies ist meine Antwort auf Ihre ursprüngliche Frage, aber ich bin gespannt, was Haskell-Experten dazu sagen.
Andererseits gibt es, wie wir bemerkt haben, auch eine 1-1-Entsprechung zwischen Monaden und Zusätzen zu (T-) Algebren. Adjoints sind nach MacLanes Worten "eine Möglichkeit, Äquivalenzen von Kategorien auszudrücken". In einer typischen Einstellung von Zusätzen, in <F,G>:X->A
denen F
es sich um eine Art 'freien Algebra-Generator' und G um einen 'vergesslichen Funktor' handelt, beschreibt die entsprechende Monade (unter Verwendung von T-Algebren), wie (und wann) die algebraische Struktur von aufgebaut A
ist die Objekte von X
.
Im Fall von Hask und der Listenmonade T ist die Struktur, die T
eingeführt wird, die von Monoid, und dies kann uns helfen, Eigenschaften (einschließlich der Korrektheit) von Code durch algebraische Methoden zu ermitteln, die die Theorie der Monoide bereitstellt. Zum Beispiel kann die Funktion foldr (*) e::[a]->a
leicht als assoziative Operation angesehen werden, solange <a,(*),e>
es sich um ein Monoid handelt, eine Tatsache, die vom Compiler ausgenutzt werden könnte, um die Berechnung zu optimieren (z. B. durch Parallelität). Eine andere Anwendung besteht darin, "Rekursionsmuster" in der funktionalen Programmierung unter Verwendung kategorialer Methoden zu identifizieren und zu klassifizieren, in der Hoffnung, "das Goto der funktionalen Programmierung", Y (der willkürliche Rekursionskombinator), (teilweise) zu beseitigen.
Anscheinend ist diese Art von Anwendungen eine der Hauptmotivationen der Schöpfer der Kategorietheorie (MacLane, Eilenberg usw.), nämlich die natürliche Äquivalenz von Kategorien festzustellen und eine bekannte Methode in einer Kategorie auf eine andere zu übertragen (z homologische Methoden zu topologischen Räumen, algebraische Methoden zur Programmierung usw.). Adjunkte und Monaden sind hier unverzichtbare Werkzeuge, um diese Verbindung von Kategorien auszunutzen. (Übrigens ist der Begriff der Monaden (und seiner dualen Comonaden) so allgemein, dass man sogar so weit gehen kann, "Kohomologien" von Haskell-Typen zu definieren. Aber ich habe noch nicht darüber nachgedacht.)
Was nicht deterministische Funktionen betrifft, die Sie erwähnt haben, habe ich viel weniger zu sagen ... Aber beachten Sie, dass; Wenn ein Zusatz <F,G>:Hask->A
für eine Kategorie A
die Listenmonade definiert T
, muss es einen eindeutigen "Vergleichsfunktor" geben K:A->MonHask
(die in Haskell definierbare Kategorie von Monoiden), siehe CWM. Dies bedeutet im Endeffekt, dass Ihre interessierende Kategorie eine Kategorie von Monoiden in einer eingeschränkten Form sein muss (z. B. fehlen möglicherweise einige Quotienten, aber keine freien Algebren), um die Listenmonade zu definieren.
Zum Schluss noch einige Bemerkungen:
Der in meinem letzten Beitrag erwähnte Binärbaum-Funktor lässt sich leicht auf einen beliebigen Datentyp verallgemeinern
T a1 .. an = T1 T11 .. T1m | ...
. Jeder Datentyp in Haskell definiert natürlich eine Monade (zusammen mit der entsprechenden Kategorie von Algebren und der Kleisli-Kategorie), die nur das Ergebnis eines Gesamtdatenkonstruktors in Haskell ist. Dies ist ein weiterer Grund, warum ich denke, dass Haskells Monad-Klasse nicht viel mehr als ein Syntaxzucker ist (was in der Praxis natürlich ziemlich wichtig ist).