SICP

SICP を読んでみる #73 第二章 p.113

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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です