(* Baseline: polymorphic stack via functor over an Element module *)
module type ELEMENT = sig type t val show : t -> string end ;;

module IntElem = struct
  type t = int
  let show x = Int.to_string x
end ;;

module Make (E : ELEMENT) = struct
  let create () = ref []
  let push x s = s := x :: !s
  let pop s =
    match !s with
    | [] -> None
    | h :: t -> s := t ; Some h
  let length s = List.length !s
  let to_string s =
    String.concat "," (List.map E.show !s)
end ;;

module IntStack = Make(IntElem) ;;

let s = IntStack.create () ;;
IntStack.push 1 s ;;
IntStack.push 2 s ;;
IntStack.push 3 s ;;
String.length (IntStack.to_string s)
