SICP 全笔记

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:

  1. scheme-number (lambda (x) (= 0 x))
  2. rational (lambda (x) (= 0 (numer x)))
  3. polar (lambda (x) (= 0 (real-part x)))
  4. rectangular (lambda (x) (= 0 (real-part x)))
  5. complex 已经有了 polar 与 rectangular 的判断,所以这里可以直接写为 (lambda (x) (=zero? x))

把以上操作放入相应的包内,并全局定义 =zero? 就可以。

(define (=zero? x) (apply-generic '=zero? x))

借用这个 =zero? 的操作,我们可以定义练习 2.78equ?

(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))))