Scheme assoc等效程序运行不正常

Scheme assoc等效程序运行不正常,scheme,associative-array,r5rs,Scheme,Associative Array,R5rs,我正在尝试编写一个类似于Scheme的assoc的过程。两者之间的唯一区别是,我希望我的过程只返回与给定键相关的值,其中AsAssoc给出整个对(key.value)。以下是我的程序: (define alist '((a . 1) (b . 2) (c . 3))) (define (search-list key list) (cond ((null? key) #f) ((eq? (caar list) key) (cdar list)) ((null

我正在尝试编写一个类似于Scheme的assoc的过程。两者之间的唯一区别是,我希望我的过程只返回与给定键相关的值,其中AsAssoc给出整个对(key.value)。以下是我的程序:

(define alist '((a . 1) (b . 2) (c . 3)))

(define (search-list key list)
  (cond ((null? key) #f)
        ((eq? (caar list) key) (cdar list))
        ((null? (cdr list)) #f)
        (else search-list key (cdr list))))
我似乎在正确的轨道上——(搜索列表’a列表)返回1。但是,当使用(search list'b alist)进行测试时,这是我的输出:((b.2)(c.3))

我无法理解为什么我的程序不能按我的意愿运行。如果你能指出我程序中的错误,我将非常高兴。提前感谢。

问题在于最后一行的搜索列表的呼叫(或者说是丢失的呼叫)。由于这不是用括号括起来的,因此从未递归调用该过程,并且该过程返回(cdr list)而不是(search list key(cdr list))。此代码按预期工作:

(define alist '((a . 1) (b . 2) (c . 3)))

(define (search-list key list)
  (cond ((null? key) #f)
        ((eq? (caar list) key) (cdar list))
        ((null? (cdr list)) #f)
        (else (search-list key (cdr list)))))

您发现了错误,但我建议进行其他更改:

1) 在使用
caar
等之前,您应该检查列表是否为空,因为当使用空列表调用时,您的过程将失败

2) OTOH,不需要检查密钥是否为空

3) 在Scheme中,您不应使用
list
作为参数名,以免对过程
list
造成阴影

所以我会选择

(define (search-list key lst)
  (cond
    ((null? lst) #f)
    ((eq? key (caar lst)) (cdar lst))
    (else (search-list key (cdr lst)))))

请注意,您不希望确切地看到
assq
(即
assoc
使用
eq?
而不是
equal?
)的行为,但您仍然可以在实现中使用
assq

(define (search-list key lst)
  (cond ((assq key lst) => cdr)
        (else #f)))

> (search-list 'b '((a . 1) (b . 2) (c . 3)))
2

此外,您现有的代码在使用
'()
列表时会遇到问题,因为
caar
将失败。通常在递归算法中,首先测试基本情况,即您的情况下的
(null?lst)

谢谢您的输入!