[GHC] #10343: Make Typeable track kind information better
GHC
ghc-devs at haskell.org
Sun Jan 24 20:55:27 UTC 2016
#10343: Make Typeable track kind information better
-------------------------------------+-------------------------------------
Reporter: oerjan | Owner: goldfire
Type: feature request | Status: new
Priority: normal | Milestone: 8.0.1
Component: Compiler | Version: 7.10.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case: typeOf ::
| Typeable (a::k) => Proxy a ->
| TypeRep
Blocked By: | Blocking:
Related Tickets: #9858 | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by bgamari):
I've been playing around with various ways that we could achieve this. As
far as I can tell there are two options,
* Encode type constructor kinds into `TyCon` and reconstruct applications
from these at runtime. This would require that `TyCon` get a bit larger,
and would need to include a `TypeRep`, which is unfortunate as this cost
is paid by all users, regardless of whether they use `Typeable`.
* Construct the kind representation at when we are asked to construct a
`Typeable` dictionary.
At the moment I'm leaning towards the second approach (and have a broken
implementation in Phab:D1830).
The trouble is that you need to be very careful when handling recursive
kinding relationships. Consider, for instance, these examples:
{{{#!hs
(->) :: (->) * (* -> *)
TYPE :: Levity -> TYPE 'Lifted
}}}
Here the types we are trying to derive kind representations for appear in
their own kinds. This causes trouble in solving for these representations:
Currently we construct `Typeable` evidence by decomposing type
applications until we hit a tycon. One way to account for kind
representations would be to require that when generating evidence for
`Typeable (t :: k)` we also generate evidence for `Typeable k`. However,
if we do this naively we end up sending the solver in a loop. Consider the
case we are asked to solve for `Typeable (Int -> Bool)`. Evidence
construction would roughly proceed as follows,
{{{
want (Typeable (Int -> Bool :: *))
want (Typeable ((->) :: (* -> * -> *)) -- Normally this isn't a
problem:
-- since (->) is a
TyCon, we could
-- just stop here;
but...
-- now we need a kind
representation
want (Typeable (* -> * -> *))
want (Typeable ((->) * (* -> *))) -- again we decompose
want (Typeable (->))
want (Typeable (* -> * -> *)) -- again solve for kind
of (->)
... -- now we are in a
loop...
}}}
Likewise, we can also get non-trivial cycles,
{{{#!hs
Levity :: TYPE 'Lifted
TYPE :: Levity -> TYPE 'Lifted
'Lifted :: Levity
}}}
One way to address this issue would be to manually define these
representations (just as we did before my recent solution to #11120),
allowing us to tie the knot.
It's possible, however, that I have fundamentally misunderstood something
here. If so, please feel free to say so.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10343#comment:24>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list