
On Sun, 26 Jun 2011 09:27:47 -0400
David Place
On Jun 26, 2011, at 8:25 AM, Heinrich Apfelmus wrote:
What about the combinator
withFile :: FilePath -> (String -> a) -> IO a withFile name f = bracket (openFile name ReadMode) hClose $ \h -> evaluate . f =<< hGetContents h
? It gives you the same thing as Iteratees - a way to apply a function to the contents of a file - without the need to rewrite all the existing list functions like map , lines , words , and so on.
When I stumbled upon lazy IO newbie-wise I was pointed to withFile resp. bracket by Daniel Fischer and now that I know how to do it it seems fine to me. It also alerted me to pay more attention to lazyness as this is a Haskell immanent thingie.
How would you, for instance, implement the program for counting all the words in a list of files that Oleg describes in his message?
I'm not quite sure if it boils down to the same problem structure-wise but I had to scan thru some 4000 small xml files, and I did it like this (after Daniel lifted me up...): import qualified System.IO.UTF8 as U ... dt <- scanDir ccbd let xmlfiles = filter (\x -> "xml" `isSuffixOf` x) dt -- insert xml contents into two maps s, and ht. (s,ht) <- foldM insertXml (M.empty,M.empty) xmlfiles ... and insertXml (stat, m) xf = U.withBinaryFile xf ReadMode (\handle -> do ct <- getXmlContent xf handle ... some code... return $! (stat',m')) and getXmlContent xf inh = do xml <- U.hGetContents inh let content = parseXMLDoc xml ... -- Manfred