io-streams-1.5.2.2: Simple, composable, and easy-to-use stream I/O

Safe Haskell | None
Language | Haskell2010

System.IO.Streams

Contents

- Stream types
  - A note about resource acquisition/release semantics
- Creating streams
- Primitive stream operations
- Connecting streams together
- Thread safety / concurrency
- Utility streams
- Generator monad
- Batteries included

Description

This module is a top-level convenience module which re-exports most of the `io-streams` library.

It is recommended to import this module qualified, as follows:

    import           System.IO.Streams (Generator, InputStream, OutputStream)
    import qualified System.IO.Streams as Streams

For an in-depth tutorial on how to use `io-streams`, please see the System.IO.Streams.Tutorial module.

Is there a function missing from this library? Interested in contributing? Send a pull request to http://github.com/snapframework/io-streams.

Synopsis

- data InputStream a
- data OutputStream a
- makeInputStream :: IO (Maybe a) -> IO (InputStream a)
- makeOutputStream :: (Maybe a -> IO ()) -> IO (OutputStream a)
- read :: InputStream a -> IO (Maybe a)
- unRead :: a -> InputStream a -> IO ()
- peek :: InputStream a -> IO (Maybe a)
- write :: Maybe a -> OutputStream a -> IO ()
- writeTo :: OutputStream a -> Maybe a -> IO ()
- atEOF :: InputStream a -> IO Bool
- connect :: InputStream a -> OutputStream a -> IO ()
- connectTo :: OutputStream a -> InputStream a -> IO ()
- supply :: InputStream a -> OutputStream a -> IO ()
- supplyTo :: OutputStream a -> InputStream a -> IO ()
- appendInputStream :: InputStream a -> InputStream a -> IO (InputStream a)
- concatInputStreams :: [InputStream a] -> IO (InputStream a)
- lockingInputStream :: InputStream a -> IO (InputStream a)
- lockingOutputStream :: OutputStream a -> IO (OutputStream a)
- nullInput :: IO (InputStream a)
- nullOutput :: IO (OutputStream a)
- data Generator r a
- fromGenerator :: Generator r a -> IO (InputStream r)
- yield :: r -> Generator r ()
- module System.IO.Streams.Builder
- module System.IO.Streams.ByteString
- module System.IO.Streams.Combinators
- module System.IO.Streams.Handle
- module System.IO.Streams.File
- module System.IO.Streams.List
- module System.IO.Streams.Network
- module System.IO.Streams.Process
- module System.IO.Streams.Text
- module System.IO.Streams.Vector
- module System.IO.Streams.Zlib

# Stream types

data InputStream a #

An `InputStream` generates values of type `c` in the `IO` monad.

Two primitive operations are defined on `InputStream`:

- ``read` :: `InputStream` c -> `IO` (`Maybe` c)` reads a value from the stream, where "end of stream" is signaled by `read` returning `Nothing`.
- ``unRead` :: c -> `InputStream` c -> `IO` ()` "pushes back" a value to the stream.

It is intended that `InputStream`s obey the following law:

    unRead c stream >> read stream === return (Just c)

#### Instances

Instances details

