Exercise 2.80. Define a generic predicate =zero? that tests if its argument is zero, and install it in the generic arithmetic package. This operation should work for ordinary numbers, rational numbers, and complex numbers.
要判断一个数是否是 0,那么在不同的 package,我们就可以分别判断相应类型的数字是否是 0:
- scheme-number (lambda (x) (= 0 x))
- rational (lambda (x) (= 0 (numer x)))
- polar (lambda (x) (= 0 (real-part x)))
- rectangular (lambda (x) (= 0 (real-part x)))
- complex 已经有了 polar 与 rectangular 的判断,所以这里可以直接写为 (lambda (x) (=zero? x))
把以上操作放入相应的包内,并全局定义 =zero? 就可以。
(define (=zero? x) (apply-generic '=zero? x))
借用这个 =zero? 的操作,我们可以定义练习 2.78的 equ?:
(define (equ? x y) (=zero? (sub x y)))
其余不需要变动。
下面是测试:
(load "../testframe.scm")
(asserttrue (=zero? 0))
(asserttrue (=zero? (sub (make-rational 1 12)
(make-rational 1 12))))
(asserttrue (=zero? (make-complex-from-mag-ang 0 12)))
(asserttrue (=zero? (make-complex-from-real-imag 0 0)))
(asserttrue (equ? '(scheme-number . 3) '(scheme-number . 3)))
(asserttrue (equ? 3 3))
(asserttrue (equ? (make-rational 12 20) (make-rational 3 5)))
(asserttrue (equ? (make-complex-from-mag-ang 3 4)
(make-complex-from-mag-ang 3 4)))
(asserttrue (equ? (make-complex-from-mag-ang 3 4)
(make-complex-from-mag-ang 3 4)))
(asserttrue (equ? (make-complex-from-real-imag 1 1)
(sub (make-complex-from-real-imag 2 3)
(make-complex-from-real-imag 1 2))))