[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