scheme3.1.1 局部状态变量
通过改变局部变量,我们可以完成一些需要改变状态的操作。例如,我们可以设计一个收支系统,对某一账户内的金额进行增加和提取。
初始系统:
点击查看代码
#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

浙公网安备 33010602011771号