# deriving weirdness on newtypes

Simon Peyton-Jones simonpj@microsoft.com
Tue, 22 Oct 2002 12:36:03 +0100

```Hal

I have fixed this bug in the HEAD.

The fix is more than a tiny one, so I'm inclined to leave it as a know
bug in 5.02.2.   It'd cost me another few hours to patch it into the
5.02 branch.  I don't think this is a widely-used feature, yet.  Even
John Hughes didn't notice the bug.

Simon

| -----Original Message-----
| From: Hal Daume III [mailto:hdaume@ISI.EDU]
| Sent: 02 October 2002 18:58
| To: GHC Users Mailing List
| Subject: deriving weirdness on newtypes
|=20
| So I love the fact that I can derive anything I want on
| newtypes.  However, there seem to be problems with it.  If I write:
|=20
|     newtype Foo =3D Foo Int deriving (Show)
|     x =3D show (Foo 5)
|=20
| Then x is "Foo 5"
|=20
| However, if I do
|=20
|     newtype Foo =3D Foo Int deriving (Num)
|     x =3D show (Foo 5)
|=20
| Then the definition of 'x' claims that there is no Show instance of
Foo.
|=20
| However (this is where it gets weird).  If I do:
|=20
|     newtype Foo =3D Foo Int deriving (Num)
|     x =3D show ((Foo 5) + 4)
|=20
| then x is *valid* and has value "9", not "Foo 9".  Moreoever, I can
even
| do:
|=20
|     x =3D show ((5::Foo) + 4)
|=20
| and this x has value "9".
|=20
| Futhermore, if I do:
|=20
|     newtype Foo =3D Foo Int deriving (Show,Num)
|=20
| then "show (Foo 5)" has value "5", not "Foo 5".
|=20
| IMO, the correct value of "show (Foo 5)" no matter which of the above
we
| have is "Foo 5".  I think the deriving mechanism should be changed in
two
| ways.
|=20
|   (1) If you derive X on a newtype and X is a subclass of Y,
|       you must have an instance of Y on that newtype.  This is
|       how it works on data types, and I think makes sense.
|       For instance,
|         newtype Foo =3D Foo Int deriving (Ord)
|       should be just as illegal as
|         data Foo =3D Foo Int deriving (Ord)
|=20
|   (2) The derived Show instances for newtypes in the presense of
|       derived Num instances should be fixed so that the
|       constructor is also printed.  Rational: adding something
|       to the list of derived classes should *not* change
|       previously derived instances.
|=20
| There is yet another thing.  If we have:
|=20
|     newtype Foo =3D Foo Int deriving (Num)
|     instance Show Foo where { show =3D undefined }
|=20
| then, the value of 'show (Foo 5)' is undefined, but the value of 'show
| (5::Foo)' is "5".  definately *WRONG*.
|=20
|  - Hal
|=20
| --
| Hal Daume III
|=20
|  "Computer science is no more about computers    | hdaume@isi.edu
|   than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume
|=20
| _______________________________________________