(* the OO-like interface we will meet two different ways *) type t = { add : int -> t; sum : unit -> int; length : unit -> int } (* way #1, "methods" use "private fields" i and l *) let rec add_f i l = let rec r = { add = (fun j -> add_f j r); sum = (fun () -> i + l.sum()); length = (fun () -> 1 + l.length()) } in r let mt_list1 = let rec r = { add = (fun j -> add_f j r); sum = (fun () -> 0); length = (fun () -> 0) } in r (* way #2, "methods" use "private fields" sum and len *) (* much faster length and sum, slightly slower add *) let rec make sum len = { add = (fun i -> make (i+sum) (1+len)); sum = (fun () -> sum); length = (fun () -> len) } let mt_list2 = make 0 0 let lst = [mt_list1; mt_list2; mt_list1.add(7); mt_list2.add(9)] type t2 = { (* impossible to implement correctly *) add : int -> t2; sum : unit -> int; sum_of_longer : t2 -> int (* sum of whichever is longer; self or arg *) }