Sebastiaan Visser wrote:
Hi,

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)

that's impure because parseHttpHeader doesn't return anything telling you how much of the stream it's looked at. Maybe it looked ahead more than it needed to, thus deleting part of the body. I was going to suggest, if you can't change parseHttpHeader to use ByteStrings,

>     bs <- Data.ByteString.Lazy.hGetContents myStream
>     header <- parseHttpHeader (Data.ByteString.Lazy.unpack bs)

but you still have to get parseHttpHeader (or perhaps if it has similar friends) to tell you how much of the string it consumed! I don't know what parsing functions you have available to work with, so I can't tell you whether it's possible.

-Isaac
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to