Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature wish: enhanced module constraints #8100

vicuna opened this Issue Apr 13, 2003 · 2 comments


None yet
2 participants
Copy link

commented Apr 13, 2003

Original bug ID: 1634
Reporter: administrator
Status: acknowledged
Resolution: open
Priority: normal
Severity: feature
Category: typing

Bug description

Full_Name: Brian Rogoff
Version: OCaml
Submission from: (

In the latest round of thrashing over the parameterization trick hack for
encoding mutually recursive type and functor instantiations, an old annoyance
reared it's head again so I decided I'd see if you want to fix it.

The problem is that when we have a signature which exports two types (say,
Set.S, which exports t and elt) and we'd like to enforce that these two types
related like in the following, where Ord.t is obviously a polymorphic type

(* Not legal!!! *)

module MakeRec(Ord: OPEN_ORDERED) : (S with type elt = t Ord.t) =
^-- how to refer to S.t?

the only way I think we can do this now is to expand the signature S out with
type equalities coded in the expanded sig. If that's right, that is a
of the module system, and very un-Caml-like in it's verbosity, as I now have to
repeat the whole signature just to get the type equality I want. I understand
that neither "t" (which t does that refer to) nor "S.t" will work there, but
isn't this just syntax? Can't something like the following, also not legal
OCaml, be made to work?

module MakeRec(Ord: OPEN_ORDERED) : (S with type t and type elt = t Ord.t) =

where we first mention the t so that we know we're talking about the t in the
struct being defined, and then refer to it.

I trust that fixing this is easier than fixing the recursive module problem :-)

-- Brian


This comment has been minimized.

Copy link

commented Apr 3, 2019

It's possible to work around this limitation, at least in simple cases, by using a recursive module binding to bring the type name into scope:

module rec MakeRec : functor (Ord: OPEN_ORDERED) -> (S with type elt = MakeRec(Ord).t Ord.t) =
                     functor (Ord: OPEN_ORDERED) ->

This comment has been minimized.

Copy link

commented Apr 3, 2019

Here's a slightly less unpleasant approach using destructive substitution rather than recursive modules:

module MakeRec (Ord: OPEN_ORDERED) :
    type t
    include S with type t := t
              with type elt = t Ord.t
   end) = ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.