如何重复一次函数调用n次

时间:2015-04-20 19:12:33

标签: scheme

我正在尝试使用名为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。我已经解决了这个问题,但是我很好奇它是否可以通过这种方式解决。

2 个答案:

答案 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