From: Xavier Leroy <Xavier.Leroy@inria.fr>
To: pbrisset@eis.enac.dgac.fr
Cc: caml-list@margaux.inria.fr
Subject: Re: One more question about the module system
Date: Thu, 28 Mar 1996 15:16:16 +0100 (MET) [thread overview]
Message-ID: <199603281416.PAA23161@pauillac.inria.fr> (raw)
In-Reply-To: <199603251721.SAA25211@concorde.inria.fr> from "pbrisset@eis.enac.dgac.fr" at Mar 25, 96 06:22:09 pm
> I have a program implemented in several files (say m.ml, m1.ml and m2.ml).
> This program depends on a module L and the dependency is expressed
> using the .mli/open mechanism. So I have:
>
> (* m.ml *)
> open L
> open M1
> ...
>
> (* m1.ml *)
> open L
> open M2
> ...
>
> (* m2.ml *)
> open L
> ...
>
> I want to transform this program in order to have a functor of argument L
> (i.e. I want to use twice my program with two different module L's). So
> I want to be able to write (in a main.ml):
>
> module ML1 = M(L1)
> module ML2 = M(L2)
> ...
>
> where M is the functor.
>
> I use the following idea: because my different (implicit) modules
> depend on L, I have to translate them into (explicit) functors. Then, I
> apply the functors for m1.ml and m2.ml in the main module defined in m.ml.
> The m1.ml module can no longer include an "open M2" since M2 is a functor:
> m1.ml have to speak about M2 through the instantiation of M2 done in M.
No, but M1.Make can take L as a parameter, apply M2.Make to it, bind
the result with a "module" binding, and "open" the result. E.g.
(* m1.ml *)
module Make(L: MTYPE_L) = struct
module M2L = M2.Make(L)
open L
open M2L
...
end
(* m.ml *)
module Make(L: MTYPE_L) = struct
module M1L = M1.Make(L)
open L
open M1L
...
end
However, it's often more flexible to avoid applying functors inside
functors. Instead, just pass extra parameters to your functors:
(* 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
next prev parent reply other threads:[~1996-03-28 18:02 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
1996-03-25 17:22 pbrisset
1996-03-28 14:16 ` Xavier Leroy [this message]
1996-03-29 14:10 pbrisset
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=199603281416.PAA23161@pauillac.inria.fr \
--to=xavier.leroy@inria.fr \
--cc=caml-list@margaux.inria.fr \
--cc=pbrisset@eis.enac.dgac.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox