Hello Neil,

On Thu, Nov 27, 2008 at 13:17, Neil Mitchell <ndmitchell@gmail.com> wrote:
Hi José,

You may also want to weigh in on this issue:

http://hackage.haskell.org/trac/ghc/ticket/2782

The instance of Ratio changed between 6.10 and 6.8 in a way that means
a program can't reflect on the fields contained within the :%
constructor using the value undefined. The reason is that :% is marked
as strict in both arguments, so _|_ :% _|_ == _|_. This breaks
Uniplate, and I've had to explicitly make a test for a type of
Rational in the Uniplate code - which is ugly. I'm not sure how many
other programs this might break - or if the impact was well understood
when the change was made.

This change is made massively worse by giving the error message
"undefined" when it fails! If an SYB using program goes from working
in GHC 6.8 to failing in GHC 6.10 with "undefined", this may be a
culprit.

I see that this in particular has been fixed already.
 


I'm not sure there is a nice solution - reflection at the type level
(using _|_ at the value level), combined with strictness at the value
level, has limitations. It may be that the reflection machinery in SYB
can be tweaked to either alert the user in advance (i.e. by getting
the strictness of various fields), or providing some operation
combining gmapQ and fromConstr which isn't strict. To see my use case
take a look at "contains" in:

http://www.cs.york.ac.uk/fp/darcs/uniplate/Data/Generics/PlateData.hs

I'm not sure there's an easy solution either. As you say, the problem here seems to be caused by the strictness. Getting the strictness of each field would require changes to the representation types and to the deriving mechanism.

Would your problem be solved if you used fromConstrB instead of simply fromConstr and built an entirely determined (without bottoms) value?


Thanks,
Pedro