[Haskell-cafe] Iteratee IO examples
jwlato at gmail.com
Sat Jun 25 12:51:48 CEST 2011
From: Eric Rasmussen <ericrasmussen at gmail.com>
> Examples are very helpful to me too -- thank you for sharing. I'm
> curious to see if there are any examples that allow you to use or convert
> non-iteratee-based functions. I have only just begun reading about
> and might be missing the point, but it seems like many of the examples so
> far rely on explicit recursion or special functions from one of the
You might be interested in the attoparsec-enumerator and attoparsec-iteratee
packages, which adapt attoparsec parsers to work with iteratees. They're
small, self-contained, and quite readable. Since attoparsec works with
partial parses, it's a natural fit for iteratees.
Honestly I'm quite dis-satisfied with the current state of code which
depends on iteratee/enumerator. It's nearly all written in a very low-level
style, i.e. directly writing 'liftI step', or 'case x of Yield -> ...'.
This is exactly what I would hope users could avoid, by using the functions
in e.g. Data.Iteratee.ListLike.
I've recently added more functions to iteratee which greatly reduce the need
for this type of code. I don't know about enumerator, but I expect it isn't
rich enough since most user code I've seen is pretty low-level.
For some other iteratee examples, you can 'darcs get
http://www.tiresiaspress.us/haskell/sndfile-enumerators/' and look at the
examples directory (or browse online, of course).
> Is there a way to take a simple function (example below) and use an
> enumerator to feed it a ByteString from a file, or do you have to write
> functions explicitly to work with a given iteratee implementation?
> import qualified Data.ByteString.Char8 as B
> sortLines = B.unlines . sort . B.lines
For this case, there's no point to using iteratees at all. Just read the
file in directly to a strict bytestring. Since you're sorting, you'll need
to see all the lines before results can be returned. If the file is too big
to fit into memory, you'd need a more sophisticated algorithm for which you
could use iteratees.
In the general case, you need to write for a given iteratee implementation,
but in many specific cases it's not necessary. If you want to transform
each line of a file, for instance (with iteratee):
import Data.ByteString.Char8 as B
import Data.Iteratee as I
transform :: (ByteString -> ByteString) -> FilePath -> Iteratee [ByteString]
transform tFunc oFile = do
h <- liftIO $ openFile oFile WriteMode
joinI $ rigidMapStream tFunc $ I.mapM_ (B.hPutStrLn h)
liftIO $ hClose h
rewriteFile :: (ByteString -> ByteString) -> FilePath -> FilePath -> IO ()
rewriteFile tFunc iFile oFile = fileDriver (joinI $ enumLinesBS (transform
tFunc oFile)) iFile
An unfolding version would be possible too, which would take a parameter
tFunc :: (s -> ByteString -> (s, ByteString))
Maybe I'll add these as utilities in the next version of iteratee.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe