Iteratee I/O is a way to avoid the problems that can occur with lazy I/O. They work by making the I/O actions explicit, making their behavior easier to reason about.

−

Iteratee I/O is a way to avoid the problems that can occur with lazy I/O.

+

== The problem with lazy I/O ==

−

Discussions elsewhere on this wiki include:

+

As a beginner, you probably used Haskell's lazy I/O through the <code>System.IO</code> module. However, while it is good enough for simple programs, its unpredictability makes it unsuitable for practical use.

−

* [[Enumerator and iteratee]]

+

For example, a common beginner mistake is to close a file before one has finished reading it:

−

* [[Iteratee]]

+

−

Essays by Oleg:

+

<haskell>

+

wrong = do

+

fileData <- withFile "test.txt" ReadMode hGetContents

+

putStr fileData

+

</haskell>

+

+

The problem is <code>withFile</code> closes the handle before <code>fileData</code> is forced. The correct way is to pass all the code to <code>withFile</code>:

+

+

<haskell>

+

right = withFile "test.txt" ReadMode $ \handle -> do

+

fileData <- hGetContents handle

+

putStr fileData

+

</haskell>

+

+

Here, the data is consumed before <code>withFile</code> finishes.

+

+

Although this is easily fixed, the type system does not enforce the correct solution. Even worse, if you use the former code, it won't even raise an error &ndash; it will just fail silently and return an empty string. Many years passed before a satisfactory solution to the ''streaming data problem'' was found.

+

+

== How iteratees work ==

+

+

When you "step" an iteratee, it reads a chunk of data, updates the internal state and returns a new iteratee along with the data it read. Because an iteratee is simply a function with state, many iteratees can be composed together to form a pipeline.

+

+

Some implementations also provide a resource management layer that releases resources automatically when they are no longer needed. This is very useful in a server, where sockets and file handles are scarce.

* [http://hackage.haskell.org/package/enumerator enumerator] [http://www.haskell.org/pipermail/haskell-cafe/2010-August/082324.html ANNOUNCE: enumerator, an alternative iteratee package] (this package does not use any extensions, so it will work with most Haskell compilers)

Although this is easily fixed, the type system does not enforce the correct solution. Even worse, if you use the former code, it won't even raise an error – it will just fail silently and return an empty string. Many years passed before a satisfactory solution to the streaming data problem was found.

2 How iteratees work

When you "step" an iteratee, it reads a chunk of data, updates the internal state and returns a new iteratee along with the data it read. Because an iteratee is simply a function with state, many iteratees can be composed together to form a pipeline.

Some implementations also provide a resource management layer that releases resources automatically when they are no longer needed. This is very useful in a server, where sockets and file handles are scarce.