Scheme 尝试检查列表中的所有元素是否唯一

Scheme 尝试检查列表中的所有元素是否唯一,scheme,equality,member,Scheme,Equality,Member,正如标题所示,我正在尝试编写一个scheme函数,用于检查列表中的所有元素是否唯一。我已经编写了一些我认为应该有效的代码: (define are-all-unique? (lambda (v) (if (member (car v) (cdr v)) #f (if (pair? v) (are-all-unique? (cdr v)) #t)))) 如果

正如标题所示,我正在尝试编写一个scheme函数,用于检查列表中的所有元素是否唯一。我已经编写了一些我认为应该有效的代码:

(define are-all-unique?
      (lambda (v)
        (if (member (car v) (cdr v))
            #f
            (if (pair? v)
                (are-all-unique? (cdr v))
                #t))))
如果它是错误的,那么它很好用,但是如果我写:

 (are-all-unique? '(1 2 3))
它返回:

Exception in car: () is not a pair

有没有人知道如何解决这个问题,以及我做错了什么

嗯,正如您的错误消息所述,您正试图将空列表传递给car。至于为什么会发生这种情况,让我们看看你的代码。

正如我们所知,我们需要将cons单元传递给car和cdr,以使其工作。我们使用pair?检查此属性,您正在执行此操作。问题是当你在做的时候

调试这样一个函数的最佳方法是跟踪将错误输入传递给函数时发生的情况。它要做的第一件事是在if语句中运行测试:membercarv cdrv。现在,因为我们跟踪的输入是空列表,所以每次都会失败。你想要的是更像这样的东西:

这里需要注意的是这个版本函数的控制流结构:一个合适的列表要么是cons单元格,要么是空列表,因此我们的函数中有两种情况,每种情况一种。在编写处理列表的函数时,大多数情况下都应该决定在非空和空的情况下要做什么,并将列表参数发送到适当的情况作为函数内部要做的第一件事。这种方法在进行结构递归时是合适的,也就是说,用我的一位大一教授的话来说,“数据的结构决定了代码的结构”

;; are-all-equal? is a poor choice of function name, by the way, since that's
;; not really what this function checks
(define are-all-unique? 
  (lambda (v)
    (if (pair? v)
        ; The only way that this branch will ever execute is
        ; if (pair? v) is true, so we know that (car v) and (cdr v)
        ; will never raise any exceptions
        (and (not (member (car v) (cdr v)))
             (are-all-unique? (cdr v)))
        #t)))