私は次のものを持っています
[3,2,1] >> [1]
= [1,1,1]
なぜこれが起こるのか完全には理解できませんか?>>を見ると、結果は [3,2,1] になると思いますが、これはリストでは異なることがわかります。
誰でも理由を説明できますか?
どのモナドでも、a >> bとして変換できますa >>= \_ -> b。リストモナドでは、バインド演算子(>>=)はconcatMap引数が反転しているため、例は次と同等です
concatMap (\_ -> [1]) [3, 2, 1]
このように評価できます。
concatMap (\_ -> [1]) [3, 2, 1]
= concat (map (\_ -> [1]) [3, 2, 1]) -- definition of concatMap
= concat [[1], [1], [1]] -- apply map
= [1, 1, 1] -- apply concat
>>次のように定義できます。
ma >> mb = ma >>= const mb
Monad(これは のインスタンスでの実際の定義では[]ありませんが、問題ではありません。)
リストの場合、 の各要素に対して[1,2,3]が得られ、全体の結果は、つまり に[1]相当します。concat [[1],[1],[1]][1,1,1]
[]GHC.Baseのインスタンスは次のとおりです。
m >>= k = foldr ((++) . k) [] m
m >> k = foldr ((++) . (\ _ -> k)) [] m
ここでは折り畳みを使用して、左側の要素ごとに右側の 1 つのコピーを連結し、その要素が何であれ無視します。
returnfor リストはであることを思い出してください\x -> [x]。おそらく、あなたの例を次のように書き直せばより明確になるでしょう。return
[1,2,3] >> return 1
do記法シュガーを追加しましょう
do [1,2,3]
return 1
今見えますか?>>左の引数から値を取得せず、それらを囲むコンテキストのみを取得します。この場合、コンテキストは 3 要素のリストです。つまり、すべて非決定論的に選択された 3 つの異なる選択肢です。次に、それぞれのケースで、return 1.
あなたが代わりにやっていたら
do x <- [1,2,3]
return x
次に、各ケースで 1 を選択するのではなくx、各「ブランチ」の特定の選択を表す を選択します。この結果がどうなるかを推測してみて、ghci をチェックして、あなたが正しかったかどうかを確認してください。次に、それを脱糖し、等式の推論を使用して正しい答えを取得します。