(ハスケル、スカラ座やClojureの中に答えをハッピー) 、あなたは機能を持っている>>=
とsequence
:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
sequence :: Monad m => [m a] -> m [a]
>>=
またはバインド機能は、モナド行動をとる値を抽出し、それを新しいモナドのアクションを返す関数に送ります。 sequence
関数は、同じ型のモナドのアクションのリストを取り、それらのすべてを実行し、結果を集約し、単一のアクションとしてラップします。反復のため
お持ちmapM
とforM
(forM = flip mapM
)
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM
とforM
機能は、リストの各要素に対してアクションを返す関数を適用する単一のアクションとして結果を集約するためのものです。
選択のために、私はあなたが条件式を意味するものと仮定します。これはHaskellでif-the-else式として実装されています。それらは、純粋な表現で使用できるものと同じモナド式で直接使用することができます。しかし、特定のモナドを使用して選択肢を実行したり、少なくともエラーを処理したりすることもできます。それは非常に単純な実装を持っている
data Maybe a = Nothing | Just a
instance Monad Maybe where
return a = Just a
(Just a) >>= f = f a
Nothing >>= f = Nothing
:完全に理解するのが最も簡単でMaybe
モナドです。基本的に、Nothing
を他のものにシーケンスすると、毎回Nothing
が返されます。これは、あなた短絡故障の概念を与える:
ここ
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
、"foo"
のルックアップが失敗した場合、myFunc
はすぐNothing
を返します。同様に、"bar"
の検索が失敗した場合、myFunc
はすぐにNothing
を返します。両方のルックアップが成功した場合にのみ、myFunc
は計算を行います。これは、ある種の「エラー処理」を提供します。 「失敗」値は、このような文字列のエラーメッセージまたは障害が発生した時点での計算の状態として、いくつかのコンテキストを運ぶことができ除いて、非常に同じように動作します似たモナド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
があります。
'' = 'は本当にシーケンスを保証するのですか、それとも最も一般的なモナドの動作ですか? – kqr
@kqrあなたが求めているのであれば、評価の順序付けを保証するものではありません。なぜなら、評価の順序は '(>> =)'の定義に依存し、 '(>> =)'のすべての実装が第2引数の前に第1引数を評価するわけではないからです。 –
@kqr順序を保証するものではありませんが、do not表記を使用することができる関数です。これは、質問として解釈したものです。 bindは本質的にdo文の各アクションの(暗黙の)セミコロンを定義するので、特定のコードブロックの制御フローの側面を定義する方法を提供します。 – bheklilr