(* [counter] is not an abstract type: it is a type abbreviation. It
   is defined both in the [.ml] file and in the [.mli] file, since
   it is meant to be publicly visible. *)

type counter =
  (unit -> int) * (unit -> unit)

let count init step : counter =
  (* Allocate the counter's internal state. Here, we need a heap block
     with just one mutable field, which holds the counter's current
     value. We use an OCaml "reference" for this purpose. We create
     a new reference, so that two calls to [count] produce two independent
     counters. *)
  let next = ref init in
  (* We now define two functions, [next] and [reset], which have access
     to the heap block [next]. They also have access to the integers
     [init] and [step]. In OCaml, a function has access to the variables
     that exist outside. *)
  let next() =
    let n = !next in
    next := n + step;
    n
  and reset() =
    next := init
  in
  (* There remains to build (and return) a pair of the functions [next]
     and [reset]. *)
  (next, reset)