[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Xavier Leroy <xleroy@p...> |
| Subject: | Re: CSL modules |
> 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