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)
练习3.1 制作一个累加器
点击查看代码
(define (make-accumulator result)
  (lambda (amount)
     (begin (set! result (+ result amount)) result)))
------------------------------------------------------------------------
(define A (make-accumulator 10))
> (A 10)
20
> (A 20)
40
练习3.2 制作一个程序调用次数的计数器
点击查看代码
(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
posted @ 2026-01-22 22:34  檐上落白luckin  阅读(0)  评论(0)    收藏  举报