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

[Caml-list] Module type of a structure returned by functor

11 views
Skip to first unread message

Dawid Toton

unread,
Apr 23, 2010, 7:14:59 PM4/23/10
to caml-list
1. The following piece of code contains illegal constructs. These are
functor applications marked with (* ? *).
Basically, I need module type of what is produced by functor.
My first question is: what is the proper, "canonical" workaround
for unavailability of applications marked (* ? *) ?

module type Big = sig type t type u end
module type Small = sig type t end

module type MakeEdge = functor (Big : Big) -> sig val foo : Big.t option end
module MakeEdge = functor (Big : Big) -> struct let foo = None end

module type Add_boilerplate = functor (Small:Small) -> sig type t end
module Add_boilerplate = functor (Small:Small) -> struct type t =
Small.t type u = t end

module type ConvenientEdge = functor (Small:Small) -> MakeEdge
(Add_boilerplate (Small)) (* ? *)
module ConvenientEdge = functor (Small:Small) -> MakeEdge
(Add_boilerplate (Small))

module SmallX = struct type t = int end
module EdgeX = ConvenientEdge (SmallX)
module type EdgeX = ConvenientEdge (SmallX) (* ? *)

module Algorithm = functor (EdgeX : EdgeX) -> struct let doit =
EdgeX.foo end


2. And the related question: why one can't do functor applications in
module types as in above lines marked with (* ? *) ? Is there some
theoretical reason?

3. Will the "module type of..." feature of 3.12 help with this? I can
imagine e.g.:

module type EdgeX = (module type of (ConvenientEdge (SmallX)))


Dawid

_______________________________________________
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

Dawid Toton

unread,
Apr 26, 2010, 12:33:35 PM4/26/10
to caml-list
I've found that I have more fundamental problem. What is the exact
meaning of the following line?

module type Foo = functor (X:X) -> sig val foo : X.t end

(1) Foo is not a functor, but it is a type of some functors that map
modules to modules
(2) Foo is a mapping from modules to module types

Currently I think that it (1) is true and (2) is false. Let me know if
I'm wrong.

It means that there is no easy way to get module type of what results
from functor application. I think that the solution is to separately
define signature of results of the functor and use "with type" clauses
to recreate all result module types that are needed.

This is not very bad, but I'm still wondering if "module type of..." of
3.12 will provide elegant solution for this.

Vincent Aravantinos

unread,
Apr 26, 2010, 12:48:13 PM4/26/10
to Dawid Toton, caml-list
Hi,

Le 26 avr. 10 à 18:33, Dawid Toton a écrit :

> I've found that I have more fundamental problem. What is the exact
> meaning of the following line?
>
> module type Foo = functor (X:X) -> sig val foo : X.t end
>
> (1) Foo is not a functor, but it is a type of some functors that map
> modules to modules
> (2) Foo is a mapping from modules to module types
>
> Currently I think that it (1) is true and (2) is false. Let me know
> if I'm wrong.

You're right.

> It means that there is no easy way to get module type of what
> results from functor application. I think that the solution is to
> separately define signature of results of the functor and use "with
> type" clauses to recreate all result module types that are needed.

That's exactly the way to go (BTW is it such a pain? maybe your "with
type" is easily inferred but not easily written?)

> This is not very bad, but I'm still wondering if "module type of..."
> of 3.12 will provide elegant solution for this.

I can't remember this point...

V.

ross...@mpi-sws.org

unread,
Apr 26, 2010, 12:54:55 PM4/26/10
to Dawid Toton, caml-list
Dawid Toton <d...@wp.pl> wrote:
> I've found that I have more fundamental problem. What is the exact
> meaning of the following line?
>
> module type Foo = functor (X:X) -> sig val foo : X.t end
>
> (1) Foo is not a functor, but it is a type of some functors that map
> modules to modules
> (2) Foo is a mapping from modules to module types
>
> Currently I think that it (1) is true and (2) is false. Let me know if
> I'm wrong.

That's right. A construct for (2), sometimes referred to as "parameterized
signatures", does not exist in OCaml directly. However, you can encode it
using a functor with a nested signature in its result:

module FooOf (X : X) =
struct
module type S = sig val foo : X.t end
end

Now, for example:

module F (X : X) (Y : FooOf(X).S) = ...

> It means that there is no easy way to get module type of what results
> from functor application. I think that the solution is to separately
> define signature of results of the functor and use "with type" clauses
> to recreate all result module types that are needed.
>
> This is not very bad, but I'm still wondering if "module type of..." of
> 3.12 will provide elegant solution for this.

Interesting, it looks like it may. I wasn't aware that singleton
signatures will be coming in 3.12 - nice.

/Andreas

Jacques Garrigue

unread,
Apr 26, 2010, 8:23:33 PM4/26/10
to d...@wp.pl, caml...@yquem.inria.fr
From: Dawid Toton <d...@wp.pl>

You are mixing two things: the signature of a functor (which cannot be
applied to anything, since it is a signature, not a functor), and a
functor returning a signature.
Using ocaml 3.11, you have to wrap the returned signature inside a
structure:

(* Signature wrapped inside a structure *)
module MakeEdgeSig (Big : Big) = struct
module type S = sig val foo : Big.t option end
end
module MakeEdge (Big : Big) = struct let foo = None end

module Add_boilerplate (Small:Small) =


struct type t = Small.t type u = t end

module ConvenientEdgeSig (Small:Small) = MakeEdgeSig (Add_boilerplate (Small))
module ConvenientEdge (Small:Small) = MakeEdge (Add_boilerplate (Small))

module SmallX = struct type t = int end
module EdgeX = ConvenientEdge (SmallX)

(* Build the corresponding signature *)
module type EdgeX = ConvenientEdgeSig(SmallX).S

module Algorithm (EdgeX : EdgeX) = struct let doit = EdgeX.foo end

> 3. Will the "module type of..." feature of 3.12 help with this? I can
> imagine e.g.:
>
> module type EdgeX = (module type of (ConvenientEdge (SmallX)))

Indeed, if your only goal is to obtain this specific signature, this
does the trick. But if you want to specify signatures independently of
implementations, you can also use the new destructive substitution
mechanism.

(* Requires ocaml 3.12 *)
(* New signature Edge, parameterized with t *)
module type Edge = sig type t val foo : t option end

(* Edge with type t := Big.t == sig val foo : Big.t option end *)
module MakeEdge (Big : Big) : Edge with type t := Big.t =


struct let foo = None end

module Add_boilerplate (Small:Small) =


struct type t = Small.t type u = t end

module ConvenientEdge (Small:Small) : Edge with type t := Small.t =
MakeEdge(Add_boilerplate (Small))

module SmallX = struct type t = int end
module EdgeX = ConvenientEdge (SmallX)

(* Build the result signature by instantiating Edge signature *)
module type EdgeX = Edge with type t := SmallX.t
(* Alternative approach, obtain the same signature from EdgeX itself *)
module type EdgeX' = module type of EdgeX

module Algorithm(EdgeX : EdgeX) = struct let doit = EdgeX.foo end


Hope this helps,

Jacques Garrigue

0 new messages