In der Fehlermonade stoppt der erste Fehler jede weitere Ausführung, indem der Fehler nur durch folgende Bindungen übertragen wird.
Welche Monade hält am Erfolg an, um nur Erfolge voranzutreiben, Fehler zu verschlucken und die nächste Bindung zu versuchen, ohne das Scheitern der vorherigen zu berücksichtigen?
Die Fehlermonade könnte vielleicht verwendet werden, um Fehler wie Erfolg zu behandeln, aber ich bin gespannt, ob die Standardbibliotheken eine Monade für diesen speziellen Zweck haben, fast wie eine Oder-Monade in meinem Kopf "Mach dies oder das".
Bearbeiten:
Verhalten wäre:
Left "fail" >>= (\x -> Right "win") >>= (\x -> Left "ahh neener") >>= (\x -> Right (x + " yay"))
In der Fehlermonade wird der erste linke Wert nur vorgetragen, das Ergebnis ist also Left "fail"
. Das Verhalten, das ich möchte, ist das, wo das oben Gesagte zurückgibt. Right "win yay"
Es ist eine triviale Monade, die ich selbst schreiben könnte, aber ich dachte, es gibt etwas, um dies zu tun (vielleicht wird entweder nicht verwendet, aber das ist das erste, was mir für ein solches Verhalten einfällt).
Antworten:
Was Sie brauchen, ist MonadPlus (siehe auch Haskell-Wiki ). Es definiert
was einen nicht spezifizierten Fehler darstellt, und
Dies versucht die zweite Berechnung, wenn die erste fehlschlägt. Einige Hilfsfunktionen sind ebenfalls vorhanden:
Instanzen von
MonadPlus
können in zwei Kategorien unterteilt werden:mplus
kombiniert alle möglichen Ergebnisse aus beiden Argumenten (entspricht dem Gesetz der linken Verteilung).[]
undSeq
sind wahrscheinlich die einzigen Fälle mit diesem Verhalten.mplus
wählt das linke Argument aus, wenn es einen gültigen Wert enthält, andernfalls wählt es das rechte aus (entspricht dem Left Catch-Gesetz). Instanzen mit diesem Verhalten sindMaybe
,Either
,STM
undIO
.(
MonadPlus
Instanz von wurdeEither
früher in Control.Monad.Error als definiertaber aus irgendeinem Grund scheint es in der aktuellen Version zu fehlen.)
Siehe auch MonadPlus in Wikibooks und MonadPlus-Definition für Haskell IO .
quelle
Seq
auch ein Beispiel istMonadPlus
. Ich würde es stark über empfehlen[]
, weil Verkettung (mplus
) fürSeq
ist O (log n) während Verkettung von Listen ist O (n) .