[Haskell-cafe] SYB with class: Bug in Derive.hs module

Simon Peyton-Jones simonpj at microsoft.com
Tue Sep 16 12:27:20 EDT 2008


The message below is a rather old thread but, as Ian says, it's related to

http://hackage.haskell.org/trac/ghc/ticket/1470
http://hackage.haskell.org/trac/ghc/ticket/1735

which I have been looking it in preparation for 6.10.

The good news is that I think I have fixed #1470.  I think #1735 is deeply dodgy code which is rendered unnecessary by #1470.

The key part is this (the full message is below):

| The Data instance that Derive generates is as follows:
|
|  > instance (Data ctx a,
|  >                   Data ctx (BinTree a),
|  >                   Sat (ctx (BinTree a))) =>
|  >                   Data ctx (BinTree a) where
|
| Note the recursive |Data ctx (BinTree a)| in the context. If I get
| rid of it (a correct manual instance is also included in the
| attachment) the example works.

This is indeed a Bad Instance. It says "if you supply me with a (Data ctx (BinTree a)) dictionary, I will construct a (Data ctx (BinTree a)) dictionary".  It's akin to saying
        instance Eq [a] => Eq [a]

Admittedly,
 a) #1470 meant that leaving off this constraint stopped the program compiling
 b) under very special conditions (I'm not quite sure what) you could
        just about make such a program work (see #1735) with the Bad Instance

But the right thing is
  a) to fix #1470 (which I have done) and
  b) to omit the bad constraint from the instance declaration
        (which needs a change to some library)

OK?  I'll commit the fix tomorrow.

Simon


| -----Original Message-----
| From: haskell-cafe-bounces at haskell.org [mailto:haskell-cafe-bounces at haskell.org] On Behalf Of
| Alexey Rodriguez Yakushev
| Sent: 31 March 2008 14:47
| To: haskell-cafe
| Cc: AlexJacobson at HAppS.org; Ralf Laemmel
| Subject: [Haskell-cafe] SYB with class: Bug in Derive.hs module
|
| Hi people (and Ralf and Alex),
|
| I found a bug in the SYB with class library when trying to implement
| generic equality. I am hoping that someone in the Cafe (maybe Ralf)
| can confirm it is a bug, or maybe show me that I am doing something
| wrong.
|
| I am using the "Scrap your boilerplate with class" library (http://
| homepages.cwi.nl/~ralf/syb3/). More precisely, I am using the library
| distributed by the HAppS project, because it works with GHC 6.8 . You
| can get the repository as follows:
|
| darcs get http://happs.org/HAppS/syb-with-class
|
| However, the offending module (Derive.hs) produces broken instances
| in both distributions.
|
| The bug:
| ----------
|
| Generic equality needs type safe casting when implemented in SYB3, I
| have tried both the gzipwith variant and using Pack datatypes
| (geq*.hs in the first distribution). However, both functions loop
| when applied to a tree value.
|
| This loop occurs when the functions try to cast one of the arguments.
| I have managed to reduce the error to a smaller source file that I
| send attached. It does the following:
|
|  > main = print typeReps
|  >
|  > tree = (Bin (Leaf 1) (Leaf 2))::BinTree Int
|  >
|  > data Pack = forall x. Typeable x => Pack x
|  >
|  > packedChildren = gmapQ geqCtx Pack tree
|  >
|  > typeOfPack (Pack x) = typeOf x
|  >
|  > typeReps = map typeOfPack packedChildren
|
| Basically the tree is transformed into a list of Pack-ed values and
| then to a list of type representations. This program loops at
| "typeOf" when you call "main".
|
| The Data instance that Derive generates is as follows:
|
|  > instance (Data ctx a,
|  >                   Data ctx (BinTree a),
|  >                   Sat (ctx (BinTree a))) =>
|  >                   Data ctx (BinTree a) where
|
| Note the recursive |Data ctx (BinTree a)| in the context. If I get
| rid of it (a correct manual instance is also included in the
| attachment) the example works.
|
| I thought of removing this from the context in the Derive source. But
| maybe I might break some other use cases. So I am asking for help!
| Should Derive be fixed? How?
|
| Cheers,
|
| Alexey



More information about the Haskell-Cafe mailing list