[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