caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [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;
as well as URLs for NNTP newsgroup(s).