
#8503: New GeneralizedNewtypeDeriving check still isn't permissive enough -------------------------------------+------------------------------------ Reporter: goldfire | Owner: goldfire Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.7 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: 8548 Blocking: | Related Tickets: #8541 -------------------------------------+------------------------------------ Comment (by nomeata): Replying to [comment:9 goldfire]:
Hold the phone! There is an easier solution to the original problem!
\[..\]
Thoughts? Is this a good plan? We could always, as a first pass, implement GND in terms of `Coercible` and fail if there are any unsolved constraints, working for `C Age` above but not `C (List a)`.
I’ve been trying to get your attempt to work. It works for a lot of easy cases, and it works in theory, but there is an implementational difficulty with extra type variables in the instance. Consider: {{{ import GHC.Exts class Cls a where meth :: a newtype Id m = Id m deriving Cls }}} The instance we want to generate is {{{ instance forall m. Cls m => Cls (Id m) where meth = coerce (meth :: m) :: Id m }}} But that will require `ScopedTypeVariables`. Question one: Can I generate code at `TcGenDeriv` stage that uses scoped type variables, without requiring that extension to be enabled in the whole module? Next problem: Currently the code produces {{{ ==================== Derived instances ==================== Derived instances: instance T3423.Cls m_ayI => T3423.Cls (T3423.Id m_ayI) where T3423.meth = GHC.Prim.coerce (T3423.meth :: m_ayI) :: T3423.Id m_ayI }}} so there is no `forall` in the instance head. For `newtype ... deriving Cls` it might be possible to add that (although I did not yet find where), but the user should be able to specify {{{ deriving instance Cls m => Cls (Id m) }}} without having to add `forall m.`. I’m not sure what to do here. It would be best if we could generate code that works without having to specify types in the method definition at all, maybe using something like `$ClsId = case $superClassDict of D:Cls meth => D:Cls (coerce meth)`, but I do not see how `$superClassDict` should look like. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8503#comment:35 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler