[GHC] #14579: GeneralizedNewtypeDeriving produces ambiguously-kinded code
GHC
ghc-devs at haskell.org
Sat Jan 5 22:18:04 UTC 2019
#14579: GeneralizedNewtypeDeriving produces ambiguously-kinded code
-------------------------------------+-------------------------------------
Reporter: RyanGlScott | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone: 8.10.1
Component: Compiler (Type | Version: 8.2.2
checker) |
Resolution: | Keywords: deriving
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: GHC rejects | Test Case:
valid program | deriving/should_compile/T14579{a}
Blocked By: 12045 | Blocking:
Related Tickets: | Differential Rev(s): Phab:D4264,
Wiki Page: | Phab:D5229
-------------------------------------+-------------------------------------
Comment (by RyanGlScott):
Cruelly enough, comment:20 means the the original program in this ticket
must have an explicit kind signature anyway, since in the kind of
`'Proxy`:
{{{#!hs
'Proxy :: forall {k} (a :: k). Proxy a
}}}
We have an inferred type variable binder! Argh.
I wonder if we can be a bit smarter about where we put explicit kind
signatures? This is the code that GHC 8.6.3 currently generates for the
original program's `Eq (Glurp a)` instance:
{{{
instance GHC.Classes.Eq a => GHC.Classes.Eq (Bug.Glurp a) where
(GHC.Classes.==)
= GHC.Prim.coerce
@((Bug.Wat (Data.Proxy.Proxy :: (Data.Proxy.Proxy a_a1Dx :: TYPE
GHC.Types.LiftedRep)) :: TYPE GHC.Types.LiftedRep)
-> (Bug.Wat (Data.Proxy.Proxy :: (Data.Proxy.Proxy a_a1Dx ::
TYPE GHC.Types.LiftedRep)) :: TYPE GHC.Types.LiftedRep)
-> GHC.Types.Bool)
@(Bug.Glurp a_a1Dx -> Bug.Glurp a_a1Dx -> GHC.Types.Bool)
(GHC.Classes.==) ::
Bug.Glurp a_a1Dx -> Bug.Glurp a_a1Dx -> GHC.Types.Bool
(GHC.Classes./=)
= GHC.Prim.coerce
@((Bug.Wat (Data.Proxy.Proxy :: (Data.Proxy.Proxy a_a1Dx :: TYPE
GHC.Types.LiftedRep)) :: TYPE GHC.Types.LiftedRep)
-> (Bug.Wat (Data.Proxy.Proxy :: (Data.Proxy.Proxy a_a1Dx ::
TYPE GHC.Types.LiftedRep)) :: TYPE GHC.Types.LiftedRep)
-> GHC.Types.Bool)
@(Bug.Glurp a_a1Dx -> Bug.Glurp a_a1Dx -> GHC.Types.Bool)
(GHC.Classes./=) ::
Bug.Glurp a_a1Dx -> Bug.Glurp a_a1Dx -> GHC.Types.Bool
}}}
There are many explicit kind signatures here that are completely
redundant—for instance, each `(_ :: TYPE GHC.Types.LiftedRep)` signature
is redundant, since they're not needed to fix any type variables. The only
signature that's strictly necessary is the `(Data.Proxy.Proxy ::
(Data.Proxy.Proxy a_a1Dx :: ...))` one, since that fixes `a_a1Dx`.
Perhaps we should adopt a more fine-grained heuristic (besides the mere
presence of inferred type variable binders) to determine when to insert
explicit kind signatures? For instance, the `reify_tc_app` function in
`TcSplice` (which reifies applications of tycons) uses a more complicated
heuristic: if the free variables of the tycon's kind are not a subset of
the free variables of the arguments in injective positions, then it needs
an explicit signature. (This is explained in
[https://gitlab.haskell.org/ghc/ghc/blob/master/compiler/typecheck/TcSplice.hs#L1824-1917
this Note]).
This heuristic could work well in this situation as well. We'd need to
modify the definition of "injective positions" to include specified
arguments (currently it only includes required ones), but if we did, then
I believe we could drop all of the explicit signatures in the original
program.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14579#comment:21>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list