#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