content: {-# LANGUAGE CPP                        #-}
  {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  {-# LANGUAGE OverloadedStrings          #-}
  
  -- | 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>.
  module System.IO.Streams
   ( -- * Stream types
     InputStream
   , OutputStream
  
  
     -- ** A note about resource acquisition\/release semantics
     -- $resource
  
     -- * Creating streams
   , makeInputStream
   , makeOutputStream
  
     -- * Primitive stream operations
   , read
   , unRead
   , peek
   , write
   , writeTo
   , atEOF
  
     -- * Connecting streams together
   , connect
   , connectTo
   , supply
   , supplyTo
   , appendInputStream
   , concatInputStreams
  
     -- * Thread safety \/ concurrency
   , lockingInputStream
   , lockingOutputStream
  
     -- * Utility streams
   , nullInput
   , nullOutput
  
      -- * Generator monad
      -- $generator
    , Generator
    , fromGenerator
    , yield
  
     -- * 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
  #ifdef ENABLE_NETWORK
   , module System.IO.Streams.Network
  #endif
   , module System.IO.Streams.Process
   , module System.IO.Streams.Text
   , module System.IO.Streams.Vector
  #ifdef ENABLE_ZLIB
   , module System.IO.Streams.Zlib
  #endif
   ) where
  
  ------------------------------------------------------------------------------
  import           Prelude                       ()
  
  ------------------------------------------------------------------------------
  import           System.IO.Streams.Internal
  
  import           System.IO.Streams.Builder
  import           System.IO.Streams.ByteString
  import           System.IO.Streams.Combinators
  import           System.IO.Streams.File
  import           System.IO.Streams.Handle
  import           System.IO.Streams.List
  #ifdef ENABLE_NETWORK
  import           System.IO.Streams.Network
  #endif
  import           System.IO.Streams.Process
  import           System.IO.Streams.Text
  import           System.IO.Streams.Vector
  #ifdef ENABLE_ZLIB
  import           System.IO.Streams.Zlib
  #endif
  
  ------------------------------------------------------------------------------
  -- $generator
  -- #generator#
  --
  -- 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' $ 'Control.Monad.sequence' $ 'Prelude.map' Streams.'yield' [1..5::Int]) >>= Streams.'toList'
  -- [1,2,3,4,5]
  -- @
  
  
  ------------------------------------------------------------------------------
  -- $resource
  -- #resource#
  --
  -- 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 'System.IO.Streams.withFileAsInput'. For example, sending
  -- \"end-of-stream\" to an 'OutputStream' wrapped around a 'System.IO.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
  -- 'Control.Exception.bracket' to handle resource acquisition and cleanup in an
  -- exception-safe way.
  --
  
  