在这个表达式中,x应该比n大1个单位。然而,结果列表大多是由负数组成的。
f :: [Integer]
f = [x-n | x <- [1,2..], n <- [0,1..]]
take 10 f
输出:
[1,0,-1,-2,-3,-4,-5,-6,-7,-8]
我期望它是一个15的列表,我不确定为什么不是这样。
谢谢。
在您的定义中,对于x
的每个值,n
的每个值都与其配对。例如考虑
g :: [Integer]
g = [ (x, n) | x <- [1,2..4], n <- [0,1..3]]
输出为
[(1,0),(1,1),(1,2),(1,3),(2,0),(2,1),(2,2),(2,3),(3,0),(3,1),(3,2),(3,3),(4,0),(4,1),(4,2),(4,3)]
如果您希望x
和n
的元素通过各自的位置配对,则尝试zip
:
f1 = [x-n | (x, n) <- zip [1,2..] [0,1..]]
> take 10 f1
[1,1,1,1,1,1,1,1,1,1]
您给出的代码
f :: [Integer]
f = [x-n | x <- [1,2..], n <- [0,1..]]
是祈使句,相当于
for x in range(1, inf):
for n in range(0, inf):
return x - n
很明显,x
一开始是1
,然后循环n
直到无穷大。所以你得到1 - 0
,1 - 1
,1 - 2
等等。
从你的问题中,我猜你想要对每个列表中的元素逐一配对,而不是嵌套循环。因此,代码应该是
zipWith (-) [1..] [0..] -- this is equal to the infinite list [1,1,1,1,...]
正如@Willem Van Onsen在评论中提到的,你的理解相当于一个嵌套循环,其中x上的外部循环永远不会移动到下一次迭代。因此,对于每个n的值,您看到的是(1 - n)。
你似乎需要的是压缩两个列表在一起,然后做减法,像这样:
f = map (x -> (fst x) - snd x) $ zip [1,2..] [0,1..]
这将从每个列表中成对地获取元素,并进行减法,得到您期望的答案1。