Opened 2 years ago
Last modified 4 months ago
#10141 new bug
CUSK mysteries
Reported by: | goldfire | Owned by: | goldfire |
---|---|---|---|
Priority: | normal | Milestone: | 8.4.1 |
Component: | Compiler | Version: | 7.10.1-rc2 |
Keywords: | TypeFamilies, TypeInType | Cc: | |
Operating System: | Unknown/Multiple | Architecture: | Unknown/Multiple |
Type of failure: | None/Unknown | Test Case: | indexed-types/should_fail/T10141 |
Blocked By: | Blocking: | ||
Related Tickets: | Differential Rev(s): | ||
Wiki Page: |
Description
Take the following definition:
type family G (a :: k) where G Int = Bool G Bool = Int G a = a
It compiles in 7.8.3, but not in 7.10.1 RC2. This makes me sad. I will fix.
(Found by Jan Stolarek.)
Change History (18)
comment:1 Changed 2 years ago by
comment:2 follow-up: 4 Changed 2 years ago by
Resolution: | → invalid |
---|---|
Status: | new → closed |
This is by design. As I discovered en route to the solution to #9200, the old kind inference for closed type families was bogus. For the type family above, what should the return kind be? k
, k2
, and *
are all viable options. Thus, this type family has no principal kind and should be rejected.
Another was of looking at this is that G
does not have a CUSK. Therefore, its right-hand side must use kind variables uniformly -- which it doesn't, because the first two equations must specialize k
to *
.
So, closing as invalid.
comment:3 Changed 2 years ago by
In this particular case, given the third equation G a = a
, I'm pretty sure the only possible return kind is k
, no? But there was that whole long discussion about CUSKs that I didn't really follow, so I take it that in general a closed type family may have no principal kind.
I would venture to say though that the error message GHC produces is IMHO not that helpful. In this case the fix is clearly to add a CUSK type family G (a :: k) :: k where
; could GHC work out when it is appropriate to suggest adding a CUSK?
comment:4 Changed 2 years ago by
Owner: | goldfire deleted |
---|---|
Resolution: | invalid |
Status: | closed → new |
Replying to goldfire:
So, closing as invalid.
I believe we should create a test case so that any accidental change of semantics does not go unnoticed (like it seems to have between 7.8.3 and 7.10.1?). Richard, I'm re-opening and assigning to you but if you don't have the time please re-assign it to me - I'll take care of that in due time.
comment:5 Changed 2 years ago by
Owner: | set to goldfire |
---|
comment:6 Changed 2 years ago by
Responding to comment:3:
No, the return kind could well be *
. I'll rewrite with explicit kinds:
type family G (a :: k) :: * where G * Int = Bool G * Bool = Int G * a = a
This G
doesn't really use its kind-polymorphism, but the definition kind checks.
However, I think you're right about the suggestion for a CUSK, here and in other cases. And I think it's possible for GHC to have at least some heuristics for when a CUSK is the answer. Specifically, it could include a note about CUSKs in error messages that arise from kind mismatches in non-CUSK right-hand sides.
And, yes, this would make for a decent test case. Thanks for the suggestion.
I'm very unsure I can get to this by Friday (the next RC release), though!
comment:7 Changed 2 years ago by
Priority: | highest → normal |
---|
comment:9 Changed 2 years ago by
I've added a (not-yet-pushed) test case, but it's hard to see how to improve error messages. The problem is that the place that generates the kind errors is far from where we know whether or not we have a CUSK. I attempted to use addErrCtxt
to include a note about CUSKs before kind-checking, but this note got appended to lots of errors that are clearly unrelated to CUSKs -- this is the wrong approach. I think the right approach is to somehow record in TcM
that we're kind-checking a declaration which could potentially have a CUSK but in fact does not and then look there before reporting certain errors. But this is terribly heavy.
Perhaps after my branch is merged, a way forward will present itself.
comment:11 Changed 2 years ago by
Test Case: | → indexed-types/should_fail/T10141 |
---|
comment:13 Changed 18 months ago by
Keywords: | TypeFamilies added |
---|
comment:14 Changed 17 months ago by
Milestone: | 8.0.1 → 8.2.1 |
---|
This bug won't be fixed in 8.0.1; bumping to 8.2.
comment:15 Changed 6 months ago by
Summary: | Kind inference regression in closed type families → CUSK mysteries |
---|
Here's an example that I was baffled by. This works
type family F (a :: k) type instance F Maybe = Char
But this does not.
type family F (a :: k) where -- = r | r -> a where F Maybe = Char
The latter is rejected with
Foo.hs:6:5: error: * Expecting one more argument to `Maybe' Expected kind `k', but `Maybe' has kind `* -> *' * In the first argument of `F', namely `Maybe' In the type family declaration for `F'
It is bizarre that one works and the other does not, and I was all ready to open a ticket when Richard said: This is correct behavior. The former has a CUSK, as all open type families have CUSKs with un-annotated kinds defaulting to Type. The latter does not have a CUSK, because the result kind is unknown. You therefore cannot specialize the k variable in the definition of the latter.
I can't help feeling that our CUSK story is a bit wonky, so I'm recording it here.
comment:16 Changed 6 months ago by
Keywords: | TypeInType added |
---|
comment:17 Changed 6 months ago by
If you want TypeInType
to mean "Richard's bailiwick", that's perhaps convenient. But I'll note that this problem has nothing to do with -XTypeInType
and exists in 7.10 and perhaps 7.8.
comment:18 Changed 4 months ago by
Milestone: | 8.2.1 → 8.4.1 |
---|
Given that 8.2.1-rc1 is imminent, I'm bumping these off to the 8.4
This looks bad. Release blocker? I assume so. Say if not.