Als ich zu verstehen schien, was Rendite in Haskell ist, habe ich versucht, mit verschiedenen Alternativen zu spielen, und es scheint, dass die Rendite nicht nur überall in der Monadenkette verwendet werden kann, sondern auch ganz ausgeschlossen werden kann
%Vor%Auch wenn ich die Rückkehr in meiner eigenen Instanz auslasse, werde ich nur gewarnt ...
%Vor%und ich kann immer noch die Monade
verwenden %Vor%Was ist das Besondere am Keyword return? Geht es um komplexere Fälle, in denen ich es nicht auslassen kann? Oder weil dies der "richtige" Weg ist, Dinge auch dann zu tun, wenn sie anders gemacht werden können?
UPDATE: .. oder eine andere Alternative, ich könnte meinen eigenen monadischen Wertkonstruktor definieren
%Vor%und erzeugen Sie eine andere Variante der gleichen Kette (mit dem gleichen Ergebnis)
%Vor%Was ist das Besondere am Keyword return?
Erstens ist return
nicht ein Schlüsselwort in Haskell. Es ist eine überladene Funktion.
Sein Typ ist gegeben durch:
%Vor% Sie sehen also, dass return
eine Funktion ist, die bei einem Wert vom Typ a
einen neuen Wert vom Typ m a
zurückgibt, wobei m
ein Typ ist, der eine Instanz von Monad
ist. Zu diesen Typen gehören:
[]
I0
Maybe
STM
((->) r)
(Either e)
(ST s)
und viele mehr. Instanzen von 'Monad' sollten die folgenden Gesetze erfüllen:
%Vor% Die Implementierung einer Funktion a -> m a
ist ziemlich einfach zu erraten. Hier ist die Definition für die häufigsten Monaden:
Listen :
%Vor%Vielleicht
%Vor% Sie sehen also, dass return
eine überladene Funktion ist, die einen Wert in einen monadischen Wrapper "anhebt". Sie können es also überall dort verwenden, wo Sie seine Definition verwenden können. ZB
oder in der Begriff do
(nützlich, wenn Ausdrücke formulieren ).
Der wahre Grund, ein monadisches return
zu verwenden, ist, wenn man mehrere Werte in einer Monade zusammenstellt:
In der letzten Anweisung sehen Sie, wie die Kette kurzgeschlossen wurde, sobald sie einen Nullwert für die gegebene Monade erreichte. In diesem Fall Nothing
.
Zusammenfassung: return
ist eine überladene Funktion, die einen Wert in einen monadischen Wrapper hebt. Sie verwenden es, wenn Sie Werte heben müssen. Es ist nicht ein Steuerelement-Flow-Schlüsselwort, wie es in Imperativsprachen ist.
Ich vermute, dass Sie falsch verstehen, was "Rückkehr" im Zusammenhang mit einer Monade in Haskell bedeutet. return ist eine Funktion , die ein a
übernimmt und ein "wrapped a
" zurückgibt - also die einfachste mögliche Instanz der Monade. In anderen Sprachen wird es oft als Unit
bezeichnet. Es ist nicht der "Kontrollfluss" return
, den Sie in C-ähnlichen Sprachen sehen.
In Ihrem Beispiel von Maybe
monad haben wir die Rückgabe als Funktion definiert, die ein a
übernimmt und ein Maybe a
zurückgibt:
Und was macht es? Wenn Sie x
angeben, erhalten Sie Just x
zurück:
Und jetzt können Sie return
als Kurzschrift verwenden, wenn Sie diese Funktion benötigen, anstatt aufzuschreiben:
Es heißt return
, denn wenn Sie Monaden in do
Notation schreiben, sieht es so aus, als würden Sie in einer C-ähnlichen Sprache vorgehen.
Mike Hartl Kommentar führte mich in die richtige Richtung, obwohl war nicht so formell imho, also poste ich nur mein letztes Verständnis, was so besonders an "Return" -Operator.
Jede Typklasse listet den von ihr unterstützten Operator auf, und es gibt Funktionen, die nur in diesem Klassenkontext funktionieren können (auferlegt durch class constratint symbol = & gt;). Also zum Beispiel filterM-Signatur
%Vor%zeigt uns, dass es nur im monadischen Kontext verwendet werden kann. Die Magie ist, dass diese Funktion im Körper frei ist, jeden Operator zu verwenden, den die Klasse hat (& gt; & gt; = und für Monad zurückgibt) und wenn eine Instanz (zum Beispiel mein MaybeG) keine Methode (in meinem Fall) hat Funktion kann fehlschlagen. Also wenn die Rückkehr da ist
%Vor%und wenn es kommentiert ist (siehe meine Implementierung von MaybeG in der Frage)
%Vor%Daher ist die Implementation eines beliebigen Operators (Rückgabe in einem Monad-Fall) erforderlich, wenn die Instanz mit Funktionen verwendet werden soll, die mit dieser Klasse (Monade in diesem Fall) arbeiten.
Ich glaube, mein anfängliches Missverständnis beruhte auf der Tatsache, dass die meisten Tutorials monadische Ketten ohne polymorphen (Ad-hoc-) Kontext erklären. Dieser Kontext macht meiner Meinung nach Monaden leistungsfähiger und wiederverwendbar.
Tags und Links haskell functional-programming monads