在SICP的sum高阶函数中,参数next的具体含义是什么?
理解SICP中sum函数的
next参数及递归逻辑 嘿,我当初第一次啃SICP的这个sum函数时,也对着next参数和递归调用懵了好一会儿!咱们一步步拆解清楚:
先明确sum函数的参数定义
先把sum的定义再摆出来,方便对应:
(define (sum func a next b) (if (> a b) 0 (+ (func a) (sum func (next a) next b))))
它的四个参数各司其职:
func:你要对每个元素执行的计算函数(比如cube,用来算立方)a:当前迭代的起始值(每次递归会更新这个值)next:一个生成下一个值的函数(比如inc,就是把当前a变成a+1)b:迭代的终止值(整个过程中这个值都不会变)
你误解了递归调用的参数位置!
你提到“递归调用中为何将next传入b的参数位置”,其实这里是参数顺序搞混啦~原函数的参数顺序是func → a → next → b,递归调用(sum func (next a) next b)里:
- 第一个参数还是
func:我们要累加的目标函数没变(还是算立方) - 第二个参数是
(next a):这才是核心——把当前的a推进到下一个值(比如a=1时,(inc 1)就变成2) - 第三个参数还是
next:我们仍然要用同一个“生成下一个值”的规则(比如一直用inc递增) - 第四个参数还是
b:终止条件从头到尾都是10,根本没动过!
举个具体的调用例子帮你理解
比如你调用(sum-cubes 1 10),而sum-cubes的定义应该是:
(define (sum-cubes a b) (sum cube a inc b))
咱们走一遍递归的前几步:
- 第一次调用
sum:func=cube,a=1,next=inc,b=10- 判断
1>10?否,所以计算(+ (cube 1) (sum cube (inc 1) inc 10))→(+ 1 (sum cube 2 inc 10))
- 判断
- 第二次调用
sum:func=cube,a=2,next=inc,b=10- 判断
2>10?否,计算(+ (cube 2) (sum cube 3 inc 10))→(+ 8 (sum cube 3 inc 10))
- 判断
- 就这样一直递推,直到
a=11时,11>10成立,返回0,然后开始回溯把所有值加起来。
next参数的真正意义:让sum变成通用高阶函数
next是SICP里高阶函数的经典体现——把函数当成参数传递,让sum函数不绑定死“怎么迭代”:
- 如果想算1到10的偶数立方和,不用改sum函数,只需要把
next换成(lambda (x) (+ x 2)),调用(sum cube 1 (lambda (x) (+ x 2)) 10)就行 - 如果想从10递减到1的立方和,
next可以写成(lambda (x) (- x 1)),调用(sum cube 10 (lambda (x) (- x 1)) 1)
这样sum函数就变成了一个通用的累加框架,不管你是递增、递减还是跳着走,只要传对应的next函数就行,这就是它的精妙之处!
内容的提问来源于stack exchange,提问作者Nicholas Humphrey
相关产品推荐
相关产品推荐

