Welche Monade ist das Gegenteil der Fehlermonade in Haskell

8

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).

Jimmy Hoffa
quelle
Warum das Downvote? Hat diese Frage etwas Schlechtes?
Jimmy Hoffa
Könnten Sie ein kleines Code-Snippet bereitstellen, um zu zeigen, was Sie denken?
Daniel Gratzer
Könnte es sein, dass Sie an Backtracking denken?
Scarfridge

Antworten:

4

Was Sie brauchen, ist MonadPlus (siehe auch Haskell-Wiki ). Es definiert

mzero :: m a

was einen nicht spezifizierten Fehler darstellt, und

mplus :: m a -> m a -> m a

Dies versucht die zweite Berechnung, wenn die erste fehlschlägt. Einige Hilfsfunktionen sind ebenfalls vorhanden:

-- Extends `mplus` to lists of computations:
msum :: MonadPlus m => [m a] -> m a
-- Fails a computation conditionally.
guard :: MonadPlus m => Bool -> m ()
-- Filter (fail) computations that don't satisfy the predicate.
mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a

Instanzen von MonadPluskönnen in zwei Kategorien unterteilt werden:

  1. mpluskombiniert alle möglichen Ergebnisse aus beiden Argumenten (entspricht dem Gesetz der linken Verteilung). []und Seqsind wahrscheinlich die einzigen Fälle mit diesem Verhalten.
  2. mpluswä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 sind Maybe, Either, STMund IO.

( MonadPlusInstanz von wurde Eitherfrüher in Control.Monad.Error als definiert

instance (Error e) => MonadPlus (Either e) where
    mzero            = Left noMsg
    Left _ `mplus` n = n
    m      `mplus` _ = m

aber aus irgendeinem Grund scheint es in der aktuellen Version zu fehlen.)

Siehe auch MonadPlus in Wikibooks und MonadPlus-Definition für Haskell IO .

Petr Pudlák
quelle
Danke, klingt wie Monadplus-Liste ist der Gedanke, den ich hatte.
Jimmy Hoffa
@ JimmyHoffa Ich habe vergessen zu erwähnen, dass dies Seqauch ein Beispiel ist MonadPlus. Ich würde es stark über empfehlen [], weil Verkettung ( mplus) für Seqist O (log n) während Verkettung von Listen ist O (n) .
Petr Pudlák
Das Haskell-Wiki ist sehr aufschlussreich. Es hört sich so an, als würde die Haskell-Community darüber nachdenken, in welche Richtung es gehen soll, genauso wie ich darüber nachdenke, wie es funktionieren soll. ob ich möchte, dass es ein Oder als "Dies oder Das" oder ein Dann, "Dies dann das" ist, bei dem der erste Fehler ein Verhalten wie Oder die Verwendung des Pre-Failure-Werts für den nächsten verursacht, aber ein Erfolg immer noch das nennt Das nächste ist im Gegensatz zu Or und verwendet den von der ersten Funktion zurückgegebenen Wert.
Jimmy Hoffa
Ja, ich unterstütze den Reformvorschlag von MonadPlus . Ich glaube, dies würde die Dinge sehr klarstellen.
Petr Pudlák