BufferedIO (InputStream ByteString) # |
Instance details Defined in System.IO.Streams.Internal Methods newBuffer :: InputStream ByteString -> BufferState -> IO (Buffer Word8) # fillReadBuffer :: InputStream ByteString -> Buffer Word8 -> IO (Int, Buffer Word8) # fillReadBuffer0 :: InputStream ByteString -> Buffer Word8 -> IO (Maybe Int, Buffer Word8) # emptyWriteBuffer :: InputStream ByteString -> Buffer Word8 -> IO (Buffer Word8) # flushWriteBuffer :: InputStream ByteString -> Buffer Word8 -> IO (Buffer Word8) # flushWriteBuffer0 :: InputStream ByteString -> Buffer Word8 -> IO (Int, Buffer Word8) #
BufferedIO (StreamPair ByteString) # |
Instance details Defined in System.IO.Streams.Internal Methods newBuffer :: StreamPair ByteString -> BufferState -> IO (Buffer Word8) # fillReadBuffer :: StreamPair ByteString -> Buffer Word8 -> IO (Int, Buffer Word8) # fillReadBuffer0 :: StreamPair ByteString -> Buffer Word8 -> IO (Maybe Int, Buffer Word8) # emptyWriteBuffer :: StreamPair ByteString -> Buffer Word8 -> IO (Buffer Word8) # flushWriteBuffer :: StreamPair ByteString -> Buffer Word8 -> IO (Buffer Word8) # flushWriteBuffer0 :: StreamPair ByteString -> Buffer Word8 -> IO (Int, Buffer Word8) #
IODevice (InputStream ByteString) # |
Instance details Defined in System.IO.Streams.Internal Methods ready :: InputStream ByteString -> Bool -> Int -> IO Bool # close :: InputStream ByteString -> IO () # isTerminal :: InputStream ByteString -> IO Bool # isSeekable :: InputStream ByteString -> IO Bool # seek :: InputStream ByteString -> SeekMode -> Integer -> IO Integer # tell :: InputStream ByteString -> IO Integer # getSize :: InputStream ByteString -> IO Integer # setSize :: InputStream ByteString -> Integer -> IO () # setEcho :: InputStream ByteString -> Bool -> IO () # getEcho :: InputStream ByteString -> IO Bool # setRaw :: InputStream ByteString -> Bool -> IO () # devType :: InputStream ByteString -> IO IODeviceType # dup :: InputStream ByteString -> IO (InputStream ByteString) # dup2 :: InputStream ByteString -> InputStream ByteString -> IO (InputStream ByteString) #
IODevice (StreamPair ByteString) # |
Instance details Defined in System.IO.Streams.Internal Methods ready :: StreamPair ByteString -> Bool -> Int -> IO Bool # close :: StreamPair ByteString -> IO () # isTerminal :: StreamPair ByteString -> IO Bool # isSeekable :: StreamPair ByteString -> IO Bool # seek :: StreamPair ByteString -> SeekMode -> Integer -> IO Integer # tell :: StreamPair ByteString -> IO Integer # getSize :: StreamPair ByteString -> IO Integer # setSize :: StreamPair ByteString -> Integer -> IO () # setEcho :: StreamPair ByteString -> Bool -> IO () # getEcho :: StreamPair ByteString -> IO Bool # setRaw :: StreamPair ByteString -> Bool -> IO () # devType :: StreamPair ByteString -> IO IODeviceType # dup :: StreamPair ByteString -> IO (StreamPair ByteString) # dup2 :: StreamPair ByteString -> StreamPair ByteString -> IO (StreamPair ByteString) #
RawIO (InputStream ByteString) # | The offset argument is ignored if present.
Instance details Defined in System.IO.Streams.Internal Methods read :: InputStream ByteString -> Ptr Word8 -> Word64 -> Int -> IO Int # readNonBlocking :: InputStream ByteString -> Ptr Word8 -> Word64 -> Int -> IO (Maybe Int) # write :: InputStream ByteString -> Ptr Word8 -> Word64 -> Int -> IO () # writeNonBlocking :: InputStream ByteString -> Ptr Word8 -> Word64 -> Int -> IO Int #
RawIO (StreamPair ByteString) # | The offset argument is ignored if present.
Instance details Defined in System.IO.Streams.Internal Methods read :: StreamPair ByteString -> Ptr Word8 -> Word64 -> Int -> IO Int # readNonBlocking :: StreamPair ByteString -> Ptr Word8 -> Word64 -> Int -> IO (Maybe Int) # write :: StreamPair ByteString -> Ptr Word8 -> Word64 -> Int -> IO () # writeNonBlocking :: StreamPair ByteString -> Ptr Word8 -> Word64 -> Int -> IO Int #

data OutputStream a #

An `OutputStream` consumes values of type `c` in the `IO` monad. The only primitive operation defined on `OutputStream` is:

-     write :: Maybe c -> OutputStream c -> IO ()

Values of type `c` are written in an `OutputStream` by wrapping them in `Just`, and the end of the stream is indicated by supplying `Nothing`.

If you supply a value after a `Nothing`, the behavior is defined by the implementer of the given `OutputStream`. (All `OutputStream` definitions in this library will simply discard the extra input.)

