* [Caml-list] reuse of abstract types
@ 2012-05-07 18:15 coste
2012-05-07 20:37 ` Gabriel Scherer
0 siblings, 1 reply; 3+ messages in thread
From: coste @ 2012-05-07 18:15 UTC (permalink / raw)
To: caml-list
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...
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Caml-list] reuse of abstract types
2012-05-07 18:15 [Caml-list] reuse of abstract types coste
@ 2012-05-07 20:37 ` Gabriel Scherer
2012-05-08 9:53 ` rossberg
0 siblings, 1 reply; 3+ messages in thread
From: Gabriel Scherer @ 2012-05-07 20:37 UTC (permalink / raw)
To: coste; +Cc: caml-list
> 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, <coste@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
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Caml-list] reuse of abstract types
2012-05-07 20:37 ` Gabriel Scherer
@ 2012-05-08 9:53 ` rossberg
0 siblings, 0 replies; 3+ messages in thread
From: rossberg @ 2012-05-08 9:53 UTC (permalink / raw)
To: Gabriel Scherer; +Cc: coste, caml-list
"Gabriel Scherer" <gabriel.scherer@gmail.com> wrote:
>> 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.
Actually, there is nothing wrong with coste's approach. In fact, that is the
way advocated by some in the ML modules community (see e.g. Part III on
modules in Bob Harper's SML book,
http://www.cs.cmu.edu/~rwh/smlbook/book.pdf). One advantage is that it makes
signatures more self-contained.
Others prefer the more "lightweight" approach of only putting in the types,
like you suggest. It works well, too, but can get more tedious when you are
dealing with modules exporting several types, or with several modules
exporting types of conflicting names.
/Andreas
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-05-08 9:53 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-07 18:15 [Caml-list] reuse of abstract types coste
2012-05-07 20:37 ` Gabriel Scherer
2012-05-08 9:53 ` rossberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox