扩展Haskell中的列表列表

时间:2013-04-01 15:05:14

标签: list haskell list-comprehension

无论如何我可以在Haskell中扩展列表列表吗?

我正在尝试编写一个生成[1,2,2,3,3,3,4,4,4,4 .....]的函数,它基本上是1个,2个,2个,3个三等等。

我的尝试:

nnss :: [Integer]
nnss = [nPrint x x | x <- [1,2..]]

我尝试的问题是nPrint x x返回一个整数列表,例如,nPrint 2 2将返回[2,2]。无论如何,我可以将列表从[1,2,3 ...]“扩展”到[1,2,2,3,3,3 ...]吗?

3 个答案:

答案 0 :(得分:8)

我们正在寻找的功能签名为[[a]] -> [a],如果我们检查hoogle,我们会看到concat是我们正在寻找的。

在这种情况下,列表理解是不必要的,因为我们只是迭代每个项目,所以我们真的只想做一个map。因此,由于mapconcat的组合非常常见,我们可以编写

concatMap (\x -> nPrint x x) [1..]

如果你是haskell的新手,你可以忽略这一点,但由于列表monad是用concatMap定义的,我们也可以写

[1..] >>= \x -> nPrint x x

答案 1 :(得分:1)

你也可以在不使用地图和列表连接的情况下编写它(只是在常量时间前加上):

nnss :: [Integer]
nnss = genRepeated 1 1

genRepeated :: Integer -> Integer -> [Integer]
genRepeated x 0 = genRepeated (x+1) (x+1)
genRepeated x y = x : genRepeated x (y-1)

take 22 nnss == [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,7]

其他快速可能性是:

nnss :: [Integer]
nnss = flatten [take x $ repeat x | x <- [1..]]

flatten :: [[a]] -> [a]
flatten [] = []
flatten ([]:xs) = flatten xs
flatten ((x:xs):ys) = x : flatten (xs:ys)

答案 2 :(得分:0)

只需添加concat

nnss :: [Integer]
nnss = concat [nPrint x x | x <- [1,2..]]