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
Some bugs in generative functor #6581
Comments
Comment author: @garrigue Fixed in 4.02 at revision 15336. Problem 1: Problem 2: Problem 3: Problem 4: |
Comment author: @sliquister By the way, there is the symmetric problem of problem 3: module F(X : sig end) = ... So essentially, the call site of a functor gives misleading information about the generativity of the functor (for those functors that are applied to struct end or ()). One small argument in favor of a better representation is that ppx rewriters dealing with this part of the language have to know about the struct end hack (which is not documented in parsetree.mli by the way). |
Comment author: @garrigue
Actually, this is not the case: any functor applied to "()" (or any immediate structure) will behave generatively, notwithstanding whether it was defined as generative or applicative. This is precisely the rationale behind this syntax.
Right. This should at least be documented. |
Comment author: @sliquister I don't think applying an applicative functor to (struct end) or () makes it generative when the appplication happens inside an other applicative functor. Example: module F(X : sig end) = struct If F was generative, G would have to be generative as well and A.t and B.t would be incompatible. |
Comment author: @garrigue OK, what you are saying is that if F is applicative, then we can still apply it to () inside an applicative functor, while this would be prohibited for a generative functor. Seen another way, the point is that there is only one kind of functors, and they are applicative. But we can, at definition time, restrict some of them to be generative, which means you can only use them in generative contexts. |
Original bug ID: 6581
Reporter: @garrigue
Assigned to: @garrigue
Status: closed (set by @xavierleroy on 2016-12-07T10:36:54Z)
Resolution: fixed
Priority: normal
Severity: minor
Version: 4.02.0
Target version: 4.02.1+dev
Fixed in version: 4.02.1+dev
Category: typing
Bug description
Reported by Mark Shinwell:
Problem 1 (see attached script): What is this Make(*)?
Problem 2 (see attached script): What is this Make(()), why do
we have generative functor application in type paths, and why does
building with -no-app-funct make this example work even though it
doesn't contain any applicative functor?
(Comment from Mark: as regards the error message at the end, I presume
it's two different instantiations of the functor. Maybe the error
messages should give some sort of numeric instantiation identifier, so
the user can see what's happening? I don't think we should ever give
an error that says "Type declarations do not match: FOO is not
included in FOO".)
Incremental.Make(()).t end
end
end
is not included in
sig
module Incremental :
sig
module Make :
functor () -> sig type 'a t = 'a
Incremental.Make(()).t end
end
end
At position
module type S_Incremental_lib =
sig module Std : sig module Incremental : end end
Modules do not match:
sig
module Make :
functor () -> sig type 'a t = 'a Incremental.Make(()).t end
end
is not included in
sig
module Make :
functor () -> sig type 'a t = 'a Incremental.Make(()).t end
end
At position
module type S_Incremental_lib =
sig
module Std :
sig module Incremental : sig module Make : end end
end
Modules do not match:
functor () -> sig type 'a t = 'a Incremental.Make(()).t end
is not included in
functor () -> sig type 'a t = 'a Incremental.Make(()).t end
At position
module type S_Incremental_lib =
sig
module Std :
sig module Incremental : sig module Make(()) :
end end
end
Modules do not match:
sig type 'a t = 'a Incremental.Make(()).t end
is not included in
sig type 'a t = 'a Incremental.Make(()).t end
At position
module type S_Incremental_lib =
sig
module Std :
sig module Incremental : sig module Make(()) :
end end
end
Type declarations do not match:
type 'a t = 'a Incremental.Make(()).t
is not included in
type 'a t = 'a Incremental.Make(()).t
Problem 3: why can I have apply "struct end" to a functor that takes "()"?
module M() = struct end;;
include M(struct let x = 1 end);; (* doesn't type, ok *)
Error: This is a generative functor. It can only be applied to ()
include M(struct end);; (* types, unlike what the error above says, why?? *)
(Follow-up: we worked out that it seems "()" is an alias for "struct
end", but it seems confusing nonetheless.)
Problem 4 (see attached script): the given library compiles, but
only if the ALIAS line below is not commented out or if -no-app-funct
is not given on the command line. When it fails, it fails with:
File "incremental_unit_tests.ml", line 4, characters 10-29:
Error: This expression creates fresh types.
It is not allowed inside applicative functors.
So it looks like this library shouldn't compile, even with the alias
and without -no-app-funct.
File attachments
The text was updated successfully, but these errors were encountered: