In Haskell kann ich den Typ verwenden a -> Maybe b
, um eine Funktion zu modellieren, die entweder einen Wert vom Typ b
zurückgibt oder nichts zurückgibt (dies schlägt fehl).
Wenn ich Typen a1, ..., a(n+1)
und Funktionen f1, ..., fn
, mit fi :: ai -> Maybe a(i+1)
für alle i
, 1 <= i <= n
kann ich die Kette , die Funktionen durch die Verwendung des >>=
Betreibers der Maybe
Monade und schreiben:
f1 x >>= f2 >>= f3 >>=... >>= fn
Der >>=
Operator stellt sicher, dass jede Funktion angewendet wird, solange der Vorgänger einen aussagekräftigen Wert zurückgegeben hat. Sobald eine Funktion in der Kette ausfällt, fällt die gesamte Kette aus (kehrt zurück Nothing
) und weitere Funktionen in der Kette werden nicht ausgewertet.
Ich habe ein etwas ähnliches Muster, bei dem ich mehrere Funktionen am selben Eingang ausprobieren und zurückkehren möchte, sobald eine Funktion erfolgreich ist . Wenn alle Funktionen fehlschlagen (return Nothing
), sollte die gesamte Berechnung fehlschlagen. Genauer gesagt habe ich Funktionen f1, ..., fn :: a -> Maybe b
und definiere die Funktion
tryFunctions :: [a -> Maybe b] -> a -> Maybe b
tryFunctions [] _ = Nothing
tryFunctions (f : fs) x = case f x of
Nothing -> tryFunctions fs x
r@(Just _) -> r
In gewissem Sinne ist dies für die Maybe
Monade insofern dual , als eine Berechnung beim ersten Erfolg statt beim ersten Misserfolg stoppt.
Natürlich kann ich die oben beschriebene Funktion verwenden, aber ich habe mich gefragt, ob es eine bessere, gut etablierte und idiomatische Möglichkeit gibt, dieses Muster in Haskell auszudrücken.
Alternative
der Symbol-Infix-Operator <|>
und wird als Monoid definiert
return f1 ?? f2 ?? f3 ?? DefaultValue;