以下是 equal?
的定义:
;;; 54-equal.scm
(define (equal? x y)
(cond ((and (symbol? x) (symbol? y))
(symbol-equal? x y))
((and (list? x) (list? y))
(list-equal? x y))
(else
(error "Wrong type input x and y -- EQUAL?" x y))))
(define (symbol-equal? x y)
(eq? x y))
(define (list-equal? x y)
(cond ((and (null? x) (null? y)) ; 空表
#t)
((or (null? x) (null? y)) ; 长度不同的表
#f)
((equal? (car x) (car y)) ; 对比 car 部分
(equal? (cdr x) (cdr y))) ; 递归对比 cdr 部分
(else
#f)))
equal?
的定义书上有详细的描述了,一个需要注意的地方是对空列表和长度不同的列表的处理。
另外, equal?
函数使用了 symbol? 函数和 list? 函数对输入类型进行检测,检查它们是否是一个符号或者列表:
1 ]=> (list? (list 1 2 3))
;Value: #t
1 ]=> (list? 3)
;Value: #f
1 ]=> (symbol? 'symbol)
;Value: #t
1 ]=> (symbol? 3)
;Value: #f
测试:
1 ]=> (load "54-equal.scm")
;Loading "54-equal.scm"... done
;Value: list-equal?
1 ]=> (equal? 'symbol 'symbol)
;Value: #t
1 ]=> (equal? 'symbol 'another-symbol)
;Value: #f
1 ]=> (equal? (list 'a 'b 'c) (list 'a 'b 'c))
;Value: #t
1 ]=> (equal? (list 'a) (list 'a 'b 'c))
;Value: #f