interfaceocamlsignaturefunctor

What is the right way to put type declarations in OCaml signatures


I have written the following two files, and although it works, it feels odd that the code would duplicate these long type declarations. On the other hand, if I remove either module type declaration then the code no longer compiles.

Is there a more proper way to write this kind of thing? Or is it correct to duplicate these type declarations in the .mli and .ml files?

set.mli

module type Element = sig
  type t
  val create : 'a -> t
  val compare : t -> t -> int
  val to_string : t -> string
end

module type Set = sig
  type t
  val empty : unit -> t
end

module Make : functor (M : Element) -> Set with type t = M.t list

set.ml

module type Element = sig
  type t
  val create : 'a -> t
  val compare : t -> t -> int
  val to_string : t -> string
end

module type Set = sig
  type t
  val empty : unit -> t
end

module Make (M:Element) = struct
  type t = M.t list
  let emtpy () = []
end

Solution

  • A good reference for this would be to review how the standard library is implemented. It's doubtful you're going to find a "better" way to do things than they do.

    I you consider set.mli and set.ml you'll see that they are specified very similarly to your code.

    What is curious in your code is why empty is implemented as a function, rather than simply a value. Note that you have a typo with emtpy in your second to last line.