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

时间:2014-07-21 19:32:27

标签: recursion scheme

我试图编写一个方案递归函数(lookup-env名称环境),它返回一个环境(即关联列表列表)中带有指定名称的绑定(对),如果没有这样的绑定则返回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.

1 个答案:

答案 0 :(得分:0)

这看起来像previous question的后续行动。假设lookup过程正确实现,在发布代码的第二个条件中出现错误(当您尝试获取空列表的car时,这会导致错误) ;在最后一种情况下,递归调用是不正确的,您正在调用错误的过程。试试这个:

(define (lookup-env name environment)
  (cond
    ((null? environment) '())
    ((not (null? (lookup name (car environment))))
     (lookup name (car environment)))
    (else (lookup-env name (cdr environment)))))

但我们可以做得更好,并避免在第二个条件下做一个双lookup

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