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
Add some injectivity annotations to the standard library. #9781
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not yet very familiar with the concept of injectivity and did not follow #9500, but I tried reviewing this one as it seemed rather trivial. For my own understanding, do the following hold?
-
Is it the case that when we add an injectivity annotation to the interface of a module only, the compiler checks in the implementation that the type is actually injective?
-
If the above holds, then for those types which are defined by sums or records in the implementation an injectivity annotation is not needed in the implementation (or in any case, it is ignored)
-
For types which are defined as abstract in the implementation (eg
Genarray.t
), the annotation needs to be put in both interface and implementation sides. Is it right to say that an annotation in this case can never be "wrong", ie that such an abstract type can never be "not injective"?
@nojb: The only way to obtain a contradiction using injectivity is to intentionally build a wrong equality witness, using type (_,_) eq = Refl : ('a,'a) eq
type !'a t
let w0 : (bool, float) eq = Obj.magic Refl
let w : (bool t, float t) eq = Obj.magic Refl
let w' : (bool, float) eq = (fun (type a b) (Refl : (a t, b t) eq) -> (Refl : (a, b) eq)) w |
By the way, it would be in theory sound to have purely abstract types (i.e. abstract types defined in implementations) be always injective. However, this would change the inferred types. |
Thanks for the explanation @garrigue, that clears it up for me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. For those wondering, the injectivity of 'a Lazy.t
seems to be deduced automatically from that of the built-in type 'a lazy_t
and does not require an annotation.
Looks good to go. As this touches the stdlib, let's wait a bit in case someone wants to comment further. Otherwise I'll merge by end of day today or tomorrow morning at most. |
Merged, thanks! |
This is a follow-up to @garrigue's #9500, which added support for injectivity annotations to the language. This PR adds injectivity annotations to abstract types in the standard library.
Before this PR, user code could not make use of the fact that most¹ standard library abstract types are injective:
After this PR the code above passes typechecking:
¹
Ephemeron.K1.t
is an exception