#### Instances

Instances details

BufferedIO (OutputStream ByteString) # |
Instance details Defined in System.IO.Streams.Internal Methods newBuffer :: OutputStream ByteString -> BufferState -> IO (Buffer Word8) # fillReadBuffer :: OutputStream ByteString -> Buffer Word8 -> IO (Int, Buffer Word8) # fillReadBuffer0 :: OutputStream ByteString -> Buffer Word8 -> IO (Maybe Int, Buffer Word8) # emptyWriteBuffer :: OutputStream ByteString -> Buffer Word8 -> IO (Buffer Word8) # flushWriteBuffer :: OutputStream ByteString -> Buffer Word8 -> IO (Buffer Word8) # flushWriteBuffer0 :: OutputStream ByteString -> Buffer Word8 -> IO (Int, Buffer Word8) #
BufferedIO (StreamPair ByteString) # |
Instance details Defined in System.IO.Streams.Internal Methods newBuffer :: StreamPair ByteString -> BufferState -> IO (Buffer Word8) # fillReadBuffer :: StreamPair ByteString -> Buffer Word8 -> IO (Int, Buffer Word8) # fillReadBuffer0 :: StreamPair ByteString -> Buffer Word8 -> IO (Maybe Int, Buffer Word8) # emptyWriteBuffer :: StreamPair ByteString -> Buffer Word8 -> IO (Buffer Word8) # flushWriteBuffer :: StreamPair ByteString -> Buffer Word8 -> IO (Buffer Word8) # flushWriteBuffer0 :: StreamPair ByteString -> Buffer Word8 -> IO (Int, Buffer Word8) #
IODevice (OutputStream ByteString) # |
Instance details Defined in System.IO.Streams.Internal Methods ready :: OutputStream ByteString -> Bool -> Int -> IO Bool # close :: OutputStream ByteString -> IO () # isTerminal :: OutputStream ByteString -> IO Bool # isSeekable :: OutputStream ByteString -> IO Bool # seek :: OutputStream ByteString -> SeekMode -> Integer -> IO Integer # tell :: OutputStream ByteString -> IO Integer # getSize :: OutputStream ByteString -> IO Integer # setSize :: OutputStream ByteString -> Integer -> IO () # setEcho :: OutputStream ByteString -> Bool -> IO () # getEcho :: OutputStream ByteString -> IO Bool # setRaw :: OutputStream ByteString -> Bool -> IO () # devType :: OutputStream ByteString -> IO IODeviceType # dup :: OutputStream ByteString -> IO (OutputStream ByteString) # dup2 :: OutputStream ByteString -> OutputStream ByteString -> IO (OutputStream ByteString) #
IODevice (StreamPair ByteString) # |
Instance details Defined in System.IO.Streams.Internal Methods ready :: StreamPair ByteString -> Bool -> Int -> IO Bool # close :: StreamPair ByteString -> IO () # isTerminal :: StreamPair ByteString -> IO Bool # isSeekable :: StreamPair ByteString -> IO Bool # seek :: StreamPair ByteString -> SeekMode -> Integer -> IO Integer # tell :: StreamPair ByteString -> IO Integer # getSize :: StreamPair ByteString -> IO Integer # setSize :: StreamPair ByteString -> Integer -> IO () # setEcho :: StreamPair ByteString -> Bool -> IO () # getEcho :: StreamPair ByteString -> IO Bool # setRaw :: StreamPair ByteString -> Bool -> IO () # devType :: StreamPair ByteString -> IO IODeviceType # dup :: StreamPair ByteString -> IO (StreamPair ByteString) # dup2 :: StreamPair ByteString -> StreamPair ByteString -> IO (StreamPair ByteString) #
RawIO (OutputStream ByteString) # | The offset argument is ignored if present.
Instance details Defined in System.IO.Streams.Internal Methods read :: OutputStream ByteString -> Ptr Word8 -> Word64 -> Int -> IO Int # readNonBlocking :: OutputStream ByteString -> Ptr Word8 -> Word64 -> Int -> IO (Maybe Int) # write :: OutputStream ByteString -> Ptr Word8 -> Word64 -> Int -> IO () # writeNonBlocking :: OutputStream ByteString -> Ptr Word8 -> Word64 -> Int -> IO Int #
RawIO (StreamPair ByteString) # | The offset argument is ignored if present.
Instance details Defined in System.IO.Streams.Internal Methods read :: StreamPair ByteString -> Ptr Word8 -> Word64 -> Int -> IO Int # readNonBlocking :: StreamPair ByteString -> Ptr Word8 -> Word64 -> Int -> IO (Maybe Int) # write :: StreamPair ByteString -> Ptr Word8 -> Word64 -> Int -> IO () # writeNonBlocking :: StreamPair ByteString -> Ptr Word8 -> Word64 -> Int -> IO Int #

