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

Open
vicuna opened this Issue Apr 13, 2003 · 2 comments

Comments

Projects
None yet
2 participants
@vicuna
Copy link
Collaborator

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
OS:
Submission from: 12-234-83-176.client.attbi.com (12.234.83.176)

Hi,
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
are
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?
struct
...
end

the only way I think we can do this now is to expand the signature S out with
the
type equalities coded in the expanded sig. If that's right, that is a
shortcoming
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) =
struct
...
end

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

@yallop

This comment has been minimized.

Copy link
Member

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) ->
@yallop

This comment has been minimized.

Copy link
Member

commented Apr 3, 2019

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

module MakeRec (Ord: OPEN_ORDERED) :
  (sig
    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.