SICP Exercise 2.79

Question

Define a generic equality predicate equ? that tests the equality of two numbers, and install it in the generic arithmetic package. This operation should work for ordinary numbers, rational numbers, and complex numbers.

Answer

The following works:

(define (equ? x y)
  (let ((tx (type-tag x))
        (ty (type-tag y)))
    (cond ((and (eq? tx 'scheme-number)
                (eq? ty 'scheme-number))
           (= x y))
          ((and (eq? tx 'rational)
                (eq? ty 'rational))
           (and (= (numer x) (numer y))
                (= (denom x) (denom y))))
          ((and (eq? tx 'complex)
                (eq? ty 'complex))
           (and (= (real-part x) (real-part y))
                (= (imag-part x) (imag-part y))))
          (else (error "Numbers are of different types: EQU?" )))))

For regular numbers, we can simply use the = operator. For rational and complex numbers, we compare numerator and denominator or real and imaginary part, respectively.