2015/12/06

# SICP 問題 3.48

``````;; make-accountの引数にidを追加．
;; dispatchの引数に'numberで口座番号を参照できる．
(define (make-account-and-serializer balance id)
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(let ((balance-serializer (make-serializer)))
(define (dispatch m)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
((eq? m 'balance) balance)
((eq? m 'id) id)
((eq? m 'serializer) balance-serializer)
(else (error "Unknown request: MAKE-ACCOUNT" m))))
dispatch))

(define (exchange account1 account2)
(let ((difference (- (account1 'balance)
(account2 'balance))))
((account1 'withdraw) difference)
((account2 'deposit) difference)))

;; 口座番号の小さいほうから先にserialize.
(define (serialized-exchange account1 account2)
(let ((id1 (account1 'id))
(id2 (account2 'id)))
(let ((smaller (if (< id1 id2) account1 account2))
(bigger (if (< id1 id2)) account2 account1))
(let ((serializer1 (smaller 'serializer))
(serializer2 (bigger 'serializer)))
((serializer2 (serializer1 exchange))
account1 account2)))))
``````

t.co

と教えていただいたので書き換えました．

``````;; 口座番号の小さいほうから先にserialize.
(use srfi-11)
(define (serialized-exchange account1 account2)
(let ((id1 (account1 'id))
(id2 (account2 'id)))
(let-values (smaller bigger)
(if (< id1 id2)
(values id1 id2)
(values id2 id1))
(let ((serializer1 (smaller 'serializer))
(serializer2 (bigger 'serializer)))
((serializer2 (serializer1 exchange))
account1 account2)))))
``````