みんな大好き汎用算術演算!
問題 2.77
これがどうして働くか。
complex は構築子で、 '((complex rectangular x . y)) もしくは '((complex polar r . a)) のようにタグを 2 レベル分持つように 設計されている。複合タグとでも呼べばいいのかな。 complex パッケージに以下のとおり put を追加すると (put 'real-part '(complex) real-part) (put 'imag-part '(complex) imag-part) (put 'magnitude '(complex) magnitude) (put 'angle '(complex) angle) 次のタグ(rectangular もしくは polar) に対して 同じ手続きを評価する動きになる。
トレースせよ。
gosh> (define z (make-complex-from-real-imag 3 4)) gosh> (magnitude z) (magnitude z) ==> (magnitude '((complex rectangular 3 . 4))) ・apply-generic 一回目 op='magnitude args='((complex rectangular 3 . 4)) complex に (put 'magnitude '(complex) magnitude) を追加定義したので、 proc = magnitude で apply proc (map contents args) を評価する。 ・apply-generic 二回目 op=magnitude args='((rectangular 3 . 4)) rectangular で (put 'magnitude '(rectangular) magnitude) として 手続きを put しているので同パッケージの以下 magnitude を評価する。 (define (magnitude z) (sqrt (+ (square (real-part z)) (square (imag-part z))))) (real-part z) = 3, (imag-part z) = 4 なので、 (sqrt (+ 3^2 4^2)) = 5 となるので、 結果として 5 を返す。
問題 2.78
問題にあるように attach-tag, type-tag, contents だけ修正します。
(define (attach-tag type-tag contents) (if (eq? type-tag 'scheme-number) contents (cons type-tag contents))) (define (type-tag datum) (cond ((number? datum) 'scheme-number) ((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))))
手続き内に「'scheme-number」があるのが個人的に微妙な気がします。
gosh> (mul (add 1 2) (add 3 4)) 21
こんな風に内部の数字型がそのまま使えるようになります。