无论如何我可以在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 ...]吗?
答案 0 :(得分:8)
我们正在寻找的功能签名为[[a]] -> [a]
,如果我们检查hoogle,我们会看到concat
是我们正在寻找的。 p>
在这种情况下,列表理解是不必要的,因为我们只是迭代每个项目,所以我们真的只想做一个map
。因此,由于map
和concat
的组合非常常见,我们可以编写
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..]]