在Haskell中扩展列表的列表
无论如何,我可以在Haskell中扩展列表的列表吗?在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
返回一个整数列表,例如,n打印2 2将返回[2,2]。无论如何,我可以将列表从[1,2,3 ...]扩展到[1,2,2,3,3,3 ...]?
我们正在寻找的函数签名是[[a]] -> [a]
,如果我们检查hoogle,我们发现concat
是我们正在寻找的。
而在这种情况下,列表理解是不必要的,因为我们只是遍历每个项目,所以我们真的想做一个map
。如此以来,结合map
和concat
是如此普遍,我们可以只写
concatMap (\x -> nPrint x x) [1..]
如果你是新来的Haskell但由于名单单子与concatMap
定义我们也可以这样写
[1..] >>= \x -> nPrint x x
如果我们真的想玩哈斯克尔高尔夫球,我们可以做'[1 ..] >> = join replicate',使用'replicate'作为leftaroundabout上面提到的和'Control.Monad'的'join'函数(在这种情况下是for (( - >)r)'monad实例,类型为(r - > r - > a) - > r - > a')。 –
啊谢谢,我试图想到一个功能 – jozefg
你也可以把它写在不使用地图和列表级联(在固定时间内只是在前面加上):
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)
只需添加concat
:
nnss :: [Integer]
nnss = concat [nPrint x x | x <- [1,2..]]
'nPrint'是这个坏名声(印刷是一个IO动作),是什么你使用的基本上只是“复制”。 – leftaroundabout