SICP 1.44:调用(smooth-n square 3) 2返回#<procedure>的问题排查
问题分析与修复方案
嘿,我发现你的代码里的repeat函数逻辑搞错了,这才导致调用((smooth-n square 3) 2)返回过程而非预期的计算结果。
问题根源
先看你的smooth函数:它接收一个函数,返回另一个函数——这个新函数会计算原函数在x-dx、x、x+dx三个点的平均值。而你的repeat函数误用了compose,导致逻辑完全偏离了需求:
你的repeat里用了(compose f result),这里的f是smooth,result是之前的函数。compose smooth result会生成这样一个函数:
(lambda (x) (smooth (result x)))
当你调用这个函数时,会先执行(result x)得到一个数值,然后把这个数值传给smooth——但smooth需要的是一个函数,不是数值!这就导致这个复合函数根本无法正确完成平滑计算,最终返回的过程自然无法输出你想要的数值结果。
我们真正需要的repeat,应该是把smooth重复应用到函数上:比如n=3时,要得到smooth(smooth(smooth(square))),而不是用compose做函数复合。
修复后的代码
方案1:递归版repeat
把repeat改成直接重复应用变换函数(这里是smooth)到初始函数上:
#lang planet neil/sicp (define dx 0.00001) (define (smooth f) (lambda (x) (/ (+ (f x) (f (- x dx)) (f (+ x dx))) 3))) ; 修正后的repeat函数:重复将transform应用到f上n次 (define (repeat transform f n) (if (< n 1) f (repeat transform (transform f) (- n 1)))) (define (smooth-n f n) (repeat smooth f n)) (define (square x) (* x x))
方案2:迭代版repeat
如果你更喜欢迭代风格,也可以写成这样:
(define (repeat transform f n) (define (iter n current-func) (if (< n 1) current-func (iter (- n 1) (transform current-func)))) (iter n f))
测试验证
现在调用((smooth-n square 3) 2),就能得到正确的数值结果了:它会先对square做3次平滑处理,然后计算这个三次平滑后的函数在x=2处的值。
内容的提问来源于stack exchange,提问作者song qi
相关产品推荐
相关产品推荐

