fast IO in ghc

Koen Claessen koen@cs.chalmers.se
Thu, 4 Apr 2002 08:49:19 +0200 (MET DST)


"Simon Peyton-Jones" <simonpj@microsoft.com> writes:

 | And, with a lot of help from Koen, I'm about to fold
 | in a much more efficient implementation of Read, which
 | may help.

On Thu, 4 Apr 2002, Jan-Willem Maessen wrote:

 | Any of the guilty parties want to give a quick
 | overview of how it's going to work?

The basic idea is as follows. We have an efficient
(abstract) parser type 'ReadP', which supports the following
operations:

  readP_to_S :: ReadP a -> ReadS a
  readS_to_P :: ReadS a -> ReadP a  -- might be slow

(The reason for ReadP to be abstract is so that it can be
changed to a more efficient implementation if one comes
along.)

Remember that ReadS is defined as:

  type ReadS a = String -> [(a,String)]

Now, suppose the definition of the Read class were as
follows:

  class Read a where
    reads :: ReadS a

What we did, we just added an extra method to the Read
class:

  class Read a where
    reads :: ReadS a
    readp :: ReadP a

    -- default definitions
    reads = readP_to_S readp
    readp = readS_to_P reads

Whenever GHC does a "deriving Read", it will define the
readp parser (which is efficient) rather than the reads
parser. The reads parser will just be defined in terms of
the readp parser.

Whenever an ignorant user comes along and makes an old-style
instance of the Read class:

  instance Read MyType where
    reads s = ...

The readp parser will still be there, but it might possibly
be slow.

Of course up-to-date users can make efficient instances by
actually defining readp rather than reads.

This is the basic idea. Unfortunately, the Read class does
not look like this, and we have to take care of precedences
(rather easy) and the readList method (tricky).

We will probably submit a paper to the Haskell workshop
about this.

/Koen.

--
Koen Claessen
http://www.cs.chalmers.se/~koen
Chalmers University, Gothenburg, Sweden.