Bewerber komponieren, Monaden nicht.
Was bedeutet die obige Aussage? Und wann ist einer dem anderen vorzuziehen?
haskell
functional-programming
monads
monad-transformers
applicative
fehlender Faktor
quelle
quelle
Applicative
s tatsächlich eine ganze Familie vonMonad
s sind, nämlich eine für jede mögliche "Form" der Struktur.ZipList
ist kein aMonad
, aberZipList
s von fester Länge sind.Reader
ist ein praktischer Sonderfall (oder allgemein?), bei dem die Größe der "Struktur" als Kardinalität des Umgebungstyps festgelegt wird.Reader
Monade bis hin zum Isomorphismus entspricht. Sobald Sie die Form eines Containers festgelegt haben, wird eine Funktion effektiv aus Positionen codiert, z. B. eine Notiz. Peter Hancock nennt solche Funktoren "Naperian", da sie den Gesetzen der Logarithmen gehorchen.Antworten:
Wenn wir die Typen vergleichen
Wir bekommen einen Hinweis darauf, was die beiden Konzepte trennt. Das
(s -> m t)
in der Art von(>>=)
zeigt, dass ein Wert ins
das Verhalten einer Berechnung in bestimmen kannm t
. Monaden ermöglichen Interferenzen zwischen der Wert- und der Berechnungsebene. Der(<*>)
Operator lässt keine derartigen Störungen zu: Die Funktions- und Argumentberechnungen hängen nicht von Werten ab. Das beißt wirklich. Vergleichen SieDabei wird das Ergebnis eines Effekts verwendet, um zwischen zwei Berechnungen zu entscheiden (z. B. Raketen abschießen und Waffenstillstand unterzeichnen)
Dabei wird der Wert von verwendet
ab
, um zwischen den Werten zweier Berechnungenat
und zu wählenaf
nachdem beide ausgeführt wurden, möglicherweise mit tragischer Wirkung.Die monadische Version beruht im Wesentlichen auf der zusätzlichen
(>>=)
Fähigkeit, eine Berechnung aus einem Wert auszuwählen, und das kann wichtig sein. Die Unterstützung dieser Kraft macht es jedoch schwierig, Monaden zu komponieren. Wenn wir versuchen, 'Doppelbindung' zu erstellenwir kommen so weit, aber jetzt sind unsere Schichten alle durcheinander. Wir haben eine
n (m (n t))
, also müssen wir das Äußere loswerdenn
. Wie Alexandre C sagt, können wir das tun, wenn wir einen geeigneten habendas Innere
n
undjoin
es zum anderen zu permutierenn
.Die schwächere Doppelanwendung ist viel einfacher zu definieren
weil es keine Interferenz zwischen den Schichten gibt.
Dementsprechend ist es gut zu erkennen, wann Sie wirklich die zusätzliche Leistung von
Monad
s benötigen und wann Sie mit der starren Rechenstruktur davonkommen können, dieApplicative
unterstützt.Beachten Sie übrigens, dass das Komponieren von Monaden zwar schwierig ist, aber möglicherweise mehr als nötig ist. Der Typ
m (n v)
gibt anm
, mitn
-Effekten zu rechnen und dann mit -Effekten zu einem -Wert zu rechnenv
, wobei diem
-Effekte enden, bevor dien
-Effekte beginnen (daher ist dies erforderlichswap
). Wenn Sie nurm
-Effekte mitn
-Effekten verschachteln möchten , ist die Komposition vielleicht zu viel verlangt!quelle
m
undn
Sie immer einen Monadentransformator schreibenmt
und mitn (m t)
verwenden könnenmt n t
? Sie können also immer Monaden komponieren, es ist nur komplizierter, mit Transformatoren?data Free f x = Ret x | Do (f (Free f x))
danndata (:+:) f g x = Inl (f x) | Tnr (g x)
und überlegenFree (m :+: n)
. Dies verzögert die Auswahl der Interleavings.Maybe
Dies bedeutet , dass ein frühesNothing
wird die Bewertung der Unterdrückunga
einer späteren / FolgeJust a
. Ist das richtig?Monaden tun compose, aber das Ergebnis könnte nicht eine Monade sein. Im Gegensatz dazu ist die Zusammensetzung von zwei Applikativen notwendigerweise ein Applikativ. Ich vermute, die Absicht der ursprünglichen Aussage war, dass "Anwendbarkeit komponiert, Monadität nicht". Umformuliert: "Wird
Applicative
unter Komposition geschlossen undMonad
nicht."quelle
Wenn Sie Anwendungen haben
A1
undA2
dann den Typdata A3 a = A3 (A1 (A2 a))
auch anwendbar (Sie können eine solche Instanz generisch schreiben).Wenn Sie dagegen Monaden haben
M1
undM2
der Typdata M3 a = M3 (M1 (M2 a))
dann nicht unbedingt eine Monade ist (es gibt keine sinnvolle generische Implementierung für>>=
oderjoin
für die Komposition).Ein Beispiel kann der Typ sein
[Int -> a]
(hier erstellen wir einen Typkonstruktor,[]
mit dem(->) Int
beide Monaden sind). Sie können leicht schreibenUnd das verallgemeinert sich auf jede Anwendung:
Aber es gibt keine vernünftige Definition von
Wenn Sie davon nicht überzeugt sind, betrachten Sie diesen Ausdruck:
Die Länge der zurückgegebenen Liste muss in Stein gemeißelt werden, bevor jemals eine Ganzzahl angegeben wird. Die richtige Länge hängt jedoch von der bereitgestellten Ganzzahl ab. Daher
join
kann für diesen Typ keine korrekte Funktion existieren.quelle
IO
ohneMonad
wäre ein sehr schwer zu programmieren. :)Monaden komponieren, http://web.cecs.pdx.edu/~mpj/pubs/RR-1004.pdf
quelle
swap : N M a -> M N a
ContT r m a
ist wederm (Cont r a)
nochCont r (m a)
undStateT s m a
ist ungefährReader s (m (Writer s a))
.swap
impliziert, dass die Komposition die beiden irgendwie "kooperieren" lässt. Beachten Sie auch, dasssequence
dies für einige Monaden ein Sonderfall des "Austauschs" ist. So ist esflip
eigentlich.swap :: N (M x) -> M (N x)
, sieht es für mich so aus, als könnten Siereturns
(in geeigneter Weisefmap
ped) eineM
vorne und eineN
hinten einfügen undN (M x) -> M (N (M (N x)))
dann diejoin
des Komposits verwenden, um Ihre zu erhaltenM (N x)
.Die Verteilungsgesetzlösung l: MN -> NM reicht aus
Monadizität von NM zu garantieren. Um dies zu sehen, benötigen Sie eine Einheit und ein Mult. Ich werde mich auf das Mult konzentrieren (die Einheit ist unit_N unitM)
Das geht nicht garantiert , dass MN eine Monade ist.
Die entscheidende Beobachtung kommt jedoch ins Spiel, wenn Sie verteilungsrechtliche Lösungen haben
Somit sind LM, LN und MN Monaden. Es stellt sich die Frage, ob LMN eine Monade ist (entweder von
(MN) L -> L (MN) oder durch N (LM) -> (LM) N.
Wir haben genug Struktur, um diese Karten zu erstellen. Wie Eugenia Cheng jedoch bemerkt , benötigen wir eine hexagonale Bedingung (die einer Darstellung der Yang-Baxter-Gleichung entspricht), um die Monadizität beider Konstruktionen zu gewährleisten. Tatsächlich fallen mit der hexagonalen Bedingung die zwei verschiedenen Monaden zusammen.
quelle