> Now I want to design a module Q, with operations using type t. To refer to t > in > the signature of Q, I am obliged to declare a module Mt : MT inside the > signature > > module type QT = sig > module Mt : MT > val g : Mt.t -> .... > end
I don't believe this is the way to go. You could either: 1. not mention MT in this signature, only have an abstract type t, and enforce this sharing in the module implementation only module type MT = sig type t val f : t -> int end;; module type QT = sig type t val g : t -> int end;; module M : MT = struct type t = int let f x = 0 end;; module Q : (QT with type t = M.t) = struct type t = M.t let g x = M.f x end;; 2. Define QT as a signature component of a functor depending on a (M : MT); if you're going to define functors anyway, why not. module type MT = sig type t val f : t -> int end;; module QT_Fun (M : MT) = struct module type QT = sig val g : M.t -> int end end;; module Q_Fun (M : MT) : QT_Fun(M).QT = struct let g x = M.f x end;; Of course, if you only use QT once, you could even define the signature and the functor at the same time, or not give a name to the signature at all: module Q_SameTime (M : MT) = struct module type QT = sig val g : M.t -> int end module Q : QT = struct let g x = M.f x end end;; module Q_NoName (M : MT) : sig val g : M.t -> int end = struct let g x = M.f x end;; Or not give a name to the signature at all: > > Now the module M itself, before Q, because of sharing constraint in Q: > > module M : MT = struct > type t = int > let f x = .... > end > > And finally the module Q, which must contain a module Mt to respect its > signature: > > module Q : (QT with type Mt.t = M.t) = struct > module Mt = M > let g x = .... > end > > As generally my modules are functors I will probably rather write the module > QF: > > module QF (Mx:MT) : (QT with type Mt.t = Mx.t) = struct > module Mt = Mx > let g x = ... > end > > And finally instanciate QF: > > module Q2 = QF (M) > > The declaration of Mt in QT and QF is here only to reference the type t. It > seems natural that QF be parameterized by Mx:MT as it will certainly use > operations of M, but what seems artificial is the declaration of Mt in the > signature QT (and hence in the functor QF). Intuitively, I would say that the > signature QT refers to the type t declared in the signature MT, not in the > structure M. > Is there a simpler way to do this ? I suspect my solution is too complicate, > but I couldn't find better... On Mon, May 7, 2012 at 8:15 PM, <co...@irit.fr> wrote: > Hello, > While using the module system to abstract types, I often encounter the problem > to reuse in a signature an abstract type declared in another signature. Let's > take an example. > I have a module M, which declares an abstract type t, with operations using > this type. > > module type MT = sig > type t > val f : t -> .... > end > > Now I want to design a module Q, with operations using type t. To refer to t > in > the signature of Q, I am obliged to declare a module Mt : MT inside the > signature > > module type QT = sig > module Mt : MT > val g : Mt.t -> .... > end > > Now the module M itself, before Q, because of sharing constraint in Q: > > module M : MT = struct > type t = int > let f x = .... > end > > And finally the module Q, which must contain a module Mt to respect its > signature: > > module Q : (QT with type Mt.t = M.t) = struct > module Mt = M > let g x = .... > end > > As generally my modules are functors I will probably rather write the module > QF: > > module QF (Mx:MT) : (QT with type Mt.t = Mx.t) = struct > module Mt = Mx > let g x = ... > end > > And finally instanciate QF: > > module Q2 = QF (M) > > The declaration of Mt in QT and QF is here only to reference the type t. It > seems natural that QF be parameterized by Mx:MT as it will certainly use > operations of M, but what seems artificial is the declaration of Mt in the > signature QT (and hence in the functor QF). Intuitively, I would say that the > signature QT refers to the type t declared in the signature MT, not in the > structure M. > Is there a simpler way to do this ? I suspect my solution is too complicate, > but I couldn't find better... > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa-roc.inria.fr/wws/info/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > -- Caml-list mailing list. Subscription management and archives: https://sympa-roc.inria.fr/wws/info/caml-list Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs