Was ist das Besondere an 'Return' Keyword?

8

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%     
Maksee 10.03.2013, 15:31
quelle

3 Antworten

24
  

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:

  • Monad []
  • Monad I0
  • Monad Maybe
  • Monad STM
  • Monad ((->) r)
  • Monad (Either e)
  • Monad (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

%Vor%

oder in der Begriff do (nützlich, wenn Ausdrücke formulieren ).

%Vor%

Der wahre Grund, ein monadisches return zu verwenden, ist, wenn man mehrere Werte in einer Monade zusammenstellt:

%Vor%

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.

    
Don Stewart 10.03.2013 16:34
quelle
11

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:

%Vor%

Und was macht es? Wenn Sie x angeben, erhalten Sie Just x zurück:

%Vor%

Und jetzt können Sie return als Kurzschrift verwenden, wenn Sie diese Funktion benötigen, anstatt aufzuschreiben:

%Vor%

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.

    
Eric Lippert 10.03.2013 15:35
quelle
1

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.

    
Maksee 12.03.2013 10:03
quelle