Recursion scheme递归函数如何在最近的环境中返回具有指定名称的绑定

Recursion scheme递归函数如何在最近的环境中返回具有指定名称的绑定,recursion,scheme,Recursion,Scheme,我正在尝试编写一个scheme递归函数lookup env name environment,它返回环境中具有指定名称的绑定对,即关联列表列表,如果未找到此类绑定,则返回null (define (lookup name assoc_list) (cond ((null? assoc_list) '()) ((equal? name (caar assoc_list)) (car assoc_list)) (else (lookup name (cdr assoc_l

我正在尝试编写一个scheme递归函数lookup env name environment,它返回环境中具有指定名称的绑定对,即关联列表列表,如果未找到此类绑定,则返回null

(define (lookup name assoc_list) 
  (cond
    ((null? assoc_list) '())
    ((equal? name (caar assoc_list)) (car assoc_list))
   (else (lookup name (cdr assoc_list)))))


(define (lookup-env name environment) 
  (cond
   ((null? environment) '())
   ((equal? name (car (lookup name environment))) (lookup name environment))
   (else (lookup name (cdr environment)))))
我应该可以像这样测试它

(define l1 '( (ben "short") (cara "walking") (dan "bald")))
(define l2 '( (kurt "is not") (ski "skinny") (kim "cook") (cara "injured")))

(define e (list l1 l2) )

(lookup-env 'ben e)
;Value 14: (ben "short")

(lookup-env 'kurt e)
;Value 15: (kurt "is not")

(lookup-env 'cara e)
;Value 16: (cara "walking")

(lookup-env 'jaga e)
;Value 17: ()
然而,当我尝试它时,我得到了错误

;The object (), passed as the first argument to car, is not the correct type.

这看起来像是一场灾难的后续行动。假设正确地执行了查找过程,那么当您试图驾驶空列表的汽车时,所发布代码的第二个条件中有一个错误,这是导致错误的原因;同样,在最后一种情况下,递归调用是不正确的,您调用了错误的过程。请尝试以下方法:

(define (lookup-env name environment)
  (cond
    ((null? environment) '())
    ((not (null? (lookup name (car environment))))
     (lookup name (car environment)))
    (else (lookup-env name (cdr environment)))))
但我们可以做得更好,避免在第二种情况下进行双重查找:

(define (lookup-env name environment)
  (if (null? environment)
      '()
      (let ((binding (lookup name (car environment))))
        (if (not (null? binding))
            binding
            (lookup-env name (cdr environment))))))

对不起,我认为汽车“返回”@LokiKira这对CL是正确的,而不是对Scheme。@LokiKira就像Sylvester说的,它在Scheme中不是这样工作的。事实上,为了使Scheme中的事情更简单,最好在找不到绑定时查找返回f。目前的情况是,测试是否找到绑定会增加一些麻烦