
Hello Neil,
On Thu, Nov 27, 2008 at 13:17, Neil Mitchell
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