Closed norm2782 closed 9 years ago
Unfortunately, this bug resurfaces with GHC 7.10. This is because GHC 7.10 is more scrupulous about including kind signatures when reifying type families -- sometimes omitting the kind signature can yield the wrong behavior. This is surely an improvement in GHC. However, it causes a conundrum for th-desugar. With kind signatures in type family patterns, th-desugar would have to do kind matching when figuring out how to simplify closed type families. This would include type inference, something we're surely not doing. So, I don't see how to fix this, I'm afraid.
Perhaps the best solution is to expose some ability to pass a TH expression through GHC's solver. But that will have to wait for GHC 7.12. Your best bet, if you're caught by this, is to fire up GHCi, and use its :kind!
command, like so:
λ> import Data.Metrology.SI
λ> :kind! Volume
Volume :: *
= Qu
'['F Data.Metrology.SI.Dims.Length ('S Two)] 'DefaultLCSU Double
:kind!
evaluates out a type family as far as it can go. Then, just copy and paste the output into your instance declaration. This is far from optimal, but also far from dead-in-the-water.
I just had a dirty thought. Because Q
wraps IO
, TH code can actually fire up GHCi and do this query itself.
I just had another, rather less dirty thought. It would seem (without looking at the code) that th-desugar could export a expandTypeNoKinds
function that just skips kind-checking. This would be unsafe, in that it might sometimes do the wrong thing. But for units
, it would solve this problem, as units
doesn't use kind-polymorphism in a way that would be dangerous here.
This seems quite workable.
Since 806a27d (issue #22), the
evalType
TH function is available to evaluate types as far as possible. This works well for, e.g.,Mass
andLength
. However, the following instance fails:Giving the following error:
In fact, all types defined using the
:/
combinator (and possibly others, such as:^
) fail with the same error. While these types are indeed more complex thanMass
andLength
, they at first glance don't appear to be very polymorphic, suggesting that it may be possible to useevalType
with types such asVolume
as well.