问题可以在http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-12.html#%_thm_1.37
找到问题是扩展连续分数以接近phi。它表明您的程序应该能够通过评估来计算phi:
(cont-frac (lambda (i) 1.0)
(lambda (i) 1.0)
k)
我的解决方案如下:
(define (cont-frac n d k)
(if (= k 1) d
(/ n (+ d (cont-frac n d (- k 1))))))
此解决方案在调用(cont-frac 1 1 k)时有效,但在问题表明使用lambda表达式时则无效。我得到的是类型错误
;ERROR: "ex-1.37.scm": +: Wrong type in arg1 #<CLOSURE <anon> (x) 1.0>
; in expression: (#@+ #@d (#@cont-frac #@n #@d (#@- #@k 1)))
; in scope:
; (n d k) procedure cont-frac
; defined by load: "ex-1.37.scm"
;STACK TRACE
1; ((#@if (#@= #@k 1) #@d (#@/ #@n (#@+ #@d (#@cont-frac #@n #@d ...
我的问题分为两部分:
问题1.为什么在使用lambda参数时出现此错误?我(错误地,当然)认为(lambda(x)1)应该评估为1.它显然不是。我不确定我是否理解它所评估的内容:我认为它没有评估任何东西(即,“返回一个值” - 可能是错误的术语),而不是传递x的参数。
为什么你会有一个返回常量的lambda,仍然没有回答。如果我理解正确,(lambda(x)1.0)将始终评估为1.0,无论x是什么。那么为什么不放1.0呢?这导致:
问题2.我为什么要使用它们?我怀疑这在ex-1.38中是有用的,我已经看过了,但我不明白为什么使用(lambda(x)1.0)与使用1.0的任何不同。
答案 0 :(得分:2)
在Scheme lambda
中,表达式创建一个函数,因此表达式如:
(lambda (i) 1.0)
确实有结果,它是一个功能对象。
但是如果你在该表达式周围添加括号,它确实将按照你的预期评估为1.0
:
((lambda (i) 1.0))
在练习中使用lambdas对于构建通用解决方案是必要的,正如您在练习1.38中正确注意到的那样,您将使用cont-frac
函数的相同实现,但具有不同的分子和分母函数,以及你会看到一个例子,你应该在运行时使用循环计数器来计算其中一个。
答案 1 :(得分:0)
(/ n (+ d (cont-frac n d (- k 1))))))
在这种情况下,'d'是lambda语句,对'+'没有任何意义,对'n'和'/'也是如此
(/ (n k) (+ (d k) (cont-frac n d (- k 1))))))
你会明白为什么在下一个练习中你也可以使这个尾递归
我将变量命名为F-d和F-n而不是d和n,因为它们接受一个计算分子和分母项的函数。 (lambda(i)1.0)是一个接受一个参数并返回1.0的函数,1.0只是一个数字。在其他连续分数中,该值可能随深度而变化(因此您需要将k传递给分子和分母函数来计算正确的项。