## 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.

# Creating streams

makeInputStream :: IO (Maybe a) -> IO (InputStream a) #

Creates an `InputStream` from a value-producing action.

(`makeInputStream m`) calls the action `m` each time you request a value from the `InputStream`. The given action is extended with the default pushback mechanism (see System.IO.Streams.Internal).

makeOutputStream :: (Maybe a -> IO ()) -> IO (OutputStream a) #

Creates an `OutputStream` from a value-consuming action.

(`makeOutputStream f`) runs the computation `f` on each value fed to it.

Since version 1.2.0.0, `makeOutputStream` also ensures that output streams no longer receive data once EOF is received (i.e. you can now assume that makeOutputStream will feed your function `Nothing` at most once.)

# Primitive stream operations

read :: InputStream a -> IO (Maybe a) #

Reads one value from an `InputStream`.

Returns either a value wrapped in a `Just`, or `Nothing` if the end of the stream is reached.

unRead :: a -> InputStream a -> IO () #

Pushes a value back onto an input stream. `read` and `unRead` should satisfy the following law, with the possible exception of side effects:

    Streams.unRead c stream >> Streams.read stream === return (Just c)

Note that this could be used to add values back to the stream that were not originally drawn from the stream.

peek :: InputStream a -> IO (Maybe a) #

Observes the first value from an `InputStream` without consuming it.

Returns `Nothing` if the `InputStream` is empty. `peek` satisfies the following law:

    Streams.peek stream >> Streams.read stream === Streams.read stream

write :: Maybe a -> OutputStream a -> IO () #

Feeds a value to an `OutputStream`. Values of type `c` are written in an `OutputStream` by wrapping them in `Just`, and the end of the stream is indicated by supplying `Nothing`.

writeTo :: OutputStream a -> Maybe a -> IO () #

Flipped version of `write`.

Since: 1.3.0.0.

atEOF :: InputStream a -> IO Bool #

Checks if an `InputStream` is at end-of-stream.

# Connecting streams together

connect :: InputStream a -> OutputStream a -> IO () #

Connects an `InputStream` and `OutputStream`, supplying values from the `InputStream` to the `OutputStream`, and propagating the end-of-stream message from the `InputStream` through to the `OutputStream`.

The connection ends when the `InputStream` yields a `Nothing`.

connectTo :: OutputStream a -> InputStream a -> IO () #

The `connectTo` function is just ``flip` `connect``.

Useful for writing expressions like `fromList [1,2,3] >>= connectTo foo`.

supply :: InputStream a -> OutputStream a -> IO () #

Connects an `InputStream` to an `OutputStream` without passing the end-of-stream notification through to the `OutputStream`.

Use this to supply an `OutputStream` with multiple `InputStream`s and use `connect` for the final `InputStream` to finalize the `OutputStream`, like so:

    do Streams.supply  input1 output
       Streams.supply  input2 output
       Streams.connect input3 output

supplyTo :: OutputStream a -> InputStream a -> IO () #

`supply` with the arguments flipped.

appendInputStream :: InputStream a -> InputStream a -> IO (InputStream a) #

`appendInputStream` concatenates two `InputStream`s, analogous to (`++`) for lists.

The second `InputStream` continues where the first `InputStream` ends.

Note: values pushed back to `appendInputStream` are not propagated to either wrapped `InputStream`.

concatInputStreams :: [InputStream a] -> IO (InputStream a) #

`concatInputStreams` concatenates a list of `InputStream`s, analogous to (`++`) for lists.

