410 Stimmen

Warum brauchen wir Monaden?

In meiner bescheidenen Meinung versuchen die Antworten auf die berühmte Frage "Was ist ein Monoid?", insbesondere die am meisten bewerteten, zu erklären, was ein Monoid ist, ohne klar zu erklären, warum Monaden wirklich notwendig sind. Können sie als Lösung für ein Problem erklärt werden?

5voto

jdinunzio Punkte 1296

Sie benötigen Monaden, wenn Sie einen Typkonstruktor und Funktionen haben, die Werte dieser Typfamilie zurückgeben. Schließlich möchten Sie diese Art von Funktionen kombinieren. Dies sind die drei Schlüsselelemente, um warum zu beantworten.

Lassen Sie mich näher darauf eingehen. Sie haben Int, String und Real und Funktionen vom Typ Int -> String, String -> Real und so weiter. Sie können diese Funktionen leicht kombinieren und landen bei Int -> Real. Das Leben ist gut.

Dann, eines Tages, müssen Sie eine neue Familie von Typen erstellen. Es könnte sein, weil Sie die Möglichkeit in Betracht ziehen müssen, keinen Wert zurückzugeben (Maybe), einen Fehler zurückzugeben (Either), mehrere Ergebnisse zurückzugeben (List) und so weiter.

Beachten Sie, dass Maybe ein Typkonstruktor ist. Er nimmt einen Typ wie Int und gibt einen neuen Typ Maybe Int zurück. Erste Sache zu merken: kein Typkonstruktor, keine Monad.

Natürlich möchten Sie Ihren Typkonstruktor verwenden in Ihrem Code, und bald enden Sie mit Funktionen wie Int -> Maybe String und String -> Maybe Float. Jetzt können Sie Ihre Funktionen nicht mehr einfach kombinieren. Das Leben ist nicht mehr gut.

Und hier kommen die Monaden zur Rettung. Sie ermöglichen es Ihnen, diese Art von Funktionen wieder zu kombinieren. Sie müssen nur die Komposition von . in >== ändern.

5voto

heisenbug Punkte 384

Monaden sind nur ein praktisches Rahmenwerk zur Lösung einer Klasse wiederkehrender Probleme. Erstens müssen Monaden Funktoren sein (d.h. sie müssen das Abbilden ohne Betrachten der Elemente (oder ihres Typs) unterstützen), sie müssen auch eine Bindung (oder Verkettung) und eine Möglichkeit zum Erstellen eines monadischen Werts aus einem Elementtyp bringen ( return ). Schließlich müssen bind und return zwei Gleichungen erfüllen (linke und rechte Identitäten), die auch als Monadengesetze bezeichnet werden. (Alternativ könnte man Monaden definieren, um eine Aplattierungsoperation anstelle von Bindung zu haben.)

Der Listen-Monad wird häufig zur Behandlung von Nicht-Determinismus verwendet. Die Bindungsausführung wählt ein Element der Liste aus (intuitiv alle in parallelen Welten), ermöglicht dem Programmierer eine Berechnung mit ihnen durchzuführen und kombiniert dann die Ergebnisse in allen Welten zu einer einzelnen Liste (durch Konkatenieren oder Abflachen einer verschachtelten Liste). Hier ist, wie man eine Permutationsfunktion im monadischen Rahmenwerk von Haskell definieren würde:

perm [e] = [[e]]
perm l = do (führer, index) <- zip l [0 :: Int ..]
            lassen Sie verkürzen = nehmen Sie den Index l ++ überspringen Sie (Index + 1) l
            trailer <- perm verkürzt
            return (Führer : Anhänger)

Hier ist ein Beispiel für eine repl Sitzung:

 *Main> perm "a"
["a"]
*Main> perm "ab"
["ab","ba"]
*Main> perm ""
[]
*Main> perm "abc"
["abc","acb","bac","bca","cab","cba"]

Es sei darauf hingewiesen, dass der Listen-Monad in keiner Weise eine Seiteneffektberechnung ist. Eine mathematische Struktur, die eine Monade ist (d.h. den oben genannten Schnittstellen und Gesetzen entspricht), impliziert keine Nebeneffekte, obwohl sich nebenwirkende Phänomene oft gut in das monadische Rahmenwerk einfügen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X