Heutzutage wird viel über Monaden gesprochen. Ich habe einige Artikel / Blog-Beiträge gelesen, kann aber mit ihren Beispielen nicht weit genug gehen, um das Konzept vollständig zu verstehen. Der Grund dafür ist, dass Monaden ein funktionales Sprachkonzept sind und die Beispiele daher in Sprachen vorliegen, mit denen ich nicht gearbeitet habe (da ich keine funktionale Sprache ausführlich verwendet habe). Ich kann die Syntax nicht tief genug verstehen, um den Artikeln vollständig zu folgen ... aber ich kann sagen, dass es dort etwas gibt, das es wert ist, verstanden zu werden.
Ich kenne C # jedoch ziemlich gut, einschließlich Lambda-Ausdrücken und anderen funktionalen Merkmalen. Ich weiß, dass C # nur eine Teilmenge von Funktionsmerkmalen hat, und daher können Monaden möglicherweise nicht in C # ausgedrückt werden.
Ist es aber doch möglich, das Konzept zu vermitteln? Zumindest hoffe ich das. Vielleicht können Sie ein C # -Beispiel als Grundlage präsentieren und dann beschreiben, was ein C # -Entwickler von dort aus gerne tun würde , aber nicht, weil der Sprache funktionale Programmierfunktionen fehlen. Das wäre fantastisch, weil es die Absicht und den Nutzen von Monaden vermitteln würde. Hier ist meine Frage: Was ist die beste Erklärung, die Sie einem C # 3-Entwickler für Monaden geben können?
Vielen Dank!
(EDIT: Übrigens, ich weiß, dass es bereits mindestens 3 "Was ist eine Monade?" - Fragen auf SO gibt. Ich habe jedoch das gleiche Problem mit ihnen ... daher wird diese Frage aufgrund des C # -Entwicklers imo benötigt Fokus. Danke.)
Antworten:
Das meiste, was Sie den ganzen Tag programmieren, besteht darin, einige Funktionen miteinander zu kombinieren, um daraus größere Funktionen zu erstellen. Normalerweise haben Sie nicht nur Funktionen in Ihrer Toolbox, sondern auch andere Dinge wie Operatoren, Variablenzuweisungen und dergleichen, aber im Allgemeinen kombiniert Ihr Programm viele "Berechnungen" zu größeren Berechnungen, die weiter miteinander kombiniert werden.
Eine Monade ist eine Möglichkeit, diese "Kombination von Berechnungen" durchzuführen.
Normalerweise ist Ihr grundlegendster "Operator", um zwei Berechnungen miteinander zu kombinieren ,
;
:Wenn Sie dies sagen, meinen Sie "zuerst tun
a
, dann tunb
". Das Ergebnisa; b
ist im Grunde wieder eine Berechnung, die mit mehr Material kombiniert werden kann. Dies ist eine einfache Monade, es ist eine Möglichkeit, kleine Berechnungen mit größeren zu kombinieren. Der;
sagt "mach das Ding links, dann mach das Ding rechts".Eine andere Sache, die in objektorientierten Sprachen als Monade angesehen werden kann, ist die
.
. Oft findet man solche Dinge:Das
.
bedeutet im Grunde "die Berechnung auf der linken Seite auswerten und dann die Methode auf der rechten Seite als Ergebnis davon aufrufen". Es ist eine andere Möglichkeit, Funktionen / Berechnungen miteinander zu kombinieren, etwas komplizierter als;
. Und das Konzept, Dinge miteinander zu verketten,.
ist eine Monade, da auf diese Weise zwei Berechnungen zu einer neuen Berechnung kombiniert werden können.Eine andere ziemlich verbreitete Monade, die keine spezielle Syntax hat, ist dieses Muster:
Ein Rückgabewert von -1 zeigt einen Fehler an, aber es gibt keine echte Möglichkeit, diese Fehlerprüfung zu abstrahieren, selbst wenn Sie viele API-Aufrufe haben, die Sie auf diese Weise kombinieren müssen. Dies ist im Grunde nur eine weitere Monade, die die Funktionsaufrufe nach der Regel kombiniert: "Wenn die Funktion links -1 zurückgibt, geben Sie -1 selbst zurück, andernfalls rufen Sie die Funktion rechts auf". Wenn wir einen Operator hätten
>>=
, der dies tut, könnten wir einfach schreiben:Dies würde die Lesbarkeit verbessern und dazu beitragen, unsere spezielle Art der Funktionskombination zu abstrahieren, sodass wir uns nicht immer wieder wiederholen müssen.
Und es gibt viel mehr Möglichkeiten, Funktionen / Berechnungen zu kombinieren, die als allgemeines Muster nützlich sind und in einer Monade abstrahiert werden können, so dass der Benutzer der Monade viel präziseren und klareren Code schreiben kann, da die gesamte Buchhaltung und Verwaltung von Die verwendeten Funktionen werden in der Monade ausgeführt.
Zum Beispiel könnte das Obige
>>=
erweitert werden, um "die Fehlerprüfung durchzuführen und dann die rechte Seite des Sockets aufzurufen, den wir als Eingabe erhalten haben", so dass wir nichtsocket
oft explizit angeben müssen :Die formale Definition ist etwas komplizierter, da Sie sich Gedanken darüber machen müssen, wie Sie das Ergebnis einer Funktion als Eingabe für die nächste erhalten, wenn diese Funktion diese Eingabe benötigt und Sie sicherstellen möchten, dass die von Ihnen kombinierten Funktionen passen die Art, wie Sie versuchen, sie in Ihrer Monade zu kombinieren. Das Grundkonzept besteht jedoch nur darin, dass Sie verschiedene Arten der Kombination von Funktionen formalisieren.
quelle
;
Beispiel: Welche Objekte / Datentypen werden zugeordnet;
? (ThinkList
MapsT
toList<T>
) Wie werden;
Morphismen / Funktionen zwischen Objekten / Datentypen abgebildet? Was istpure
,join
,bind
für;
?Es ist ein Jahr her, seit ich diese Frage gestellt habe. Nachdem ich es veröffentlicht hatte, beschäftigte ich mich ein paar Monate lang mit Haskell. Ich habe es sehr genossen, aber ich habe es beiseite gelegt, als ich bereit war, mich mit Monaden zu beschäftigen. Ich machte mich wieder an die Arbeit und konzentrierte mich auf die Technologien, die mein Projekt benötigte.
Und letzte Nacht bin ich gekommen und habe diese Antworten noch einmal gelesen. Am wichtigsten ist , dass ich das spezifische C # -Beispiel in den Textkommentaren des Brian Beckman-Videos , das oben erwähnt wurde , erneut lese . Es war so klar und aufschlussreich, dass ich beschlossen habe, es direkt hier zu posten.
Aufgrund dieses Kommentars habe ich nicht nur das Gefühl, genau zu verstehen , was Monaden sind. Mir ist klar, dass ich tatsächlich einige Dinge in C # geschrieben habe, die Monaden sind… oder zumindest sehr nahe beieinander, und mich bemühe, dieselben Probleme zu lösen.
Also, hier ist der Kommentar - dies ist alles ein direktes Zitat aus dem Kommentar hier von Sylvan :
quelle
Eine Monade ist im Wesentlichen eine verzögerte Verarbeitung. Wenn Sie versuchen, Code mit Nebenwirkungen (z. B. E / A) in einer Sprache zu schreiben, die diese nicht zulässt und nur reine Berechnungen zulässt, müssen Sie ausweichen: "Ok, ich weiß, dass Sie keine Nebenwirkungen haben für mich, aber können Sie bitte berechnen, was passieren würde, wenn Sie es tun würden? "
Es ist eine Art Betrug.
Diese Erklärung wird Ihnen helfen, die große Absicht von Monaden zu verstehen, aber der Teufel steckt im Detail. Wie genau Sie berechnen Sie die Konsequenzen? Manchmal ist es nicht schön.
Der beste Weg, um einen Überblick darüber zu geben, wie jemand an imperative Programmierung gewöhnt ist, besteht darin, zu sagen, dass Sie sich in einem DSL befinden, in dem Operationen, die syntaktisch so aussehen, wie Sie es außerhalb der Monade gewohnt sind, stattdessen verwendet werden, um eine Funktion zu erstellen, die dies tun würde Was Sie wollen, wenn Sie (zum Beispiel) in eine Ausgabedatei schreiben könnten. Fast (aber nicht wirklich) so, als würden Sie Code in einer Zeichenfolge erstellen, die später ausgewertet werden soll.
quelle
Maybe
undEither e
) und Statusverwaltung (State s
,ST s
) erscheinen mir als besondere Instanzen von "Bitte berechnen Sie, was passieren würde, wenn Sie [Nebenwirkungen für mich] tun würden". Ein anderes Beispiel wäre Nichtdeterminismus ([]
).Ich bin mir sicher, dass andere Benutzer ausführlich posten werden, aber ich fand dieses Video bis zu einem gewissen Grad hilfreich, aber ich werde sagen, dass ich mit dem Konzept immer noch nicht so fließend bin, dass ich mit dem Lösen beginnen könnte (oder sollte) Probleme intuitiv mit Monaden.
quelle
Sie können sich eine Monade als C # vorstellen
interface
, das Klassen implementieren müssen . Dies ist eine pragmatische Antwort, die alle kategorietheoretischen Berechnungen ignoriert, die dahinter stehen, warum Sie diese Deklarationen in Ihrer Benutzeroberfläche haben möchten, und alle Gründe ignoriert, warum Sie Monaden in einer Sprache haben möchten, die versucht, Nebenwirkungen zu vermeiden. Aber ich fand es ein guter Anfang für jemanden, der (C #) -Schnittstellen versteht.quelle
Siehe meine Antwort auf "Was ist eine Monade?"
Es beginnt mit einem motivierenden Beispiel, arbeitet das Beispiel durch, leitet ein Beispiel für eine Monade ab und definiert formal "Monade".
Es setzt keine Kenntnisse der funktionalen Programmierung voraus und verwendet Pseudocode mit
function(argument) := expression
Syntax mit möglichst einfachen Ausdrücken.Dieses C # -Programm ist eine Implementierung der Pseudocode-Monade. (Als Referenz:
M
Ist der Typkonstruktor,feed
ist die "Bind" -Operation undwrap
ist die "Return" -Operation.)quelle