
On Sunday 23 May 2010 13:12:16, wren ng thornton wrote:
Daniel Fischer wrote:
There are more rules elsewhere. If you compile with optimisations, GHC turns your realToFrac into double2Float# nicely, so it's okay to use realToFrac. However, without optimisations, no rules fire, so you'll get (fromRational . toRational).
That must be new, because it didn't used to be the case.
GHC.Float.lhs contains the rules for (realToFrac :: (Float|Double) -> (Float|Double)) since 6.8.1 at least, I didn't look at previous releases.
Also, rewrite rules can be fragile.
True. I don't see how you would construct such a situation for these rules, but if several rules match a piece of code, you can't know which one fires first, perhaps making the others not match anymore. And inlining may prevent rules from matching, too. If you need rewrite rules, it is advisable to check whether they actually fired.
Not to mention that the (fromRational . toRational) definition is incorrect for converting between Float and Double because Rational cannot properly encode the transfinite values in Float/Double.
The robust solution is to use the RealToFrac class from the logfloat package:
http://hackage.haskell.org/packages/archive/logfloat/0.12.1/doc/html/Dat a-Number-RealToFrac.html
Yes.