Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: [Caml-list] Partially hiding modules in packages

10 views
Skip to first unread message

blue storm

unread,
Sep 9, 2009, 3:40:36 PM9/9/09
to Alexey Rodriguez, OCaml List
The problem with your packages.tgz example is that you use "module
type Foo = .." in the .mli. This gives the signature of a module type,
that is, it refers to a _module type_ defined in the implementation
file.

What you want to do here is to give the signature of a _module_, not a
module types, so here is the correct syntax :

module Foo : sig
type foo_t

val initial : foo_t
val show : foo_t -> string
end


Regarding your original problem, I've had the same needs and came up
with a slightly different solution : in order to avoid the additional
indirection level related to -pack (Foobar.Foo), is used a flattened
representation by adding a "foobar.ml" file containing only :

include Foo

(and possibly include of other modules in the package). Then the
foobarl.mli is :

type foo_t

val initial : foo_t
val show : foo_t -> string

And values can be referred with Foobar.foo, instead of Foobar.Foo.foo.
Of course this is only useful if you don't want the user to see the
internal module hierarchy, wich may not be what you had in mind.

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

Alain Frisch

unread,
Sep 9, 2009, 4:25:35 PM9/9/09
to Alexey Rodriguez, OCaml List
On 9/9/2009 9:00 PM, Alexey Rodriguez wrote:
> My question is about how to hide modules (or parts thereof) in
> an ocaml package from the outside world (users of the package).

It is not a well-known fact, but it is possible to provide an explicit
interface for the packaged module (just create an ad hoc foobar.mli and
compile it before doing the -pack'ing).

-- Alain

Jean-Christophe Filliâtre

unread,
Sep 10, 2009, 2:09:09 AM9/10/09
to Alexey Rodriguez, OCaml List
Hi,

Alexey Rodriguez a �crit :


> My question is about how to hide modules (or parts thereof) in
> an ocaml package from the outside world (users of the package).
>

> * Add the file foobar.mli which contains the signatures of Foo and Bar
> but hiding
> Foo.unsafe_change. I think it could work, but I would have to repeat
> much of the Foo
> and Bar interfaces. I tried this but it didn't work, ocaml complains
> as follows:

That's the solution we followed in Mlpost (http://mlpost.lri.fr/) and it
works fine (you may have a look at the Makefile.in in mlpost sources).

Indeed, you have to repeat (parts of) the modules interfaces, but since
it is where we put all the ocamldoc documentation, in a single file, it
appears to be a satisfying solution.

--
Jean-Christophe

Alexey Rodriguez

unread,
Sep 10, 2009, 8:29:34 AM9/10/09
to blue storm, OCaml List
Thanks to all who replied. I have solved my problem, but I still have
a question regarding clashing type definitions.

On Wed, Sep 9, 2009 at 9:40 PM, blue storm <bluesto...@gmail.com> wrote:
> The problem with your packages.tgz example is that you use "module
> type Foo = .." in the .mli. This gives the signature of a module type,
> that is, it refers to a _module type_ defined in the implementation
> file.
>
> What you want to do here is to give the signature of a _module_, not a
> module types, so here is the correct syntax :
>
> �module Foo : sig
> � �type foo_t
>
> � �val initial : foo_t
> � �val show : foo_t -> string
> �end

Well spotted! I already encountered this before and at the time I
understood it, but I guess my brain forgot about it yesterday. Thanks
for checking the files, now it works. Whether the modules are
flattened in Foobar or not, I think it is orthogonal to the issue of
hiding (we both use the same solution). In our case I prefer to keep
the hierarchy as the packages tend to have many big modules.

I also checked the source code of mlpost, thanks for the tip
Jean-Christophe. This is probably the most promising solution.

Now I am trying to see how much reuse of "signatures" can be achieved.
Currently I defined the FOO and BAR signatures in sigs.ml. I include
them in the local mli files, for example:

foo.mli:
> include Sigs.FOO with type foo_t = int
>
> val unsafe_modify : foo_t -> foo_t

bar.mli:
> include Sigs.BAR with type foo_t = Foo.foo_t

And now the package signature is:
> module Foo : Sigs.FOO
> module Bar : Sigs.BAR with type foo_t = Foo.foo_t

This works great: the representation of Foo.foo_t is hidden and the
unsafe function is not visible. This requires adding the type foo_t to
the signature of Bar:

> module type BAR = sig
> type bar_t
> type foo_t
> val initial : bar_t
> val combine : bar_t -> foo_t -> foo_t
> end

So there is no free lunch here, I can reuse the signatures to avoid
repetition but I have to introduce extra type aliases to relate
signatures at include time. This could add some complexity for modules
sharing many types, and now I cannot include both FOO and BAR in the
same module due to clashing definitions of foo_t.

The only way that comes to my mind to avoid such clashes is to invent
new type alias names even though they refer to the same type. Is there
a nice methodology to avoid clashing type definitions when I want to
include two module (interfaces) that share types?

Cheers,

Alexey

Guillaume Yziquel

unread,
Nov 28, 2009, 1:49:48 PM11/28/09
to blue storm, OCaml List
blue storm a écrit :

>
> Regarding your original problem, I've had the same needs and came up
> with a slightly different solution : in order to avoid the additional
> indirection level related to -pack (Foobar.Foo), is used a flattened
> representation by adding a "foobar.ml" file containing only :
>
> include Foo
>
> (and possibly include of other modules in the package). Then the
> foobarl.mli is :
>
> type foo_t
>
> val initial : foo_t
> val show : foo_t -> string
>
> And values can be referred with Foobar.foo, instead of Foobar.Foo.foo.
> Of course this is only useful if you don't want the user to see the
> internal module hierarchy, wich may not be what you had in mind.

Where do you put the foobar.ml? I've been trying it all over, I do not
see how you can flatten something that you pack.

Do you put foobar.ml at the same level of your directory foobar/, or in
you directory foobar/ ?

Or am I understanding you wrong?

All the best,

--
Guillaume Yziquel
http://yziquel.homelinux.org/

0 new messages