我的问题是关于sequence
中的Prelude
函数,其签名如下:
sequence :: Monad m => [m a] -> m [a]
我了解此功能对List
Maybe
的效果如何。例如,在sequence
上应用[Just 3, Just 9]
会产生Just [3, 9]
。
我注意到在sequence
的{{1}}上应用List
会给出其笛卡尔积。有人可以帮我理解这是怎么回事?为什么会这样?
答案 0 :(得分:31)
这很有效,因为在Haskell中使用列表作为monad会使它们成为模型的不确定性。考虑:
sequence [[1,2],[3,4]]
根据定义,它与:
相同do x <- [1,2]
y <- [3,4]
return [x,y]
只需将其读作“首先选择1和2之间,然后选择3到4”。列表monad现在将累积所有可能的结果 - 因此答案[[1,3],[1,4],[2,3],[2,4]]
。
(对于更加模糊的例子,请参阅here)
答案 1 :(得分:20)
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
]
答案 2 :(得分:2)
只是为了解释一下,为什么将序列应用到列表列表与序列应用到Maybe-values列表有很大不同:
当您将sequence
应用于列表列表时,序列类型将专门用于
sequence :: Monad m => [m a] -> m [a]
to(类型构造函数m设置为[])
sequence :: [[] a] -> [] [a]
(与sequence :: [[a]] -> [[a]]
相同)
在内部,序列使用(&gt;&gt; =) - 即monadic绑定函数。对于列表,这个绑定函数的实现完全不同于m设置为Maybe!