私は次のものを持っています
[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 つのコピーを連結し、その要素が何であれ無視します。
return
for リストはであることを思い出してください\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 をチェックして、あなたが正しかったかどうかを確認してください。次に、それを脱糖し、等式の推論を使用して正しい答えを取得します。