
Ryan Ingram wrote:
I usually use something like this instead:
hStrictGetContents :: Handle -> IO String hStrictGetContents h = do s <- hGetContents h length s `seq` hClose h return s
A small idiomatic nitpick: When I see (length s) gets computed and thrown away I wince at the wasted effort. I would prefer (finiteSpine s): finiteSpine = foldr (const id) () hStrictGetContents :: Handle -> IO String hStrictGetContents h = do s <- hGetContents h finiteSpine s `seq` hClose h return s "finiteSpine" finds the "end" of a finite list and will hang forever on an infinite list. One can even notice that the type of finiteSpine is Strategy [a]: import Control.Parallel.Strategies(Strategy) finiteSpine :: Strategy [a] finiteSpine = foldr (const id) () And in fact "finiteSpine = seqList r0", which returns () after applying the "do nothing" strategy "r0" to every element. -- Chris