A note about resource acquisition/release semantics

In general, the convention within this library is that input and output
streams do not deal with resource acquisition/release semantics, with rare
exceptions like withFileAsInput. For example, sending
"end-of-stream" to an OutputStream wrapped around a Handle
doesn't cause the handle to be closed. You can think of streams as little
state machines that are attached to the underlying resources, and the
finalization/release of these resources is up to you.

This means that you can use standard Haskell idioms like
bracket to handle resource acquisition and cleanup in an
exception-safe way.

As a general rule, you should not acquire resources that need to be freed
from a Generator, because there is no guarantee the coroutine continuation
will ever be called, nor can you catch an exception from within a
Generator.

Calling yield x causes the value Just x to appear on the input
when this generator is converted to an InputStream. The rest of the
computation after the call to yield is resumed later when the
InputStream is read again.