Für die Sequenzierung in Haskell, haben Sie die Funktionen >>=
und sequence
:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
sequence :: Monad m => [m a] -> m [a]
Die >>=
oder bind Funktion nimmt eine monadischen Aktion, extrahiert den Wert daraus und füttert es in eine Funktion, die eine neue monadische Aktion zurückgibt. Die sequence
-Funktion nimmt eine Liste von monadischen Aktionen des gleichen Typs und führt alle von ihnen aus, aggregiert ihre Ergebnisse und wickelt sie als eine einzige Aktion ein.
Für Iteration haben Sie mapM
und forM
(forM = flip mapM
)
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
Die mapM
und forM
Funktionen sind für eine Funktion der Anwendung, die eine Aktion für jedes Element in einer Liste zurückgibt, die Ergebnisse als eine einzige Aktion aggregieren.
Zur Auswahl nehme ich an, Sie meinen Bedingungen, die in Haskell als nur If-the-else-Ausdrücke implementiert sind. Sie können direkt in monadischen Ausdrücken verwendet werden, genauso wie sie in reinen Ausdrücken verwendet werden können. Sie können jedoch auch bestimmte Monaden zum Ausführen von Auswahlmöglichkeiten oder zumindest zur Behandlung von Fehlern verwenden. Der einfachste grok ist die Maybe
Monade:
data Maybe a = Nothing | Just a
instance Monad Maybe where
return a = Just a
(Just a) >>= f = f a
Nothing >>= f = Nothing
Es hat eine sehr einfache Implementierung hat. Im Wesentlichen, wenn Sie versuchen, eine Nothing
in etwas anderes zu sequenzieren, wird es Nothing
jedes Mal zurückgeben. Dies gibt Ihnen die Vorstellung von kurzgeschlossen failure:
lookup :: Eq a => a -> [(a, b)] -> Maybe b
-- Looks up a value in a key-value association list
myFunc :: Int -> [(String, Int)] -> Maybe Int
myFunc mult assocList = do
i <- lookup "foo" assocList
j <- lookup "bar" assocList
return $ i * mult + j
Wenn hier die Suche für "foo"
ausfällt, die myFunc
sofort wieder Nothing
. Wenn die Suche nach "bar"
fehlschlägt, gibt myFunc
sofort Nothing
zurück. Nur wenn beide Nachschlagevorgänge erfolgreich sind, führt myFunc
eine Berechnung durch. Dies bietet eine Art "Fehlerbehandlung". Es gibt eine ähnliche Monade Either a
data Either a b = Left a | Right b
instance Monad (Either a) where
return a = Right a
(Right a) >>= f = f a
(Left a) >>= f = Left a
, die sehr ähnlich, mit Ausnahme des „Fehler“ Wert arbeitet, kann etwas Kontext tragen, wie zum Beispiel einer String Fehlermeldung oder den Zustand der Berechnung an dem Punkt des Scheiterns.
Ist '>> =' wirklich garantiert Sequenzierung oder ist das nur das Verhalten der häufigsten Monaden? – kqr
@kqr Es garantiert nicht Sequenzierung der Auswertung, wenn das ist, was Sie fragen.Der Grund dafür ist, weil die Reihenfolge der Auswertung von der Definition von '(>> =)' abhängt, und nicht alle Implementierungen von '(>> =)' das erste Argument vor dem zweiten Argument auswerten. –
@ kqr Es garantiert keine Sequenzierung, aber es ist die Funktion, die es uns erlaubt, die 'do'-Notation zu verwenden, was ich als Frage interpretiert habe. Da bind im Prinzip das (implizierte) Semikolon für jede Aktion in einer do-Anweisung definiert, gibt es uns die Möglichkeit, einen Aspekt des Kontrollflusses für einen bestimmten Codeblock zu definieren. – bheklilr