[Haskell-beginners] Question on Lazy IO

Chul-Woong Yang cwyang at aranetworks.com
Thu Jul 24 09:08:50 UTC 2014


Thank you, Michael, for kind explanation.

My first approach was calling the following sentinel function
before proceeding:
isValidReq req = (type req) /= ERROR && (length $ hdrs req) < 10000

The hdrs of (web) request are constructed lazily, so I should do length
call to
wait until full request are read.

With HTTP processing, I cannot figure out how to do with strict I/O.
Maybe complex parsing (parsec?) is required, I think.

So I changed the sentinel function using deepseq.
isVaidReq req = (hdrs req) `deepseq` (type req) /= ERROR

Regards,
Chul-Woong


2014-07-24 16:54 GMT+09:00 Michael Snoyman <michael at snoyman.com>:

> My biggest recommendation would be not to use lazy I/O. But excluding
> that...
>
> You just need to make sure that as much of the input is actually received
> before sending a response. You do that by forcing evaluation of the thunk.
> With lazy I/O, forcing evaluation ends up causing I/O to be performed,
> which is what you want in this case. As an example, to make sure that at
> least one character is received before continuing, you could use this
> function:
>
> getSomeContents = do
>   x <- getContents
>   case x of
>     [] -> return x
>     _:_ -> return x
>
> Another possibility is to use *some* strict I/O. For example, you can get
> the first character strictly and the rest lazily:
>
> getSomeContents = do
>   c <- getChar
>   x <- getContents
>   return $ c : x
>
> Something else you should think about is what data representation you want
> to use. Everything we've done here using String, which is (1) inefficient,
> since it's an unpacked representation, and (2) incorrect, since HTTP data
> is really a series of bytes, not a series of unicode code points. But I'm
> going on the assumption that this exercise is more to understand I/O
> evaluation.
>
>
> On Thu, Jul 24, 2014 at 9:07 AM, 양철웅 <cwyang at aranetworks.com> wrote:
>
>> Hi, all.
>>
>> Haskell's lazy IO causes below program to
>> write back "ECHO result" to the user
>> even if he doesn't give any input to the program.
>>
>> test1 :: IO ()
>> test1 = do
>>   l <- fmap lines getContents
>>   putStrLn "ECHO result"
>>   putStr $ unlines l
>>
>> If the client logic, that is the part for feeding data to this program
>> and wait for the response, expect the server logic to respond
>> only after all the client's request data are feed to the server logic,
>> the behaviour could be problematic.
>>
>> I'm now writing simple web server, as you might guess, and
>> my web server responds "HTTP/1.1" before any client's request
>> are given. I'm using hGetContents and web server's logic is
>> basically same with above code skeleton.
>>
>> How can I tell the program to respond data only after all the
>> requests are feed? Any directions are welcomed.
>> Thanks.
>>
>> Chul-Woong
>>
>>
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://www.haskell.org/mailman/listinfo/beginners
>>
>>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20140724/b50c59ce/attachment-0001.html>


More information about the Beginners mailing list