Не удалось заставить работать комбинатор Y

Вот код (также здесь):

#lang racket
(define poorY
  ((lambda length
    (lambda (ls)
      (cond
        [(null? ls) 0]
        [else (add1 ((length length) (cdr ls)))])))
  (lambda length
    (lambda (ls)
      (cond
        [(null? ls) 0]
        [else (add1 ((length length) (cdr ls)))])))))

Когда я запускаю его:

> (poorY '(9 7 8))
. . application: not a procedure;
 expected a procedure that can be applied to arguments
  given: '(#<procedure>)
  arguments...:
   '(#<procedure>)

Скриншот выглядит так:

введите здесь описание изображения

Я использую DrRacket в качестве замены. Что не так с кодом?


person Hanfei Sun    schedule 12.08.2012    source источник


Ответы (1)


Вокруг length должны быть скобки:

(define poorY
  ((lambda (length)  ;; here
    (lambda (ls)
      (cond
        [(null? ls) 0]
        [else (add1 ((length length) (cdr ls)))])))
  (lambda (length)   ;; and here
    (lambda (ls)
  ......

Вместо того, чтобы дважды вводить одно и то же длинное лямбда-выражение, вы также можете попробовать

(define poorY
  ((lambda (f) (f f))
   (lambda (length)
     (lambda (ls)
       (cond
         [(null? ls) 0]
         [else (add1 ((length length) (cdr ls)))])))))

См. также обсуждение комбинатора Y в The Little Schemer .

person Will Ness    schedule 12.08.2012