#2721: Newtype deriving doesn't work with type families
-------------------------------------------+--------------------------------
    Reporter:  rl                          |        Owner:                  
        Type:  bug                         |       Status:  new             
    Priority:  normal                      |    Milestone:  6.10.2          
   Component:  Compiler                    |      Version:  6.10.1          
    Severity:  normal                      |   Resolution:                  
    Keywords:                              |   Difficulty:  Unknown         
    Testcase:  deriving/should_fail/T2721  |           Os:  Unknown/Multiple
Architecture:  Unknown/Multiple            |  
-------------------------------------------+--------------------------------
Changes (by simonpj):

  * testcase:  => deriving/should_fail/T2721

Old description:

> This assumes `-XTypeFamiles -XGeneralizedNewtypeDeriving`. Example:
> {{{
> class C a where
>   type T a
>   foo :: a -> T a
>
> instance C Int where
>   type T Int = Int
>   foo = id
>
> newtype N = N Int deriving(C)
> }}}
> This happily produces an `instance C N` but no `type instance T N`. It
> should either (preferably) generate
> {{{
> type instance T N = Int
> }}}
> or fail. The example also compiles if `T` is a data family (the `Int`
> instance needs to be change accordingly). It should probably fail in this
> case.
>
> BTW, this also compiles fine, with rather dramatic consequences:
> {{{
> type family T a
> class C a where
>   foo :: a -> T a
>
> type instance T Int = Int
> instance C Int where
>   foo = id
>
> type instance T N = Double
> newtype N = N Int deriving(C)
> }}}
> I guess this last example is the same bug as `#1496`. I wonder if the
> deriving clause could generate something like:
> {{{
> instance T Int ~ T N => C Int
> }}}

New description:

 This assumes `-XTypeFamiles -XGeneralizedNewtypeDeriving`. Example:
 {{{
 class C a where
   type T a
   foo :: a -> T a

 instance C Int where
   type T Int = Int
   foo = id

 newtype N = N Int deriving(C)
 }}}
 This happily produces an `instance C N` but no `type instance T N`. It
 should either (preferably) generate
 {{{
 type instance T N = Int
 }}}
 or fail. The example also compiles if `T` is a data family (the `Int`
 instance needs to be change accordingly). It should probably fail in this
 case.

 BTW, this also compiles fine, with rather dramatic consequences:
 {{{
 type family T a
 class C a where
   foo :: a -> T a

 type instance T Int = Int
 instance C Int where
   foo = id

 type instance T N = Double
 newtype N = N Int deriving(C)
 }}}
 I guess this last example is the same bug as #1496. I wonder if the
 deriving clause could generate something like:
 {{{
 instance T Int ~ T N => C Int
 }}}

Comment:

 Good point.  For now I'm just going to make it fail.  It's quite a bit
 more work to make it generate the extra instance, and the fact that it
 does not work at all for 'data' convinced me.

 It's annoying that you therefore cannot do newtype-deriving for a class
 with an associated type.  An alternative is to allow top-level
 declarations for associated types, and check that these exist when doing
 the instance decl. So this would be valid:
 {{{
 class C a where
   type T a
   op :: a -> T a

 type instance T Int = Bool
 instance C Int where
   op x = True
 }}}
 So I'll leave this open to record the idea, but meanwhile I'll push a
 patch to make it fail uniformly.

 Simon

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/2721#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to