-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
<package-type-constraint> does not allow constraints for non-nullary abstract types #5078
Comments
Comment author: @alainfrisch Yes, there is a technical reason, related to type inference and unification. Currently, two package types (S with t1=T1 and ... and tn=Tn) and (S' with t1'=T1' and ... tm=T'm) are equal if and only if S and S' are the same path, n = m, ti=ti' (modulo permutation) and Ti=T'i for all i. This gives a simple unification procedure for package types. Allowing parametrized types in constraints within package types should be possible by using a more complex definition of equality and unification, but this is not completely straightforward. |
Comment author: nlinger Here is a proposed generalization to packaged module type unification. unify (module A with (as1)t1 = T1 ... (asn)tn = Tn) This seems sound. The only tricky part is the check that c has not |
Comment author: @alainfrisch For the implementation, I believe one should be able to reuse some machinery introduced for polymorphic methods. An equality like: (module S with type ('a, 'b) t = T) == (module S with type ('a, 'b) t = S) should behave as the equality: < m : 'a 'b. T > = < m : 'a 'b. S > This might give some guidance on how to extend all the type-based operations. |
Comment author: @alainfrisch The branch fstclassmod_parametrized in the OCaml SVN repository allows more kinds of constraints (in particular, constraints on parametrized types). Feel free to try it! |
Comment author: kaustuv Awesome! Thanks. I have been playing with it for a few hours and it appears to be expressive enough for at least the use case this bug report was originally triggered by (phantom type parameters). The next obstacle I face is for something like this:
I understand why the expression "f m" above is rejected. I would have preferred if constrained module types induced a subtyping relationship so that I might have written, for example, "f (m :> (module T))". It forces me to duplicate some code -- precisely, the code for f. However, unlike the ability to constrain non-nullary types, which was a show stopper, this duplication is only half a dozen lines in my actual code. It is probably not worth complicating the implementation of first class modules to handle this kind of subtyping. I'm not filing a separate feature request. |
Comment author: @alainfrisch You can simulate subtyping by unpacking and repacking: let g m = Jacques Garrigue is working on another branch (implicit-unpack) which improves a lot the support for first-class modules. Explicit package types become optional in (val expr) and (module M) forms, whenever the package type can be inferred. Also, explicit subtyping allows to forget with-constraints in package types. These extensions might not play so well with with-constraints extended on parametrized types. So if you have a good case for this extension, this is the time to describe it! |
Comment author: nlinger The primary reason I have for wanting with-constraints on parameterized types is a straightforward encoding of universal and existential quantifiers like so module type Exists = sig module type Forall = sig With-constraints over the t component of these signatures allows one to express
In both cases, one avoids the need to introduce an auxiliary module type with |
Comment author: @alainfrisch I mark this issue as suspended for now. This means that while we consider this as an interesting feature request, no core developer is currently interested in working on it. If someone can submit a short and well-tested patch, we will happily consider it for inclusion, though. |
Comment author: @gasche I occasionally run into this limitation as well (one fairly common example would be parametrizing functions over a first-class module describing a monad). Has there been any change to the status of this discussion since january 2012? What is the "upstreamability status" of the branch fstclassmod_parametrized? |
Comment author: @alainfrisch
The type-checking of first-class module has changed a lot since then (to support type inference), so it won't be possible to integrate the branch in its current state. I've no idea if type-inference interacts well with this feature or not. Hopefully, Jacques will be able to give a more useful answer! |
Original bug ID: 5078
Reporter: kaustuv
Assigned to: @alainfrisch
Status: resolved (set by @alainfrisch on 2012-01-18T09:42:42Z)
Resolution: suspended
Priority: normal
Severity: feature
Version: 3.12.0+beta1 or 3.12.0+rc1
Category: ~DO NOT USE (was: OCaml general)
Has duplicate: #5140
Monitored by: nlinger
Bug description
The following is rejected because package type constraints as specified in the grammar (sec. 7.14 of the manual) cannot constrain a non-nullary type.
% ocaml
Objective Caml version 3.13.0+dev0 (2010-06-07)
module type S = sig type 'a t end ;;
module type S = sig type 'a t end
let f (m : (module S with type 'a t = 'a * int)) = m ;;
Syntax error: ')' expected, the highlighted '(' might be unmatched
Is there a technical reason to limit oneself to
type =
instead of
type [] =
for ?
The text was updated successfully, but these errors were encountered: