大いにハマった問2.77も済んで、やっと前に進めます。
問題解答
問 2.78
(define (attach-tag type-tag contents)
(if (eq? type-tag 'scheme-number)
contents
(cons type-tag contents)))
(define (type-tag datum)
(cond ((number? datum) datum)
((pair? datum) (car datum))
(else (error "Bad tagged datum -- TYPE-TAG" datum))))
(define (contents datum)
(cond ((number? datum) datum)
((pair? datum) (cdr datum))
(else (error "Bad tagged datum -- CONTENTS" datum))))
この方法は場当たり的な感じがしてちょっと嫌な感じがするかな。
問 2.79
equ? の大元を定義。
(define (equ? x y) (apply-generic 'div x y))
install-scheme-number-package に追加
(put 'equ? '(scheme-number scheme-number)
(eq? x y))
install-rational-package に追加
(define (equ? x y)
(if (not (eq? (numer x) (numer x)))
#f
(if (not (eq? (denom x) (denom x)))
#f
#t)))
(put 'equ? '(rational rational)
(lambda (x y) (equ? x y)))
※先人の知恵と比較したら、±の判別が甘かった
(define (equ?-rat x y)
(or (and (= (numer x) (numer y)) (= (denom x) (denom y)))
(and (= (numer x) (- (numer y))) (= (denom x) (- (denom y))))))
install-rectangular-package に追加
(define (equ? x y)
(if (not (eq? (magnitude x) (magnitude y)))
#f
(if (not (eq? (angle x) (angle y)))
#f
#t)))
(put 'equ? '(rectangular rectangular)
(lambda (x y) (equ? x y)))
install-complex-package に追加
(define (equ? x y)
(if (not (eq? (real-part x) (real-part y)))
#f
(if (not (eq? (imag-part x) (imag-part y)))
#f
#t)))
(put 'equ? '(complex complex)
(lambda (x y) (equ? x y)))
以上。自分の解答では if をネストしているのがダサい。 and や or を使うべし。