Hi Oleg, Just thought I'd mention that this is, in fact, my preferred method of iterating over a file. It alleviates the pain associated with lazy file IO, and simultaneously provides a useful abstraction. I actually have 3*2 functions that I use which look like:
type Iteratee iter seed = seed -> iter -> Either seed seed hFoldChars :: FilePath -> Iteratee Char seed -> seed -> IO seed hFoldLines :: FilePath -> Iteratee String seed -> seed -> IO seed hFoldWords :: FilePath -> Iteratee [String] seed -> seed -> IO seed
type IterateeM iter seed = seed -> iter -> IO (Either seed seed) hFoldCharsM :: FilePath -> IterateeM Char seed -> seed -> IO seed hFoldLinesM :: FilePath -> IterateeM String seed -> seed -> IO seed hFoldWordsM :: FilePath -> IterateeM [String] seed -> seed -> IO seed
Which perform as expected (hFoldWords(M) can be written in terms of hFoldLinesM, but I find I use it sufficiently frequently to warrent having it stand out). Also, of course, the only ones actually implemented are the (M) variants; the non-M variants just throw a return into the Iteratee. - Hal
hfold_left:: FileName -> Title -> Iteratee seed -> seed -- the initial seed -> IO seed type FileName = String type Title = String -- just an identifying string for debug printing type Iteratee seed = seed -> Char -> Either seed seed
-- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume