哈斯克尔:如何用foldr减去列表中的数字



当你用foldr在列表中添加数字时,它起作用:

sumIntegers :: [Integer] -> Integer
sumIntegers xs = foldr (+) 0 xs

但是substract的工作方式不同,因为减号=加号。[2,3,4,5]类似于:2-3+4-5。

subtractNums' :: Num a => [a] -> a
subtractNums' xs = foldr (-) 0 xs
subtractNums :: Num a => [a] -> a
subtractNums []     = 0
subtractNums (x:xs) = x - subtractNums xs

有什么需要改变的?提前感谢

加法是结合的(并且是交换的,这意味着恒等式是先加在右边,还是最后加在左边都无关紧要(,所以foldrfoldl计算的和相同:

foldr (+) 0 [1,2,3] == 1 + (2 + (3 + 0)) == 1 + 2 + 3 == 6
foldl (+) 0 [1,2,3] == ((0 + 1) + 2) + 3 == 1 + 2 + 3 == 6

然而,减法是而不是关联的;(x - y) - z通常不等于x - (y - z),因此foldrfoldl计算两个不同的结果:

foldl (-) 0 [1,2,3] == ((0 - 1) - 2) - 3 
== (-1 - 2) - 3 
== -3 - 3
== -6
foldr (-) 0 [1,2,3] == 1 - (2 - (3 - 0)) 
== 1 - (2 - 3)
== 1 - -1
== 2

您选择的函数取决于您实际想要计算的运行差。

最新更新