2

私は次のものを持っています

[3,2,1] >> [1]
= [1,1,1]

なぜこれが起こるのか完全には理解できませんか?>>を見ると、結果は [3,2,1] になると思いますが、これはリストでは異なることがわかります。

誰でも理由を説明できますか?

4

3 に答える 3

14

どのモナドでも、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
于 2012-05-06T21:22:17.187 に答える
7

>>次のように定義できます。

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 つのコピーを連結し、その要素が何であれ無視します。

于 2012-05-06T21:20:31.470 に答える
4

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 をチェックして、あなたが正しかったかどうかを確認してください。次に、それを脱糖し、等式の推論を使用して正しい答えを取得します。

于 2012-05-06T23:38:25.237 に答える