結城浩のSICP日記 RSSフィード

2006-05-05

[]第5回 第5回 - 結城浩のSICP日記 を含むブックマーク

Scheme演習 第5回の問1を解きました。

Password を持つ銀行口座を作成せよ

(以下、問題文省略)

素直に書きました。

(define (call-the-cops) "You're under arrest.")
(define (make-account amount password)
  (define error-count 0)
  (define (change-amount! value)
    (set! amount value)
    amount)
  (define (withdraw value)
    (cond ((< amount value) "Insufficient funds")
          ((< value 0) "Invalid value")
          (else (change-amount! (- amount value)))))
  (define (deposit value)
    (cond ((< value 0) "Invalid value")
          (else (change-amount! (+ amount value)))))
  (define (dispatch command value)
    (cond ((equal? command 'withdraw) (withdraw value))
          ((equal? command 'deposit) (deposit value))
          (else "incorrect command")))
  (define (password-error)
    (set! error-count (+ error-count 1))
    (cond ((>= error-count 3) (call-the-cops))
          (else "incorrect password")))
  (define (password-ok) (set! error-count 0))
  (lambda (pass command value)
    (cond ((equal? pass password)
            (password-ok)
            (dispatch command value))
          (else (password-error)))))
(define acc (make-account 10000 'password))

(acc 'password 'withdraw 3000)
;=> 7000

(acc 'password 'withdraw 10000)
;=> Insufficient funds

(acc 'password 'deposit 1000)
;=> 8000

(acc 'wrong 'withdraw 5000)
;=> incorrect password

(acc 'password 'withdraw 5000)
;=> 3000

(acc 'wrong 'withdraw 1000)
;=> incorrect password

(acc 'pass 'deposit 1000)
;=> incorrect password

(acc 'word 'withdraw 1000)
;=> You're under arrest.

疑問:スタイルとして、引数と状態を表す変数をどう区別するのがよいか。