将之前写的make-monitored过程添加进去,然后监视pass?谓词的调用次数,然后改造dispatch-password过程,当次数达到7次时,调用call-the-cops过程。
#lang racket
(define (make-account balance password)
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (pass? p)
(eq? p password))
(define pass-monitor? (make-monitored pass?))
(define (call-the-cops f)
(displayln "call-the-cops"))
(define (dispatch-password p m)
(let ((is-pass (pass-monitor? p))
(times (pass-monitor? 'how-many-calls?)))
(cond (is-pass (begin (pass-monitor? 'reset-count) (dispatch m)))
((>= times 7) call-the-cops)
(else (lambda (x) "Insufficient password" )))))
(define (dispatch m)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request -- MAKE-ACCOUNT"
m))))
dispatch-password)
(define (make-monitored f)
(let ((times 0))
(define (func m)
(begin (set! times (+ times 1))
(f m)))
(define (monitor m)
(cond ((eq? m 'how-many-calls?) times)
((eq? m 'reset-count) (set! times 0))
(else (func m))))
monitor))
(define acc (make-account 100 'secret-password))
((acc 'secret-password 'withdraw) 40)
((acc 'some-other-password 'deposit) 40)
((acc 'some-other-password 'deposit) 40)
((acc 'some-other-password 'deposit) 40)
((acc 'some-other-password 'deposit) 40)
((acc 'some-other-password 'deposit) 40)
((acc 'some-other-password 'deposit) 40)
((acc 'some-other-password 'deposit) 40)
运行结果
60
"Insufficient password"
"Insufficient password"
"Insufficient password"
"Insufficient password"
"Insufficient password"
"Insufficient password"
call-the-cops