These streams slightly resemble Haskell Handles, but support a
wider range of sources and sinks. For example, you can convert an ordinary list
to an InputStream source and interact with it using the
handle-based API:

Additionally, IO streams come with a library of stream transformations that
preserve their handle-like API. For example, you can map a function over an
InputStream, which generates a new handle to the same
stream that returns transformed values:

The Just wraps more incoming data, whereas Nothing indicates the data is
exhausted. In principle, you can feed OutputStreams more
input after writing a Nothing to them, but IO streams only guarantee a
well-defined behavior up to the first Nothing. After receiving the first
Nothing, an OutputStream could respond to additional
input by:

Using the input

Ignoring the input

Throwing an exception

Ideally, you should adhere to well-defined behavior and ensure that after you
write a Nothing to an OutputStream, you don't write
anything else.

Keep in mind that you do not need to use connect or
supply at all: io-streams mainly provides them for user
convenience. You can always build your own abstractions on top of the
read and write operations.

Transform Streams

When we build or use IO streams we can tap into all the stream-processing
features the io-streams library provides. For example, we can decompress any
InputStream of ByteStrings:

io-streams provides many useful functions such as these in its standard
library and you take advantage of them by defining IO streams that wrap your
resources.

Resource and Exception Safety

IO streams use standard Haskell idioms for resource safety. Since all
operations occur in the IO monad, you can use catch,
bracket, or various "with..." functions to guard any
read or write without any special
considerations:

InputStreams can customize pushback behavior to support
more sophisticated support for pushback. For example, if you protect a stream
using throwIfProducesMoreThan and
unRead input, it will subtract the unread input from the
total byte count. However, these extra features will not interfere with the
basic pushback contract, given by the following law: