-
Notifications
You must be signed in to change notification settings - Fork 52
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
Scoped type variables #2178
Scoped type variables #2178
Conversation
…plicitly quantified Towards #2168.
Co-authored-by: Restyled.io <commits@restyled.io>
@xsebek I think it works now. I would appreciate any additional torture-testing you are able to do. |
Actually, I think this is not ready to merge --- I'm afraid I've made it too easy to make mistakes and this will just lead to problems down the road. Currently working on adding more type indexing so the Haskell type system will prevent us from using parsed polytypes that haven't been properly implicitly quanitified. I'd still appreciate any feedback / testing anyone would like to do in the meantime. |
@xsebek OK, I think this is ready to go now! |
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.
Works well and the documentation is neat. 👍
Type variables in polymorphic types now scope over any nested local type signatures by default. Closes #2168.
forall
or not, brings all its variables into scope in the body of its definition.forall
are introduced as new variables, and in particular they will shadow any type variables already in scope with the same names.forall
which are not already in scope will be implicitly quantified. Any such type variable names which are in scope will simply refer to the name in the enclosing scope.So, for example, this will work:
The type signature on
balance
will bringk
andv
into scope in its body (even though there is not an explicitforall
written); then thek
andv
in the type signatures onbaseCase
andbalanceRR
will both refer to thek
andv
bound in the type ofbalance
. In particular, this means thatinr t
is a valid definition forbaseCase
since their types match. On the other hand, if one were to writethen the
k
andv
in the type ofbaseCase
would be new type variables which are different than thek
andv
in the type ofbalance
(which would now be shadowed within the definition ofbaseCase
). This would now be a type error (which is what happens currently), sincebaseCase
is required to be anRBTree k v
for any typesk
andv
, butinr t
only has the specific type that was given as an input tobalance
.Finally, if one wrote
then only
k
would be a new type variable, whereasv
would refer to thev
from the type ofbalance
. (This would still be a type error, of course.)In addition, what used to be
Polytype
is now two separate types:RawPolytype
is what we get out of the parser, before implicit quantification has been carried out. APolytype
is guaranteed to be properly quantified, i.e. variables bound by the forall are explicitly listed. We carefully do not export the constructor so we can be sure that the typechecker is making sure that we never accidentally use aRawPolytype
before we implicitly quantify over it.