[Haskell-cafe] a bug in Read instance of Int?

Brent Yorgey byorgey at gmail.com
Thu Mar 28 11:09:21 UTC 2019


The 2010 Haskell Report specifies that

(x,"") is an element of (readsPrec d (showsPrec d x ""))

Notice it does NOT say that

(x,s) is an element of (readsPrec d (showsPrec d x s))

which would be false, as your example shows by setting x = 123 and s =
".456".

read really isn't meant to be a general-purpose parser; it only works on
sequences of lexical tokens. As Ömer points out, reads @Int and reads
@Double both depend on 'lex', and there is no way for 'lex' to know what
kind of thing reads is ultimately trying to parse.  If you changed lex so
that lex "123.456aaa" returns [("123", ".456aaa")] then reads @Double would
break.  I suppose you could try to change lex so that lex "123.456aaa"
returns [("123", ".456aaa"), ("123.456", "aaa")] but this seems like a lot
of work for little benefit.  If you are running into this kind of issue
with Read instances, it strongly suggests to me that you should be using a
proper parsing library rather than Read.

-Brent

On Thu, Mar 28, 2019 at 5:08 AM Ömer Sinan Ağacan <omeragacan at gmail.com>
wrote:

> Hi,
>
> I'm not sure if this is a bug, but I think the problem is in the lexer,
> not in
> the part that that tries to convert a single token to a value of the given
> type.
> Example:
>
>     λ:1> lex "123"
>     [("123","")]
>
>     λ:2> lex "123.aaa"
>     [("123",".aaa")]
>
>     λ:3> lex "123.456aaa"
>     [("123.456","aaa")]
>
> So in "123.aaa" you actually convert "123" to an Int, but in "123.456aaa"
> you
> try to convert "123.456" to an Int, which fails.
>
> Not sure how hard would it be to improve this (while keeping things
> standard-compliant) or whether it's worth the effort.
>
> Ömer
>
> Javran Cheng <javran.c at gmail.com>, 27 Mar 2019 Çar, 10:17 tarihinde şunu
> yazdı:
> >
> > Hi Cafe,
> >
> > Not sure if there are existing discussions, but I recently run into a
> problem with Read instance of Int:
> >
> > Prelude> :set -XTypeApplications
> > Prelude> reads @Int "123."
> > [(123,".")]
> > Prelude> reads @Int "123.aaa"
> > [(123,".aaa")]
> > Prelude> reads @Int "123.456aaa"
> > [] -- I expected this to be [(123,".456aaa")]
> > Prelude> reads @Double "123.234aaa"
> > [(123.234,"aaa")]
> >
> > Further investigation shows that [realNumber](
> http://hackage.haskell.org/package/base/docs/src/GHC.Read.html#readNumber)
> is used for Read instance of Int.
> > I think what happened is that when the leading parser input can be
> parsed as a floating number, it will do so and commit to that decision,
> making backtracking impossible.
> >
> > I do understand that Read just need to be able to parse whatever Show
> can produce and is not designed to deal with raw inputs, but this is still
> a surprising behavior to me.
> > When I'm using Text.ParserCombinators.ReadP, I really appreciates it
> that I can use `readP_to_S read` to parse simple values (integers and
> floating points in particular),
> > but it bothers me that parsing Int from "123.aaa" is fine but "123.1aa"
> will fail simply because the not-yet-consumed part of input is different.
> >
> > Javran
> > _______________________________________________
> > Haskell-Cafe mailing list
> > To (un)subscribe, modify options or view archives go to:
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > Only members subscribed via the mailman list are allowed to post.
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20190328/3f38fdda/attachment.html>


More information about the Haskell-Cafe mailing list