Geek-Side

Resource > SICP Exersise 3_4
Exersise 3.4
make-account関数にパスワードを7回間違えると通報する機能をつける

 (define (make-account balance password)
   (let ((saved-password "")
 	(incorrect 0))
     (define (call-the-cops x) "cops!!!!!!!")
     (define (withdraw amount)
       (if (>= balance amount)
 	  (begin (set! balance (- balance amount))
 		 balance)
 	  "Insufficient funds"))
     (define (deposit amount)
       (set! balance (+ balance amount))
       balance)
     (define (dispatch password m)
       (if (equal? saved-password password)
 	  (begin (set! incorrect 0)
 		 (cond ((eq? m 'withdraw) withdraw)
 		       ((eq? m 'deposit) deposit)
 		       (else (error "Unknown request -- MAKE-ACCOUNT"
 				    m))))
 	  (begin (set! incorrect (+ incorrect 1))
 		 (cond [(> incorrect 6) call-the-cops]
 		       [else (error "Incorrect password")]))))
     (begin (set! saved-password password)
 		 dispatch)))
 
 (use gauche.test)
 (test-start "Exersise 3.3")
 (define acc (make-account 100 'secret-password))
 (test* "withdraw" 60 ((acc 'secret-password 'withdraw) 40))
 (test* "deposit" 110 ((acc 'secret-password 'deposit) 50))
 (test* "error1" *test-error*  ((acc 'some-other-password 'deposit) 50))
 (test* "error2" *test-error*  ((acc 'some-other-password 'deposit) 50))
 (test* "error3" *test-error*  ((acc 'some-other-password 'deposit) 50))
 (test* "error4" *test-error*  ((acc 'some-other-password 'deposit) 50))
 (test* "error5" *test-error*  ((acc 'some-other-password 'deposit) 50))
 (test* "error6" *test-error*  ((acc 'some-other-password 'deposit) 50))
 (test* "error7" "cops!!!!!!!"  ((acc 'some-other-password 'deposit) 50))
 (test-end)