Re[3]: lisp, lambda & рекурсия
От: z00n  
Дата: 28.09.06 16:00
Оценка: 73 (8) +2
Здравствуйте, Аноним, Вы писали:

А>>Передать её её-же в качестве одного из параметров


А>>Пример нужен?


А>Нужен. Как такое возможно?


Примеры на Scheme.

Во-первых, заметим, что такая функция сама себя вызывает рекурсивно и выглядит достаточно очевидно:

; запуск приведет к бесконечному циклу:
((lambda(x) (x x))
 (lambda(x) (x x)))


Теперь попробуем сделать нечто осмысленное на примере факториала:
; factorial-maker:
(lambda(F)
 (lambda(n)
  (if (zero? n) 
      1
      (* n (F (- n 1))))))

Это функция вернет нам правильную функцию факториала, если мы придумаем, как будет выглядеть F.

Нубольшое умственное напряжение приводит нас к:
((lambda(F)(F F))
 (lambda(F)
  (lambda(n)
   (if (zero? n)
       1
       (* n ((F F) (- n 1)))))))

Это и есть рекурсивный факториал! Проверяем:

(((lambda(x)(x x))
  (lambda(F)
    (lambda(n)
      (if (zero? n)
          1
          (* n ((F F) (- n 1)))))))
 5) ; => 120


Осталось еще немного подумать и обобщить это до Y-комбинатора
(define Y
  (lambda (X)
    ((lambda (procedure)
       (X (lambda (arg) ((procedure procedure) arg))))
     (lambda (procedure)
       (X (lambda (arg) ((procedure procedure) arg)))))))

; test:
((Y (lambda(fact)
      (lambda(n)
        (if (zero? n) 
            1 
            (* n (fact (- n 1)))))))
 5) ; => 120
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.