Схема - переменная доступа в закрытии
Допустим, у меня есть следующее замыкание в Scheme, которое увеличивает счетчик каждый раз, когда он вызывается:
(define count
(let ((next 0))
(lambda ()
(set! next (+ next 1))
next)))
Мой вопрос просто, как я могу переписать эту функцию, чтобы я мог получить доступ к значению next
без увеличения счетчика? Я пытался играть с лямбдами, но я просто не могу понять это.
Изменить: некоторый контекст:
(define (dispatch m)
(let ((count 0))
(cond ((eq? m 'withdraw) withdraw) ; Increments count
((eq? m 'deposit) deposit) ; Increments count
((eq? m 'balance) balance-return)
((eq? m 'transaction) count) ; "count" on this line should return the value
(else (error "Unknown request -- MAKE-ACCOUNT"
m)))))
1 ответ
Не совсем понятно, как count
связан с примером банковского счета, однако что-то так просто, как
(define (make-account)
(let ((count 0)) ; Define `count` here...
(define (dispatch m) ; ...and define `dispatch` such that `count` is in scope
(cond ((eq? m 'next) ; On message 'next...
(lambda () (set! count (+ count 1)))) ; ...return the lambda, which has `count` in its scope
((eq? m 'count) ; On message 'count...
count) ; ...return the current count
(else ; Otherwise...
(error "Unknown request -- MAKE-ACCOUNT" m)))) ...raise error
dispatch)) ; Return `dispatch` from `make-account`
может быть то, что вы ищете.
Основными идеями являются:
- Создайте область, в которой ваша переменная может жить (здесь: область действия
make-account
процедура) - Создайте свою переменную в этой области (здесь:
(let ((count 0))
) - Просто получите доступ к нему в рамках (здесь: настройка или получение
count
) - Вернуть то, что имеет переменную в области видимости (здесь:
dispatch
закрытие).
Вы можете тогда (define acc-dispatch (make-account))
и впоследствии получить текущий счет, используя (acc-dispatch 'count)
, но вы все равно можете увеличить его, если хотите, используя ((acc-dispatch 'next))
,
Обратите внимание, что последний применяет лямбду, возвращаемую при вызове (acc-dispatch 'next)
,