3

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

我正在尝试编写一个生成 [1,2,2,3,3,3,4,4,4,4.....] 的函数,它基本上是 1 个、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...] 吗?

4

3 回答 3

8

我们正在寻找的函数签名是[[a]] -> [a],如果我们检查hoogle,我们会发现这concat就是我们正在寻找的。

但是在这种情况下,列表推导是不必要的,因为我们只是在迭代每个项目,所以我们真的想做一个map. 所以既然结合mapandconcat很常见,我们可以写

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

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

[1..] >>= \x -> nPrint x x
于 2013-04-01T15:08:22.520 回答
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)
于 2013-04-01T16:42:13.310 回答
0

只需添加concat

nnss :: [Integer]
nnss = concat [nPrint x x | x <- [1,2..]]
于 2013-04-01T19:14:27.030 回答