Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: CSL modules
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ 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