module type S = sig type 'a mylist val mt_list : 'a mylist val cons : 'a -> 'a mylist -> 'a mylist val decons : 'a mylist ->(('a * 'a mylist) option) val length : 'a mylist -> int val map : ('a -> 'b) -> 'a mylist -> 'b mylist end type 'a mylist = Empty | Cons of 'a * ('a list) type intlist = Empty | Cons of int * intlist type t1 = A | B of int * t1 | C of t1 * t1 type t2 = A | B of int * t2 (* the interface *) type t = {cons : int -> t; decons : unit -> ((int * t) option); length : unit -> int } (*library #1, "methods" use "fields" i and l *) let rec cons_f i l = let rec r = {cons = (fun j -> cons_f j r); decons = (fun() -> Some (i,l)); length = (fun() -> 1 + l.length ())} in r let mt_list1 = let rec r = {cons = (fun j -> cons_f j r); decons = (fun() -> None); length = (fun() -> 0)} in r (*library #2, "methods" use "fields" l and len *) let rec make l = let len = List.length l in {cons = (fun j -> make (j::l)); decons = (fun() -> match l with [] -> None |hd::tl -> Some(hd,make tl)); length = (fun() -> len)} let mt_list2 = make [] let lst : t list = [mt_list1; mt_list2; mt_list1.cons(7); mt_list2.cons(9)] type t4 = {cons : int -> t4; decons : unit -> ((int * t4) option); length : unit -> int; append : t4 -> t4 } type t5 = {cons : int -> t5; average : unit -> int; append : t5 -> t5 } let callbacks : (int->unit) list ref = ref [] let onKeyEvent f = callbacks := f::(!callbacks) let keyPress i = List.iter (fun f -> f i) !callbacks