Re: One more question about the module system

pbrisset@eis.enac.dgac.fr
Fri, 29 Mar 1996 15:10:46 +0100

From: pbrisset@eis.enac.dgac.fr
Message-Id: <199603291410.PAA02850@concorde.inria.fr>
Date: Fri, 29 Mar 1996 15:10:46 +0100
To: caml-list@margaux.inria.fr
Subject: Re: One more question about the module system

...
> (* m1.ml *)
> module Make(L: MTYPE_L)(Some_M2: MTYPE_M2) = struct
> open L
> open Some_M2
> ...
> end
> (* m.ml *)
> module Make(L: MTYPE_L)(Some_M1: MTYPE_M1) = struct
> open L
> open Some_M1
> ...
> end
>
> (You will probably need to express sharing constraints between type
> components of the parameters. Express them with "with type" or
> "with module", e.g.
> module Make(L: MTYPE_L)(Some_M2: MTYPE_M2 with type t = L.t) ...
> )
>
> Then do all the functor applications in a "main" file:
>
> module L = L1 (* or L2 *)
> module M2 = M2.Make(L)
> module M1 = M1.Make(L)(M2)
> module M = M.Make(L)(M1)
>
> The advantage of this approach is that you can also provide
> "hand-made" M1 or M2 modules (not produced by application of M1.Make
> or M2.Make), so you get more flexibility. The disadvantage is
> increased verbosity and number of declarations needed.
>
> - Xavier Leroy

I eventually found the same solution. Because I wanted a single "big"
module, I wrote:

(* m.ml *)
module Make(L: SIG_L) = struct
module M2 = M2.Make(L)
open M2
module M1 = M1.Make(L, M2)
open M1
...

I also checked that runtime efficiency is not modified by all these
functorizations.

--Pascal