大いにハマった問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 を使うべし。