Haskell如何处理列表生成器?具体来说,为什么这个
f n = [x:xs | x <- [1..n], xs <- []]
产生空列表?在每个&#39;迭代中,xs
中的x:xs
是什么?
答案 0 :(得分:10)
缩小的答案就是......
[x:xs | x <- [1..n], xs <- []]
...包含从x
中选取一个元素([1..n]
)加上xs
中的元素([]
)并在其中添加前一个生成的所有可能列表其他。由于[]
中没有元素,因此以这种方式生成的列表数为零。
放大的答案是list comprehensions are sugar for the list monad,所以这......
[x:xs | x <- [1..n], xs <- []]
......等同于......
do
x <- [1..n]
xs <- []
return (x:xs)
......那就是(在脱离了写法后)......
[1..n] >>= \x ->
[] >>= \xs ->
return (x:xs)
-- Or, without the line breaks:
[1..n] >>= \x -> [] >>= \xs -> return (x:xs)
......即(在用(>>=)
和return
的定义代替列表monad之后):
concatMap (\x -> concatMap (\xs -> [x:xs]) []) [1..n]
concatMap
(顾名思义,仅map
后跟concat
)在空列表中给出一个空列表,因此它变为...
concatMap (\x -> []) [1..n]
...相当于用空列表替换[1..n]
的每个元素,然后concat
- 生成一个空列表的结果。