Reputation: 3530
What is the conventional way to create an interface in OCaml? It's possible to have an interface with a single implementation by creating an interface file foo.mli
and an implementation file foo.ml
, but how can you create multiple implementations for the same interface?
Upvotes: 7
Views: 1802
Reputation: 31469
You must use modules and signatures. A .ml
file implicitly define a module, and a .mli
its signature. With explicit modules and signature, you can apply a signature to several different modules.
See this chapter of the online book "Developing Applications with OCaml".
Upvotes: 10
Reputation: 107859
If you're going to have multiple implementations for the same signature, define your signature inside a compilation unit, rather than as a compilation unit, and (if needed) similarly for the modules. There's an example of that in the standard library: the OrderedType
signature, that describes modules with a type and a comparison function on that type:
module type OrderedType = sig
type t
val compare : t -> t -> int
end
This signature is defined in both set.mli
and map.mli
(you can refer to it as either Set.OrderedType
or Map.OrderedType
, or even write it out yourself: signatures are structural). There are several compilation units in the standard library that have this signature (String
, Nativeint
, etc.). You can also define your own module, and you don't need to do anything special when defining the module: as long as it has a type called t
and a value called compare
of type t -> t -> int
, the module has that signature. There's a slightly elaborate example of that in the standard library: the Set.Make
functor builds a module which has the signature OrderedType
, so you can build sets of sets that way.
(* All four modules passed as arguments to Set.Make have the signature Set.OrderedType *)
module IntSet = Set.Make(module type t = int val compare = Pervasives.compare end)
module StringSet = Set.Make(String)
module StringSetSet = Set.Make(StringSet)
module IntSetSet = Set.Make(IntSet)
Upvotes: 6