35

私の質問は、のsequence関数についてですPrelude。その署名は次のとおりです。

sequence :: Monad m => [m a] -> m [a]

Listこの関数がsに対してどのように機能するかを理解していますMaybe。たとえば、に適用sequenceする[Just 3, Just 9]Just [3, 9]

sequencesを適用するListList、デカルト積が得られることに気付きました。誰かが私がこれがどのように/なぜ起こるのかを理解するのを手伝ってくれますか?

4

3 に答える 3

34

これが機能するのは、Haskellでリストをモナドとして使用すると、リストが非決定論をモデル化するためです。検討:

sequence [[1,2],[3,4]]

定義上、これは次と同じです。

do x <- [1,2]
   y <- [3,4]
   return [x,y]

「最初に1から2の間の選択、次に3から4の間の選択」と読んでください。リストモナドは、考えられるすべての結果を蓄積するようになります-したがって、答え[[1,3],[1,4],[2,3],[2,4]]です。

(さらにわかりにくい例については、こちらを参照してください)

于 2011-03-14T14:33:25.997 に答える
21

sequenceこのように定義されているかのように動作します。

sequence [] = return []
sequence (m:ms) = do
    x <- m
    xs <- sequence ms
    return (x:xs)

(またはsequence = foldr (liftM2 (:)) (return [])とにかく…)

リストのリストに適用するとどうなるかを考えてみてください。

sequence [] = [[]]
sequence (list : lists) =
    [ x : xs
    | x <- list
    , xs <- sequence lists
    ]
于 2011-03-14T13:52:40.320 に答える
5

説明するために、リストのリストへのシーケンスの適用が、多分値のリストへのシーケンスの適用と非常に異なる理由は次のとおりです。

リストのリストに適用する場合sequence、シーケンスのタイプは

sequence :: Monad m => [m a] -> m [a]

to(型コンストラクターmを[]に設定)

sequence :: [[] a] -> [] [a] 

(これはと同じですsequence :: [[a]] -> [[a]]

内部的には、シーケンスは(>> =)を使用します。つまり、モナディックバインド関数です。リストの場合、このバインド関数は、mがMaybeに設定されている場合とは完全に異なる方法で実装されます。

于 2011-03-14T21:38:40.037 に答える