[Haskell-cafe] Lazy IO.

Sebastiaan Visser sfvisser at cs.uu.nl
Sat Jun 14 12:18:48 EDT 2008


I've got a question about lazy IO in Haskell. The most well known
function to do lazy IO is the `hGetContents', which lazily reads all the
contents from a handle and returns this as a regular [Char].

The thing with hGetContents is that is puts the Handle in a semi-closed
state, no one can use the handle anymore. This behaviour is
understandable from the point of safety; it is not yet determined when
the result of hGetContents will actually be computed, using the handle
in the meantime is undesirable.

The point is, I think I really have a situation in which I want to use
the handle again `after' a call to hGetContents. I think I can best
explain this using a code example.

   readHttpMessage :: IO (Headers, Data.ByteString.Lazy.ByteString)
   readHttpMessage = do
     myStream <- <accept http connection from client>
     request <- hGetContents myStream
     header <- parseHttpHeader request
     bs <- Data.ByteString.Lazy.hGetContents myStream
     return (header, body)

The Data.ByteString.Lazy.hGetContents in the example above obviously
fails because the handle is semi-closed.

So, what I am trying to do here is apply a parser (on that consumes
Char's) to the input stream until it has succeeded. After this I want to
collect the remainings of the stream in a lazy ByteString, or maybe even
something else.

I tried to open the handler again using some internal handle hackery,
but this failed (luckily). In the module GHC.IO there is a function
`lazyRead' that more or less seems to do what I want. But I'll guess
there is a good reason for not exporting it.

Does anyone know a pattern in which I can do this easily?



More information about the Haskell-Cafe mailing list