Hal Daume writes: | I'm sorry, I had a small error in my code. It should have been: | | >go filelist = mapM go' filelist -- no "do return" | > where go' f = do h <- openFile f ReadMode | > text <- hGetContents h | > let c = head $! text | > return (c `seq` (hClose h `seq` c)) Hi. I don't have a handy installation of ghc to check this on, but here's a speculative attempt. go' f = do h <- openFile f ReadMode text <- hGetContents h case text of (c:_) -> do hClose h return c This way, the pattern match on `text' happens before the innermost `do', which in turn closes the handle before letting the rest of the computation continue. You may be able to get a similar effect with one more strictness operator ... return $! (c `seq` hClose h `seq` c) but that's not quite as readable. BTW I'm not sure that the strictness operator in `head $! text' makes any difference. It ensures that when the expression's evaluated, `text' is reduced to WHNF before `head' is applied to it. But then the very next thing which happens is a pattern match (head (x:_) = x) which would force that reduction anyway. Hope that (isn't mistake-ridden and) helps. - Tom