GHC: Ticket Query
http://ghc.haskell.org/trac/ghc/query?status=closed&component=Compiler+(Type+checker)&milestone=6.8.2&group=resolution&order=priority
The Glasgow Haskell Compileren-USGHChttp://ghc.haskell.org/trac/ghc/chrome/site/ghc_logo.png
http://ghc.haskell.org/trac/ghc/query?status=closed&component=Compiler+(Type+checker)&milestone=6.8.2&group=resolution&order=priority
Trac 1.0.1
http://ghc.haskell.org/trac/ghc/ticket/1220
http://ghc.haskell.org/trac/ghc/ticket/1220#1220: Newtype deriving should only work if superclasses are newtype-derivedTue, 13 Mar 2007 16:53:43 GMTsimonpj<p>
Twan van Laarhoven writes: I just noticed some unexpected consequences of the way newtype deriving is implemented in GHC. Because the dictionary of the underlying type is reused, so are base classes. This message is a literate Haskell program
illustrating the problem.
</p>
<pre class="wiki"> > {-# OPTIONS_GHC -fglasgow-exts #-}
</pre><p>
This problem comes up when an instance method calls a method of a base
class. Consider the following useless example:
</p>
<pre class="wiki"> > class Show a => Show2 a where
> show2 :: a -> String
> show2 = show
>
> instance Show2 Int
</pre><p>
Now consider a type deriving Show2, but having a different
implementation of Show (also derived).
</p>
<pre class="wiki"> > newtype Meter = Meter Int
> deriving (Eq, Show, Show2)
</pre><p>
Now, for show2 the derived Show instance (which also shows the
constructor name) is *not* used, instead the Show Int instance is used:
</p>
<pre class="wiki">] > show2 (Meter 1)
] "1"
] > show (Meter 1)
] "Meter 1"
</pre><p>
This is quite unexpected, unless you consider what is going on behind
the scenes. Even more confusingly, GHC requires that there is a Show
instance for Meters, even if it will not be used!
</p>
<pre class="wiki">] No instance for (Show Meter)
] arising from the superclasses of an instance declaration at ...
] Probable fix: add an instance declaration for (Show Meter)
] In the instance declaration for `Show2 Meter'
</pre><p>
This problem can come up whenever a class instance uses a function from
a base class. Right now this not likely happen, but it will become more
common if the standard classes are split up:
</p>
<pre class="wiki"> > class Additive a where
> add :: a -> a -> a
> class Additive a => Subtractive a where
> neg :: a -> a
> sub :: a -> a -> a
> sub x y = add x (neg y) -- calls base class function add
> class Functor m => Monad' m where
> return' :: a -> m a
> join' :: m (m a) -> m a
> join' x = bind' x id
> bind' :: m a -> (a -> m b) -> m b
> bind' ma k = join' (fmap k ma) -- calls base class function fmap
</pre><p>
As a solution I would suggest that newtype deriving a class instance is
only allowed if all base classes instances are also derived using
newtype deriving. This presents problems for Show and Read, because they
cannot be derived in that way. It will, however, catch problems with
most other classes.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/1220#changelog