From: Xavier Leroy <xleroy@pauillac.inria.fr>
Message-Id: <199603041405.PAA26261@pauillac.inria.fr>
Subject: Re: CSL modules
To: Guy.Cousineau@ens.fr
Date: Mon, 4 Mar 1996 15:05:49 +0100 (MET)
In-Reply-To: <9603011524.AA08384@aubepine.ens.fr> from "Guy.Cousineau@ens.fr" at Mar 1, 96 04:24:32 pm
> I would like to build a fonctor F such that C=F(A,B) "reexports"
> the types and variables of A and B but with tb now being an abstract type.
> and ta remaining a concrete type .
> Moreover, I want C.xa to be a value of type C.ta and not a value of
> type A.ta which would be easy. The reason for that is that I do not
> want the users of my programs to see modules A and B but only module
> C.
This is easily done using a signature constraint to specify exactly
how much of C should remain visible:
module type SIGA =
sig
type ta = A | B of int
val xa : ta
end
module type SIGB =
sig
type tb = C | D of string
val xb : tb
end
module type SIGC =
sig
type ta = A | B of int (* concrete *)
type tb (* abstract *)
val xa : ta
val xb : tb
end
module F(A: SIGA)(B: SIGB) =
(struct
type ta = A.ta = A | B of int
type tb = B.tb
let xa = A.xa
let xb = B.xb
end : SIGC)
module C = F(A)(B)
Notice the type definition "type ta = A.ta = A | B of int", which
keeps C.ta compatible with A.ta while re-exporting the constructors A
and B, which are now part of C. An alternate definition would be:
module type SIGC =
sig
type ta = A.ta (* concrete *)
type tb (* abstract *)
val xa : ta
val xb : tb
end
module F(A: SIGA)(B: SIGB) =
(struct
type ta = A.ta
type tb = B.tb
let xa = A.xa
let xb = B.xb
end : SIGC)
module C = F(A)(B)
It is also correct, but not as good because A is not completely
hidden: the constructors of C.ta still come from A, not C.
- Xavier Leroy