理解序列运行逻辑:用accumulate实现length为何用(+ y 1)而非(+ x 1)
accumulate 函数的参数规则
首先明确accumulate(也就是右折叠foldr)调用你传入的op函数时,两个入参的固定含义:
- 第一个入参:当前遍历到的序列元素的值
- 第二个入参:递归处理完当前元素之后的剩余子序列,得到的计算结果
正确写法的逻辑
我们计算序列长度的逻辑是:不管当前元素是什么,只要存在这个元素,总长度就是「剩余子序列的长度」加1。
这里的y刚好就是剩余子序列的长度计算结果,所以(+ y 1)完全匹配需求,最终递归到底(空序列返回初始值0)就会累加得到整个序列的总长度。
举个实际计算例子,求(1 2 3)的长度:
; 递归展开过程 (accumulate (lambda (x y) (+ y 1)) 0 '(1 2 3)) ; 第一步:处理最内层空列表,返回初始值0 => (op 1 (op 2 (op 3 0))) ; 从内向外计算op: ; op 3 0 → 0 + 1 = 1 (子序列(3)的长度是1) ; op 2 1 → 1 + 1 = 2 (子序列(2 3)的长度是2) ; op 1 2 → 2 + 1 = 3 (整个序列的长度是3)
结果完全正确,且不管序列元素是什么类型都不会报错,因为全程没有用到元素x的值。
错误写法的问题
(+ x 1)的写法完全不符合长度计算逻辑:
- 结果错误:你直接把当前元素的值加1,完全忽略了剩余子序列的长度计算结果
y。还是以(1 2 3)为例:
(accumulate (lambda (x y) (+ x 1)) 0 '(1 2 3)) => (op 1 (op 2 (op 3 0))) ; 计算过程: ; op 3 0 → 3 + 1 =4 ; op 2 4 → 2 +1 =3 ; op1 3 →1 +1=2 ; 最终得到错误结果2
- 兼容性差:如果序列元素不是数字(比如
("a" "b" "c")),(+ x 1)会直接抛出类型错误,无法执行。
内容的提问来源于stack exchange,提问作者David542
相关产品推荐
相关产品推荐

