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. Well, we've just written
equ?
, so we could get away with simply adding procedures to each package that test for equality using the type-specific equ?
procedure, setting one of the values to the type's equivalent of zero. I.e. 0
for scheme-number
, (make-rat 0 1)
for rational
and either (make-complex-from-real-imag 0 0)
or (make-complex-from-mag-ang 0 0)
for complex
.However, for
rational
and complex
numbers we can have a slightly simpler test. Note that any rational number that is equal to zero will have a numerator of 0. Similarly, any complex number that is equal to zero will have a magnitude of 0. Using this approach we don't need to test the denominator for rational numbers, or the angle (or rectangular form components) for complex numbers.Here's the generic operation and the modifications I made to the packages:
(define (=zero? x) (apply-generic '=zero? x)) (define (install-scheme-number-package) … (put '=zero? '(scheme-number) (lambda (x) (= 0 x))) … 'done) (define (install-rational-package) ;; internal procedures … (define (=zero? x) (= (numer x) 0)) … ;; interface to rest of the system … (put '=zero? '(rational) =zero?) … 'done) (define (install-complex-package) ;; imported procedures from rectangular and polar packages … ;; internal procedures … (define (=zero? x) (= (complex-magnitude x) 0)) … ;; interface to rest of the system … (put '=zero? '(complex) =zero?) … 'done)Similar to the last exercise, if you're wondering about
complex-magnitude
then have a read of my solution to exercise 2.77.Let's give it a spin:
> (=zero? (make-scheme-number 4)) #f > (=zero? (sub (make-scheme-number 3) (make-scheme-number 3))) #t > (=zero? (sub (make-rational 1 2) (make-rational 3 2))) #f > (=zero? (add (make-rational 1 2) (make-rational -2 4))) #t > (=zero? (make-complex-from-real-imag 0 0)) #t > (=zero? (make-complex-from-mag-ang 0 42)) #t
No comments:
Post a Comment