module type SetSig = sig type elt type t val empty : t val add : t -> elt -> t val union : t -> t -> t val remove : t -> elt -> t val mem : t -> elt -> bool end module type EltSig = sig type t val compare: t -> t -> int end module MakeSet (Elt: EltSig) : (SetSig with type elt = Elt.t) = struct type elt = Elt.t type t = elt list let empty = [] let add t elt = elt::t let union = (@) let rec remove t elt = match t with [] -> [] | hd :: tl -> let tl' = remove tl elt in if Elt.compare hd elt = 0 then tl' else hd :: tl' let rec mem t elt = match t with [] -> false | hd :: tl -> (Elt.compare hd elt = 0) || (mem tl elt) end module IntElt = struct type t = int let compare i1 i2 = if i1 > i2 then 1 else if i1 = i2 then 0 else -1 end module IntSet = MakeSet(IntElt) open IntSet let set = add (add empty 1) 2 let foo = if mem set 1 then "OK" else "Bug"