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


Comments


:) :)) :( ;) :\ |) X-( B) Markup

Exercise3-1 (last edited 2009-03-24 06:23:53 by FirstnameLastname)