通过改变局部变量,我们可以完成一些需要改变状态的操作。例如,我们可以设计一个收支系统,对某一账户内的金额进行增加和提取。
初始系统:
点击查看代码
#lang racket
(define (make-account balance)(define (withdraw amount)(if (>= balance amount)(begin (set! balance (- balance amount))balance)"Insuffcient funds"))(define (deposit amount)(set! balance (+ balance amount)) balance)(define (dispatch m)(cond ((eq? m 'withdraw) withdraw)((eq? m 'deposit) deposit)(else (error "Unknown request--Make account" m))))dispatch)
点击查看代码
(define (make-accumulator result)(lambda (amount)(begin (set! result (+ result amount)) result)))
------------------------------------------------------------------------
(define A (make-accumulator 10))
> (A 10)
20
> (A 20)
40
点击查看代码
(define (make-monitored f)(let ((count-call 0))(define (do-call args)(set! count-call (+ count-call 1))(apply f args))(define (dispatch . args)(if (= (length args) 1)(cond ((eq? 'how-many-calls? (car args)) count-call)((eq? 'reset-count (car args)) (set! count-call 0))(else (do-call args)))(do-call args)))dispatch))
------------------------------------------------------------------------------------------(define S (make-monitored sqrt))
> (S 100)
10
> (S 'how-many-calls?)
1
练习3.3 修改make-account,创建一种带密码的账户
点击查看代码
(define (make-great-account balance password)(define (withdraw amount)(if (>= balance amount)(begin (set! balance (- balance amount))balance)("余额不足!")))(define (deposit amount)(begin (set! balance (+ balance amount)) balance))(define (incorrect-password . args)(display "密码错误!"))(define (dispath try-password m)(if (eq? try-password password)(cond ((eq? m 'withdraw) withdraw)((eq? m 'deposit) deposit)(else (error "Unknown request--Make account" m)))(incorrect-password)))dispath)
-----------------------------------------------------------------------------------------
(define A1 (make-great-account 1000 'right-ps))
> ((A1 'wrong-ps withdraw) 50)
密码错误!
> ((A1 'right-ps 'withdraw) 50)
950
练习3.4 修改带密码的账户,当被不正确的密码访问7次,则会报警
点击查看代码
(define (make-policed-account balance password)(let ((wrong-count 0))(define (withdraw amount)(if (>= balance amount)(begin (set! balance (- balance amount))balance)("余额不足!")))(define (deposit amount)(begin (set! balance (+ balance amount)) balance))(define (incorrect-password . args)(set! wrong-count (+ wrong-count 1))(display "密码错误!"))(define (wrong-call . args)(if (>= wrong-count 6)(display "called the polices")(incorrect-password)))(define (dispatch try-password m)(if (eq? try-password password)(cond ((eq? m 'withdraw) withdraw)((eq? m 'deposit) deposit)(else (error "Unknown request -- Make policed account" m)))(wrong-call)))dispatch))-------------------------------------------------------------------------------------------------
> (define A2 (make-policed-account 1000 'right-ps))
> ((A2 'wrong-ps 'withdraw) 50)
密码错误!
> ((A2 'wrong-ps 'withdraw) 50)
密码错误!
> ((A2 'wrong-ps 'withdraw) 50)
密码错误!
> ((A2 'wrong-ps 'withdraw) 50)
密码错误!
> ((A2 'wrong-ps 'withdraw) 50)
密码错误!
> ((A2 'wrong-ps 'withdraw) 50)
密码错误!
> ((A2 'wrong-ps 'withdraw) 50)
called the polices
> ((A2 'right-ps 'withdraw) 50)
950