为何List.fold_left与List.fold_right执行减法得到不同结果?
为什么
List.fold_left和List.fold_right用减法会得到不同结果? 先看你给出的代码执行结果:
# List.fold_left (-) 100 [1;2;3;4];; - : int = 90 # List.fold_right (-) [1;2;3;4] 100;; - : int = 98
核心原因是减法不满足交换律和结合律,而fold_left和fold_right的计算顺序完全相反,导致最终的运算嵌套结构天差地别。
具体执行过程拆解
List.fold_left (-) 100 [1;2;3;4]的计算步骤
fold_left是从左到右遍历列表,每次用当前累加器和列表元素执行运算,结果作为新的累加器:
- 初始累加器=100,取第一个元素1:
100 - 1 = 99 - 累加器更新为99,取第二个元素2:
99 - 2 = 97 - 累加器更新为97,取第三个元素3:
97 - 3 = 94 - 累加器更新为94,取第四个元素4:
94 - 4 = 90
等价于表达式:((((100 - 1) - 2) - 3) - 4)
List.fold_right (-) [1;2;3;4] 100的计算步骤
fold_right是从右到左遍历列表,每次用列表元素和当前累加器执行运算,结果作为新的累加器:
- 初始累加器=100,取最后一个元素4:
4 - 100 = -96 - 累加器更新为-96,取倒数第二个元素3:
3 - (-96) = 99 - 累加器更新为99,取倒数第三个元素2:
2 - 99 = -97 - 累加器更新为-97,取第一个元素1:
1 - (-97) = 98
等价于表达式:(1 - (2 - (3 - (4 - 100))))
你之前的预期错误在于默认减法和加法一样,不管运算顺序结果都相同,但减法是左结合且不交换的运算,两种fold方法的运算嵌套结构完全反转,最终结果自然不同。如果换成加法(满足交换律和结合律),fold_left和fold_right的结果就会一致。
内容的提问来源于stack exchange,提问作者PoorDecisions
相关产品推荐
相关产品推荐

