<< Previous exercise (3.3) | Index | Next exercise (3.5) >>
(define (make-accumulator acc) (lambda (x) (set! acc (+ acc x)) acc)) (define (make-account balance secret-password) (define (call-the-cops) "The cops have been caled!") (define attempts (make-accumulator 0)) (define (attempts-made) (attempts 0)) (define (reset-attempts) (attempts (- (attempts 0)))) (define (is-correct-password? password) (cond ((equal? secret-password password) (reset-attempts) true) (else (attempts 1) false))) (define (withdraw amount) (cond ((>= balance amount) (set! balance (- balance amount)) balance) (else "Insufficient funds"))) (define (deposit amount) (set! balance (+ balance amount)) balance) (define (dispatch password m) (cond ((not (is-correct-password? password)) (if (> (attempts-made) 7) (lambda (x) (call-the-cops)) (lambda (x) "Incorrect password"))) ((equal? m 'withdraw) withdraw) ((equal? m 'deposit) deposit) (else (error "Unknown request: MAKE-ACCOUNT" m)))) dispatch)
I put all the password-checking functionality into a separate internal function called correct-password?. Unfortunately my implementation of scheme does not know how to (call-the-cops).
(define (make-account balance password)
(define bad-password-count 0)
(define (correct-password? p)
(if (eq? p password)
(set! bad-password-count 0)
(begin
(if (= bad-password-count 7)
(call-the-cops)
(set! bad-password-count (+ bad-password-count 1)))
(display "Incorrect password")
#f)))
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (dispatch p m)
(if (correct-password? p)
(cond
((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request -- MAKE-ACCOUNT" m)))
(lambda (x) (display ""))))
dispatch)
(define (make-account balance password) (define (call-the-cops) "Call the cops") (let ((count 0) (limit 7)) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Not enough money")) (define (deposit amount) (set! balance (+ balance amount)) balance) (define (dispatch pass m) (if (not (eq? pass password)) (lambda (amount) (if (> count limit) (call-the-cops) (begin (set! count (+ count 1)) "Wrong password"))) (begin (set! count 0) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknown call -- MAKE-ACCOUNT" m)))))) dispatch))