空列表生成器

时间:2016-12-12 02:00:30

标签: haskell

Haskell如何处理列表生成器?具体来说,为什么这个

f n = [x:xs | x <- [1..n], xs <- []]

产生空列表?在每个&#39;迭代中,xs中的x:xs是什么?

1 个答案:

答案 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 - 生成一个空列表的结果。