Аккумулятор, как правило, просто функциональный параметр.В разделе «Как разработать программы» ( онлайн, здесь и далее ) есть несколько глав, посвященных аккумуляторам.Вы их прочитали?
Например, функция reverse
реализована с использованием аккумулятора, который запоминает префикс списка, обратный:
;; reverse : list -> list
(define (reverse elems0)
;; reverse/accum : list list -> list
(define (reverse/accum elems reversed-prefix)
(cond [(null? elems)
reversed-prefix]
[else
(reverse/accum (cdr elems)
(cons (car elems) reversed-prefix))]))
(reverse/accum elems null))
Обратите внимание, что область действия аккумулятораreversed-prefix
ограничено функцией.Он обновляется путем вызова функции с новым значением для этого параметра.Разные вызовы reverse
имеют разные аккумуляторы, и reverse
ничего не помнит от одного вызова к следующему.
Возможно, вы имеете в виду переменную состояния .В этом случае вы define
(или связываете его с let
или lambda
) в соответствующей области действия и обновляете с помощью set!
.Вот глобальная переменная состояния:
;; total : number
(define total 0)
;; add-to-total! : number -> number
(define (add-to-total! n)
(set! total (+ total n))
total)
(add-to-total! 5) ;; => 5
(add-to-total! 31) ;; => 36
Вот вариант, который создает локальные переменные состояния, поэтому вы можете иметь несколько счетчиков:
;; make-counter : -> number -> number
(define (make-counter)
(let ([total 0])
(lambda (n)
(set! total (+ total n))
total)))
(define counterA (make-counter))
(define counterB (make-counter))
(counterA 5) ;; => 5
(counterB 10) ;; => 10
(counterA 15) ;; => 20
(counterB 20) ;; => 30
Но не вызывайте аккумуляторы переменных состояния;это смущает людей.