Partial type synonyms -- first-class!
ÉRDI Gergő
gergo at erdi.hu
Fri Aug 5 10:17:33 UTC 2022
As I mentioned at the end of the original thread (but probably no one
was interested in this enough to read that far), after a breakthrough
idea I have now started working on partial type synonyms that are NOT
just defined using macro expansion semantics, and indeed can be a
first-class abstraction. I think if I can iron out the wrinkles
detailed at the bottom of this message, this would be good for a GHC
proposal.
1. Defining partial type synonyms
The idea is to typecheck the type synonym declaration
type Syn a = MyType _ [a] Int
into a type synonym that has some implicit (invisible) type parameters:
type Syn {w1} a = MyType w1 [a] Int
We don't need to come up with any new design for "what this means":
this means exactly the same as
type Syn w1 a = MyType w1 [a] Int
which is something you can already write today. The only difference is
how `w1` is given at use sites.
2. Using partial type synonyms
When a partial type synonym is applied, its argument list is expanded
by adding wildcard arguments for the invisible parameters. So this use
site:
Syn Double
is typececked into the type application
Syn {_} Double
Again, we don't need to come up with any new design for "what this
means": this is the same as writing `Syn _ Double` into the same
position, it's just the `_` is not written in the surface syntax.
In particular:
* The level of the type variable conjured for the `_` is determined
fully by where the `Syn Double` occurs, and not at all by the
definition of `Syn`
* Using the type synonym `Syn` is only valid where a wildcard
occurrence would be valid. In particular, using `Syn` in a type
signature causes the signature itself to be regarded as partial
(`isCompleteHsSig` returns `False` for it).
3. Implementation
I have a proof-of-concept implementation at
https://gitlab.haskell.org/cactus/ghc/-/compare/master...cactus%2Fpartial-tysyns?from_project_id=1117
I tried to make it as small a change as I could. Its key points are:
* In the renamer, we allow wildcards in `TySynCtx` context
* In `tcTySynRhs`, we allow wildcards in the right-hand side,
retrieve them from the result of typechecking, and intersperse
them with the "normal" type parameters to get a well-scoped
telescope.
* About a third of the lines changed is just a boring refactoring of
`isCompleteHsSig` to be able to look up type synonym
`TyCon`s. This is needed because a type signature referring to
partial type synonyms will be partial itself once those type
synonym applications are elaborated.
* When typechecking a type application, implicit arguments get
filled with the result of `tcAnonWildCardOcc`.
Now, my questions about the problems I've encountered along the way. I
hope these questions are concrete enough that I can get concrete
answers to them from this list:
1. How do I find the wildcard-originating tyvars robustly? Currently,
I am using `candidateQTyVarsWithBinders` but that picks up "regular"
out-of-scope tyvars as well. I believe this causes a regression of
#17567; furthermore, it means if the user writes `type Syn a = Foo b` it
is handled the same as if they wrote `type Syn a = Foo _`, but it would
be better to reject it instead.
2. What should the `Role` of these implicit type parameters be? For
now, I've went with `Nominal` for lack of a better answer.
3. When typechecking a type application, I need to insert wildcards
for these implicit arguments. I am currently using `AnonTCB InvisArg`
binders to represent these implicit type parameters, which means by
the time I get to `tcInferTyApps`, they would get passed through
`instantiate` to `tcInstInvisibleTyBinder`. I currently have a
horrible kuldge here to check, before calling
`tcInstInivisibleTyBinder`, that the invisible binder's kind doesn't
meet the preconditions of it; and if it doesn't, I create a wildcard
instead. But of course, it would be nicer if I could put something in
the `TcTyConBinder` that identifies these binders properly.
Thanks in advance,
Gergo
--
.--= ULLA! =-----------------.
\ http://gergo.erdi.hu \
`---= gergo at erdi.hu =-------'
More information about the ghc-devs
mailing list