2章はデータの抽象がテーマ.
まずは有理数をデータとして表して、符号を正規化できる有理数構築関数make-ratを定義する。
(define (add-rat x y) (make-rat (+ (* (numer x) (denom y)) (* (numer y) (denom x))) (* (denom x) (denom y)))) (define (sub-rat x y) (make-rat (- (* (numer x) (denom y)) (* (numer y) (denom x))) (* (denom x) (denom y)))) (define (mul-rat x y) (make-rat (* (numer x) (numer y)) (* (denom x) (denom y)))) (define (div-rat x y) (make-rat (* (numer x) (denom y)) (* (denom x) (numer y)))) (define (equal-rat? x y) (= (* (numer x) (denom y)) (* (numer y) (denom x)))) (define (make-rat n d) (let ((g (gcd n d)) (sign (if (or (and (positive? n) (positive? d)) (and (negative? n) (negative? n))) 1 -1))) (cons (* sign (/ n g)) (/ d g)))) (define (numer x) (car x)) (define (denom x) (cdr x)) (define (print-rat x) (newline) (display (numer x)) (display "/") (display (denom x)))
負の数同士の乗算でテスト:-(1/3)*-(1/2)
gosh> (define m-one-third (make-rat -1 3)) m-one-third gosh> (define m-one-half (make-rat -1 2)) m-one-half gosh> (print-rat (mul-rat m-one-third m-one-half)) 1/6#<undef>