SICP 読み (70) 2.5.2 異る型のデータの統合
休みとゆー事で公園に本を持っていった。問題 2.85 を再読 (後天性記憶不全です) していると註釈を発見。round 使うとの記述。
直前エントリ (SICP 読み (69)) では切りステ、等書いてあるがとりあえず round と floor の実装の差が以下。
gosh> (floor 5.5) 5.0 gosh> (round 5.5) 6.0 gosh> (floor 5.4) 5.0 gosh> (round 5.4) 5.0 gosh>
round は四捨五入で floor は切りステらしい。ただ、SICP の件の註釈を引用すると
実数は整数へ、引数に最も近い整数を返す round 手続きを使って投影することができる。
とある。たしかにこれはこれで成程かも。ただ、動作としてはどっちでもええと言えばええんだろな、という事でバグではないと判断。floor を round に戻さずにやってみる。
まず、apply-generic に盛り込む前に drop 単体での試験を検討してみる。SICP に記述があるソレ的が以下とすると
試験としては以下ッスか。
("drop test" (setup (lambda () (install-integer-package) (install-rational-package) (install-real-package) (install-complex-package) (install-rectangular-package) (install-polar-package))) ("complex _1.5 + 0i_ can drop real" (let ((t1 (make-complex-from-real-imag 1.5 0))) (assert-equal 'real (type-tag (drop t1))) (assert-true (equ? (make-real 1.5) (drop t1)))) ) ("complex _1.0 + 0i_ can drop integer" (let ((t1 (make-complex-from-real-imag 1.0 0))) (assert-equal 'integer (type-tag (drop t1))) (assert-true (equ? (make-integer 1) (drop t1)))) ) ("complex _2 + 3i_ cannot drop" (let ((t1 (make-complex-from-real-imag 2 3))) (assert-equal 'complex (type-tag (drop t1))) (assert-equal (equ? t1 (drop t1)))) )
で、実装の検討なんですが、
- integer パケジには project 手続きが実装されていない。lower を get-raise して '() が戻る場合には一番下、という判断をする必要あり。
- 後は基本的に project した値と raise な値の比較
なカンジですか。でっち上げた手続きが以下。一応上記の試験にはパスしています。
(define (drop x) (let f ((x x)) (if (null? (get-raise (type-tag x) 'lower)) x (let ((prj (project x)) (before x)) (if (not (equ? (raise prj) before)) before (f prj))))))
備忘録
- 試験はまだ足らない (= バグっている可能性あり)
- 検討の時間が空けば空くほど再開が微妙になる (kernel の件で経験済み)
- このまま apply-generic に盛り込めるんだろうか
とは言え、こっち稼働の確保が現状では相当に (以下略