5 Stimmen

Wie funktioniert das getRight :: Either a b -> Maybe b?

Bei HaskellWiki's Do notation considered harmful, im Abschnitt Nützliche Anwendungen fand ich:

Es sei erwähnt, dass das "do" manchmal die Last von dir nimmt, langweilige Dinge zu schreiben.

Zum Beispiel in

getRight :: Either a b -> Maybe b
getRight y =
   do Right x <- y
      return x

ist ein case auf y enthalten, welches fail aufruft, wenn y kein Right (also Left) ist, und daher in diesem Fall Nothing zurückgibt.

Das Aufrufen von fail (Nothing) bei einem Musterfehler klingt interessant, also wollte ich das ausprobieren. Allerdings sieht die Syntax falsch aus - wir sind nicht im Either Monad, also wie können wir etwas aus y extrahieren?

Tatsächlich habe ich es versucht und es gab mir "Couldn't match type `Either a' with `Maybe'". Also verwenden wir den korrekten Pattern Matcher, let hier:

getRight y = do { let (Right x) = y; return x }

Das gab mir einen Syntaxfehler "parse error on input `}'". Nicht dass ich verstehe warum das nicht funktioniert, aber lassen Sie uns es in mehrzeiliger Notation schreiben:

getRight y = do
    let (Right x) = y
    return x

Ah, das schien zu funktionieren - zumindest zu parsen. Allerdings:

*Main> getRight (Right 5)
Just 5
*Main> getRight (Left 5)
Just *** Exception: [...]\test.hs:16:13-25: Irrefutable pattern failed for pattern (Data.Either.Right x)
-- `Nothing` war erwartet

Was ist hier passiert? Warum hat meine Strichpunkt-Klammer Zeile nicht funktioniert?

Wie mache ich es richtig (mit do, alles Andere ist trivial)?

9voto

jberryman Punkte 15978

Das Beispiel ist wahrscheinlich gemeint zu sein

getRight :: Either a b -> Maybe b
getRight y =
   do Right x <- return y -- Hinweis: return = Just
      return x

wo das Pattern-Match-Fehler fail = const Nothing aufruft. Es wird übersetzt in:

getRight y = let ok (Right x) = do {return x}
                 ok _         = fail "pattern mismatch error"
             in return y >>= ok

FWIW denken die meisten erfahrenen Leute fail als eine Monad-Methode war ein Fehler. Schauen Sie sich MonadPlus für einen möglicherweise prinzipielleren Ansatz zum Scheitern an.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X