假设:
Prelude>[ [Just 10, Just 20], [Just 5] ]
[ [Just 10, Just 20], [Just 5] ]
它有类型:
Prelude> :t [ [Just 10, Just 20], [Just 5] ]
[ [Just 10, Just 20], [Just 5] ] :: Num a => [[Maybe a]]
我想将其应用于sequence
:
Prelude> :t sequence
sequence :: Monad m => [m a] -> m [a]
上面列表中的Monad m
是:[a]
,据我所知,所以我希望这些类型排成一行:
sequence :: Monad m => [m a] -> m [a]
[[a]] -> [[a]]
假设没错,那么请帮助我理解输出:
Prelude> sequence [ [Just 10, Just 20], [Just 5] ]
[[Just 10,Just 5],[Just 20,Just 5]]
答案 0 :(得分:3)
sequence
做的是转变
[foo, bar, baz]
类似
do
x <- foo
y <- bar
z <- baz
return [x, y, z]
在你的情况下,我们有
do
x <- [Just 10, Just 5]
y <- [Just 5]
return [x, y]
与
相同foreach x in [Just 10, Just 5]
foreach y in [Just 5]
return [x, y]
in psuedo-OO syntax。
现在应该很明显为什么你会得到你的结果。
答案 1 :(得分:3)
仅使用Int
而不是Maybe Int
来执行此操作可能更容易:
> sequence [[10, 20], [5]]
[[10,5],[20,5]]
it :: [[Int]]
您推断出的类型签名是正确的,在这种情况下它的类型为[[a]] -> [[a]]
,在我的示例中为a ~ Int
,在示例中为a ~ Maybe Int
。每当在列表monad中使用sequence
时,我都会将其视为N维笛卡尔积。它不喜欢像
sequence [a, b, c] = do
x <- a
y <- b
z <- c
return [x, y, z]
但是使用任意数量的元素,而不仅仅是3.其他一些例子可能有助于解释:
sequence [["a1", "a2", "a3"], ["b1", "b2"], ["c1", "c2", "c3"]]
[
["a1","b1","c1"],["a1","b1","c2"],["a1","b1","c3"],["a1","b2","c1"],["a1","b2","c2"],["a1","b2","c3"],
["a2","b1","c1"],["a2","b1","c2"],["a2","b1","c3"],["a2","b2","c1"],["a2","b2","c2"],["a2","b2","c3"],
["a3","b1","c1"],["a3","b1","c2"],["a3","b1","c3"],["a3","b2","c1"],["a3","b2","c2"],["a3","b2","c3"]
]
如果你仔细研究这个输出,你会发现a
的每个元素与b
的每个元素以及c
中的每个元素相匹配。由于有3 a
s,2 b
和3 c
s,因此输出中有3*2*3 == 18
个元素。