Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface with multiple implementations in OCaml

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?

like image 283
Matthew Piziak Avatar asked Mar 23 '12 17:03

Matthew Piziak


2 Answers

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".

like image 161
gasche Avatar answered Sep 29 '22 08:09

gasche


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)
like image 37
Gilles 'SO- stop being evil' Avatar answered Sep 29 '22 08:09

Gilles 'SO- stop being evil'