2015-04-20 2 views
1

Я пытаюсь создать функцию, которая заворачивается 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.,

Это связаны, но не идентичны осуществлять 1.43 в SICP. Я решил проблему, поскольку она представлена ​​там, но мне любопытно, можно ли ее решить так же.

ответ

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 
1

Проблема с вашим определением состоит в том, что (lambda (x) (f x)) совпадает с f, то есть ваш repeat повторяет только один раз.

Я думаю, что вам нужно, это

(define (repeat f n) 
    (if (= n 1) 
     f 
     (lambda (x) (f ((repeat f (- n 1)) x))))) 

PS. Обратите внимание, что вы используете синтаксис Scheme под тегом Common Lisp; вы можете обновить тот или иной.

+0

Какой синтаксис не распространен? – naomik

+0

'(define (repeat f x) ...)' должно быть '(defun repeat (f x) ...)' – sds

Смежные вопросы