[Haskell-cafe] Embarrassed Haskeller -- why is Read so bad? What are alternatives?
Bertram Felgenhauer
bertram.felgenhauer at googlemail.com
Tue Oct 15 16:23:36 UTC 2013
Dear Ryan,
> Read instances are both (1) slow, because they take Strings, and (2) they
> don't allow sensible error messages! (Historical decision choosing Maybe
> rather than Either.)
Surprisingly, I have found (1) to be a rather small issue. Read has at
least two other features that make it abysmally slow.
- Read is built on top of a lexer (Prelude.lex), which in turn is based
on ReadP. This means checking a lot of cases which are often useless,
since while a parser would likely know which token types to expect
next, 'lex' doesn't. It even causes otherwise inexplicable non-
termination: For example,
> read ('"' : repeat ' ') :: Int
never terminates, because 'lex' keeps on trying to determine whether
the given string starts with a valid string literal or not.
ReadP supports unlimited backtracking, a well-known source of bad
performance in parsers (at least when the alternatives are returned
as a list, which ReadP does.)
- Read itself *also* supports unlimited backtracking; it's built around
the ReadS type, ReadS a = String -> [(a, String)]. Again, this causes
bad performance.
In comparison, unfolding, say, a bytestring to a temporary list that is
consumed by a parser is cheap. Of course, it's still a good idea to
avoid this.
I second the suggestions to use one of the modern parser libraries
instead.
> Argh!,
Indeed.
Bertram
More information about the Haskell-Cafe
mailing list