[Haskell-cafe] Proper round-trip HughesPJ/Parsec for Doubles?

Daniel Fischer daniel.is.fischer at web.de
Tue Feb 23 09:27:27 EST 2010

Am Dienstag 23 Februar 2010 14:44:50 schrieb Andy Gimblett:
> Hi all,
> Short version: How can I pretty print and parse values of type Double
> such that those operations are each other's inverse?
> Long version: I'm writing and QuickCheck-testing a parser using the
> approach set out here:
> http://lstephen.wordpress.com/2007/07/29/parsec-parser-testing-with-quic
> That is, each syntactic category gets a pretty-printer and a parser
> and an Arbitrary instance, and QuickCheck checks that (parse .
> prettyPrint) == id, basically.  Somewhat unsurprisingly, this
> sometimes fails for floating point values (I'm using Doubles).
> Now, I know that floats are in some sense imprecise, and comparing for
> equality is fraught with peril, but it seems that if x==x then it
> ought to be at least _possible_ to arrange matters such that (parse .
> prettyPrint x) == x as well.  At worst, pretty-printing the underlying
> binary representation!?  So my feeling is that my parser could be
> improved.

Parse it as a Rational, then convert with fromRational.
I don't know whether that will always have parse . prettyPrint == id, but 
it'll be much closer.

The naturalOrFloat default implementation uses

    fraction        = do{ char '.'
                        ; digits <- many1 digit <?> "fraction"
                        ; return (foldr op 0.0 digits)
                      <?> "fraction"
                      op d f    = (f + fromIntegral (digitToInt d))/10.0

and division by 10 isn't exact with a binary representation.

> At the moment I'm working around it by defining a type class which
> checks for equality within some margin of error, and using that
> instead of Eq - but it's messier than I'd like, so I wondered if there
> was something obvious I'm missing.
> As hpaste.org seems to be down, I'll attach a code example here instead.
> Thanks!
> -Andy
> --
> Andy Gimblett
> http://gimbo.org.uk/

More information about the Haskell-Cafe mailing list