Subsequent `InputStream`s continue where the previous one `InputStream` ends.

Note: values pushed back to the `InputStream` returned by `concatInputStreams` are not propagated to any of the source `InputStream`s.

# Thread safety / concurrency

lockingInputStream :: InputStream a -> IO (InputStream a) #

Converts an `InputStream` into a thread-safe `InputStream`, at a slight performance penalty.

For performance reasons, this library provides non-thread-safe streams by default. Use the `locking` functions to convert these streams into slightly slower, but thread-safe, equivalents.

lockingOutputStream :: OutputStream a -> IO (OutputStream a) #

Converts an `OutputStream` into a thread-safe `OutputStream`, at a slight performance penalty.

For performance reasons, this library provides non-thread-safe streams by default. Use the `locking` functions to convert these streams into slightly slower, but thread-safe, equivalents.

# Utility streams

nullInput :: IO (InputStream a) #

An empty `InputStream` that yields `Nothing` immediately.

nullOutput :: IO (OutputStream a) #

An empty `OutputStream` that discards any input fed to it.

# Generator monad

The `Generator` monad makes it easier for you to define more complicated `InputStream`s. Generators have a couple of basic features:

`Generator` is a `MonadIO`, so you can run IO actions from within it using `liftIO`:

    foo :: Generator r a
    foo = liftIO fireTheMissiles

`Generator` has a `yield` function:

    yield :: r -> Generator r ()

A call to "`yield` `x`" causes "`Just` `x`" to appear when reading the `InputStream`. Finally, `Generator` comes with a function to turn a `Generator` into an `InputStream`:

    fromGenerator :: Generator r a -> IO (InputStream r)

Once the `Generator` action finishes, `fromGenerator` will cause an end-of-stream `Nothing` marker to appear at the output. Example:

    ghci> (Streams.fromGenerator $ sequence $ map Streams.yield [1..5::Int]) >>= Streams.toList
    [1,2,3,4,5]

data Generator r a #

A `Generator` is a coroutine monad that can be used to define complex `InputStream`s. You can cause a value of type `Just r` to appear when the `InputStream` is read by calling `yield`:

    g :: Generator Int ()
    g = do
        Streams.yield 1
        Streams.yield 2
        Streams.yield 3

A `Generator` can be turned into an `InputStream` by calling `fromGenerator`:

    m :: IO [Int]
    m = Streams.fromGenerator g >>= Streams.toList     -- value returned is [1,2,3]

You can perform IO by calling `liftIO`, and turn a `Generator` into an `InputStream` with `fromGenerator`.

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`.

#### Instances

Instances details

MonadIO (Generator r) # |
Instance details Defined in System.IO.Streams.Internal Methods liftIO :: IO a -> Generator r a #
Applicative (Generator r) # |
Instance details Defined in System.IO.Streams.Internal Methods pure :: a -> Generator r a # (<*>) :: Generator r (a -> b) -> Generator r a -> Generator r b # liftA2 :: (a -> b -> c) -> Generator r a -> Generator r b -> Generator r c # (*>) :: Generator r a -> Generator r b -> Generator r b # (<*) :: Generator r a -> Generator r b -> Generator r a #
Functor (Generator r) # |
Instance details Defined in System.IO.Streams.Internal Methods fmap :: (a -> b) -> Generator r a -> Generator r b # (<$) :: a -> Generator r b -> Generator r a #
Monad (Generator r) # |
Instance details Defined in System.IO.Streams.Internal Methods (>>=) :: Generator r a -> (a -> Generator r b) -> Generator r b # (>>) :: Generator r a -> Generator r b -> Generator r b # return :: a -> Generator r a #

fromGenerator :: Generator r a -> IO (InputStream r) #

Turns a `Generator` into an `InputStream`.

yield :: r -> Generator r () #

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.

# Batteries included

module System.IO.Streams.Builder

module System.IO.Streams.ByteString

module System.IO.Streams.Combinators

module System.IO.Streams.Handle

module System.IO.Streams.File

module System.IO.Streams.List

module System.IO.Streams.Network

module System.IO.Streams.Process

module System.IO.Streams.Text

module System.IO.Streams.Vector

module System.IO.Streams.Zlib