Exercise2-97 <---> Exercise3-2
Exercise 3.1
An accumulator is a procedure that is called repeatedly with a single numeric argument and accumulates its arguments into a sum. Each time it is called, it returns the currently accumulated sum. Write a procedure make-accumulator that generates accumulators, each maintaining an independent sum. The input to make-accumulator should specify the initial value of the sum; for example
(define A (make-accumulator 5))
(A 10)
15
(A 10)
25
Ru: Накопитель (accumulator) — это процедура, которая вызывается с одним численным аргументом и собирает свои аргументы в сумму. При каждом вызове накопитель возвращает сумму, которую успел накопить. Напишите процедуру make-accumulator, порождающую накопители, каждый из которых поддерживает свою отдельную сумму. Входной параметр make-accumulator должен указывать начальное значение суммы; например,
(define A (make-accumulator 5))
(A 10)
15
(A 10)
25
Scheme solution:
(define (make-accumulator sum)
(lambda (amount)
(set! sum (+ sum amount))
sum))
OCaml solution:
OCaml does not support assignment to variables. We use a data structure with one mutable field, called "ref" to store our state. We use the "ref" function to construct one, use the ! operator to de-reference it, and the := operator to assign a new value.
let make_int_accumulator init =
let sum = ref init in
fun amount -> sum := !sum + amount;
!sum
Standard ML solution:
Standard ML does not support assignment to variables. It however offers a special mutable data structure, called a "ref", that allows us to store our state. We use the "ref" function to construct one, use the ! operator to de-reference it, and the := operator to assign a new value.
fun make_int_accumulator init = let
val sum = ref init
in
fn amount => (sum := !sum + amount;
!sum)
end
Haskell solution:
Like OCaml, we use a "ref" data structure to store the mutable value. There are different ones, like IORef, STRef, etc. depending on which monad you want to wrap the state in. Here we use the IO monad so it is easy to use from the interactive prompt:
import Data.IORef
make_int_accumulator init =
do sum <- newIORef init
return (\amount -> do modifyIORef sum (+ amount)
readIORef sum)
Example:
Prelude Data.IORef> a <- make_init_accumulator 5 Prelude Data.IORef> a 10 15 Prelude Data.IORef> a 10 25
Exercise2-97 <---> Exercise3-2