module type ComparisonSignature = sig
  type t;;
  val equality : t -> t -> bool;;
end;;

module type SetSignature = sig
  type t;;
  type set;;
  val add : t -> set -> set;;
  val belongs : t -> set -> bool;;
  val empty : set;;
end;;

module MakeSet (Comparison : ComparisonSignature) : SetSignature = struct
  type t = Comparison.t;;
  type set = Comparison.t list;;
  let empty = [];;
  let rec belongs x set =
    match set with
      | [] -> false
      | first :: rest ->
        if Comparison.equality first x then
          true
        else
          belongs x rest;;
  let rec add x set =
    match set with
      | [] -> [x]
      | first :: rest ->
        if Comparison.equality first x then
          set
        else
          first :: (add x rest);;
end;;

module IntComparison : ComparisonSignature = struct
  type t = int;;
  let equality x y =
    x == y;;
end;;

module Set = MakeSet (IntComparison);;
