[Haskell-cafe] Lazy IO.

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Sun Jun 15 17:27:30 EDT 2008


On Sat, 2008-06-14 at 18:18 +0200, 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)

Can you get the contents as a bytestring, then unpack that to a String
for the purpose of parsing a prefix of the input as the headers. Since
unpacking to a String is lazy it means you should only end up using
String for the headers and not for the payload.

As others have pointed out it's not clear from the above how you
separate the headers and the body. Returning the length of the headers
might work and then drop that amount from the bytestring would give the
body as a bytestring.

Duncan



More information about the Haskell-Cafe mailing list