我正在尝试使用名为n
repeat
次的函数
(define (repeat f n)
(if (= n 1)
f
(repeat (lambda (x) (f x)) (- n 1))))
((repeat inc 5) 2)
我期待结果等于
(inc (inc (inc (inc (inc 2))))) ; 7
但我的结果是3
我做错了什么?
要清楚,我希望repeat
返回一个接受单个参数的函数。在使用参数调用f
的返回值之前,不应应用repeat
。
如,
(define inc5 (repeat inc 5))
(inc5 2) ; => 7
P.S。,
相关但相同在SICP中练习1.43。我已经解决了这个问题,但是我很好奇它是否可以通过这种方式解决。
答案 0 :(得分:2)
您定义的问题是(lambda (x) (f x))
与f
相同,即您的repeat
只重复一次。
我认为你需要的是
(define (repeat f n)
(if (= n 1)
f
(lambda (x) (f ((repeat f (- n 1)) x)))))
PS。请注意,您在Common Lisp标记下使用Scheme语法;你可能想要更新其中一个。
答案 1 :(得分:1)
让我们看一下类似的功能。
(define (repeat-exp fn ct)
(if (= ct 1)
fn
(repeat `(lambda (x) (,fn x)) (- ct 1))))
调用它会让你
> (repeat-exp inc 5)
'(lambda (x)
((lambda (x)
((lambda (x)
((lambda (x)
((lambda (x)
(#<procedure:inc> x))
x))
x))
x))
x))
>
如您所见,您的初始函数只被调用一次;在最里面的评价中。如果你想在每个级别调用它,你也需要在那里调用它。
(define (repeat-exp2 fn ct)
(if (= ct 1)
fn
`(lambda (x)
(,fn (,(repeat-exp2 fn (- ct 1)) x)))))
> (repeat-exp2 inc 5)
'(lambda (x)
(#<procedure:inc>
((lambda (x)
(#<procedure:inc>
((lambda (x)
(#<procedure:inc>
((lambda (x)
(#<procedure:inc>
(#<procedure:inc> x)))
x)))
x)))
x)))
>
现在你可以写出等价的数字。
(define (repeat2 fn ct)
(if (= ct 1)
fn
(lambda (x)
(fn ((repeat2 fn (- ct 1)) x)))))
最初应该做你想做的事。
> (repeat2 inc 5)
#<procedure>
> ((repeat2 inc 5) 2)
7