HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Moduleio-streams-1.5.2.2Haskell2010

System.IO.Streams.Combinators

Generic stream manipulations

  • 37 values
  • Packageio-streams-1.5.2.2
  • Exports37
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceCombinators.hs

Folds

10 declarations
valueinputFoldM
  1. :: (a -> b -> IO a)

    fold function

  2. -> a

    initial seed

  3. -> InputStream b

    input stream

  4. -> IO (InputStream b, IO a)

    returns a new stream as well as an IO action to fetch and reset the updated seed value.

#

A side-effecting fold over an InputStream, as a stream transformer.

The IO action returned by inputFoldM can be used to fetch and reset the updated seed value. Example:

ghci> is <- Streams.fromList [1, 2, 3::Int]
ghci> (is', getSeed) <- Streams.inputFoldM (\x y -> return (x+y)) 0 is
ghci> Streams.toList is'
[1,2,3]
ghci> getSeed
6
valueoutputFoldM
  1. :: (a -> b -> IO a)

    fold function

  2. -> a

    initial seed

  3. -> OutputStream b

    output stream

  4. -> IO (OutputStream b, IO a)

    returns a new stream as well as an IO action to fetch and reset the updated seed value.

#

A side-effecting fold over an OutputStream, as a stream transformer.

The IO action returned by outputFoldM can be used to fetch and reset the updated seed value. Example:

ghci> is <- Streams.fromList [1, 2, 3::Int]
ghci> (os, getList) <- Streams.listOutputStream
ghci> (os', getSeed) <- Streams.outputFoldM (\x y -> return (x+y)) 0 os
ghci> Streams.System.IO.Streams.connect is os'
ghci> getList
[1,2,3]
ghci> getSeed
6
valuefold
  1. :: (s -> a -> s)

    fold function

  2. -> s

    initial seed

  3. -> InputStream a

    input stream

  4. -> IO s
#

A left fold over an input stream. The input stream is fully consumed. See foldl.

Example:

ghci> Streams.System.IO.Streams.fromList [1..10] >>= Streams.fold (+) 0
55
valuefoldM
  1. :: (s -> a -> IO s)

    fold function

  2. -> s

    initial seed

  3. -> InputStream a

    input stream

  4. -> IO s
#

A side-effecting left fold over an input stream. The input stream is fully consumed. See foldl.

Example:

ghci> Streams.System.IO.Streams.fromList [1..10] >>= Streams.foldM (x y -> return (x + y)) 0
55
valuefold_
  1. :: (x -> a -> x)

    accumulator update function

  2. -> x

    initial seed

  3. -> (x -> s)

    recover folded value

  4. -> InputStream a

    input stream

  5. -> IO s
#

A variant of System.IO.Streams.fold suitable for use with composable folds from 'beautiful folding' libraries like the foldl library. The input stream is fully consumed.

Example:

ghci> let folds = liftA3 (,,) Foldl.length Foldl.mean Foldl.maximum
ghci> Streams.System.IO.Streams.fromList [1..10::Double] >>= Foldl.purely Streams.System.IO.Streams.fold_ folds is
ghci> (10,5.5,Just 10.0)

Since 1.3.6.0

valuefoldM_
  1. :: (x -> a -> IO x)

    accumulator update action

  2. -> IO x

    initial seed

  3. -> (x -> IO s)

    recover folded value

  4. -> InputStream a

    input stream

  5. -> IO s
#

A variant of System.IO.Streams.foldM suitable for use with composable folds from 'beautiful folding' libraries like the foldl library. The input stream is fully consumed.

Example:

ghci> let folds = Foldl.mapM_ print *> Foldl.generalize (liftA2 (,) Foldl.sum Foldl.mean)
ghci> Streams.System.IO.Streams.fromList [1..3::Double] >>= Foldl.impurely Streams.System.IO.Streams.foldM_ folds
1.0
2.0
3.0
(6.0,2.0)

Since 1.3.6.0

valueany :: (a -> Bool) -> InputStream a -> IO Bool
#

any predicate stream returns True if any element in stream matches the predicate.

any consumes as few elements as possible, ending consumption if an element satisfies the predicate.

ghci> is <- Streams.fromList [1, 2, 3]
ghci> Streams.any (> 0) is    -- Consumes one element
True
ghci> Streams.System.IO.Streams.read is
Just 2
ghci> Streams.any even is     -- Only 3 remains
False
valueall :: (a -> Bool) -> InputStream a -> IO Bool
#

all predicate stream returns True if every element in stream matches the predicate.

all consumes as few elements as possible, ending consumption if any element fails the predicate.

ghci> is <- Streams.fromList [1, 2, 3]
ghci> Streams.all (< 0) is    -- Consumes one element
False
ghci> Streams.System.IO.Streams.read is
Just 2
ghci> Streams.all odd is      -- Only 3 remains
True
valuemaximum :: Ord a => InputStream a -> IO (Maybe a)
#

maximum stream returns the greatest element in stream or Nothing if the stream is empty.

maximum consumes the entire stream.

ghci> is <- Streams.fromList [1, 2, 3]
ghci> Streams.maximum is
3
ghci> Streams.System.IO.Streams.read is     -- The stream is now empty
Nothing
valueminimum :: Ord a => InputStream a -> IO (Maybe a)
#

minimum stream returns the greatest element in stream

minimum consumes the entire stream.

ghci> is <- Streams.fromList [1, 2, 3]
ghci> Streams.minimum is
1
ghci> Streams.System.IO.Streams.read is    -- The stream is now empty
Nothing

Unfolds

1 declaration
valueunfoldM :: (b -> IO (Maybe (a, b))) -> b -> IO (InputStream a)
#

unfoldM f seed builds an InputStream from successively applying f to the seed value, continuing if f produces Just and halting on Nothing.

ghci> is <- Streams.unfoldM (n -> return $ if n < 3 then Just (n, n + 1) else Nothing) 0
ghci> Streams.toList is
[0,1,2]

Maps

8 declarations
valuemapM_ :: (a -> IO b) -> InputStream a -> IO (InputStream a)
#

Maps a side effect over an InputStream.

mapM_ f s produces a new input stream that passes all output from s through the side-effecting IO action f.

Example:

ghci> Streams.System.IO.Streams.fromList [1,2,3] >>=
      Streams.mapM_ (putStrLn . show . (*2)) >>=
      Streams.System.IO.Streams.toList
2
4
6
[1,2,3]
valuemapMaybe :: (a -> Maybe b) -> InputStream a -> IO (InputStream b)
#

A version of map that discards elements

mapMaybe f s passes all output from s through the function f and discards elements for which f s evaluates to Nothing.

Example:

ghci> Streams.System.IO.Streams.fromList [Just 1, None, Just 3] >>=
      Streams.mapMaybe id >>=
      Streams.System.IO.Streams.toList
[1,3]

Since: 1.2.1.0

Filter

4 declarations
valuefilter :: (a -> Bool) -> InputStream a -> IO (InputStream a)
#

Drops chunks from an input stream if they fail to match a given filter predicate. See filter.

Items pushed back to the returned stream are propagated back upstream.

Example:

ghci> Streams.System.IO.Streams.fromList ["the", "quick", "brown", "fox"] >>=
      Streams.filter (/= "brown") >>= Streams.System.IO.Streams.toList
["the","quick","fox"]
valuefilterM :: (a -> IO Bool) -> InputStream a -> IO (InputStream a)
#

Drops chunks from an input stream if they fail to match a given filter predicate. See Prelude.filter.

Items pushed back to the returned stream are propagated back upstream.

Example:

ghci> Streams.System.IO.Streams.fromList ["the", "quick", "brown", "fox"] >>=
      Streams.filterM (return . (/= "brown")) >>= Streams.System.IO.Streams.toList
["the","quick","fox"]
valuefilterOutputM :: (a -> IO Bool) -> OutputStream a -> IO (OutputStream a)
#

Filters output to be sent to the given OutputStream using a predicate function in IO. See filterM.

Example:

ghci> let check a = putStrLn a ("Allow " ++ show a ++ "?") >> readLn :: IO Bool
ghci> import qualified Data.ByteString.Char8 as S
ghci> os1 <- Streams.System.IO.Streams.unlines Streams.System.IO.Streams.stdout
ghci> os2 <- os1 >>= Streams.contramap (S.pack . show) >>= Streams.filterOutputM check
ghci> Streams.System.IO.Streams.write (Just 3) os2
Allow 3?
False<Enter>
ghci> Streams.System.IO.Streams.write (Just 4) os2
Allow 4?
True<Enter>
4

Takes and drops

4 declarations
valuetake :: Int64 -> InputStream a -> IO (InputStream a)
#

Wraps an InputStream, producing a new InputStream that will produce at most n items, subsequently yielding end-of-stream forever.

Items pushed back to the returned InputStream will be propagated upstream, modifying the count of taken items accordingly.

Example:

ghci> is <- Streams.fromList [1..9::Int]
ghci> is' <- Streams.take 1 is
ghci> Streams.read is'
Just 1
ghci> Streams.read is'
Nothing
ghci> Streams.System.IO.Streams.peek is
Just 2
ghci> Streams.unRead 11 is'
ghci> Streams.System.IO.Streams.peek is
Just 11
ghci> Streams.System.IO.Streams.peek is'
Just 11
ghci> Streams.read is'
Just 11
ghci> Streams.read is'
Nothing
ghci> Streams.read is
Just 2
ghci> Streams.toList is
[3,4,5,6,7,8,9]

Zip and unzip

5 declarations
valuezipWith
  1. :: a -> b -> c
  2. -> InputStream a
  3. -> InputStream b
  4. -> IO (InputStream c)
#

Combines two input streams using the supplied function. Continues yielding elements from both input streams until one of them finishes.

valuezipWithM
  1. :: a -> b -> IO c
  2. -> InputStream a
  3. -> InputStream b
  4. -> IO (InputStream c)
#

Combines two input streams using the supplied monadic function. Continues yielding elements from both input streams until one of them finishes.

valueunzip :: InputStream (a, b) -> IO (InputStream a, InputStream b)
#

Takes apart a stream of pairs, producing a pair of input streams. Reading from either of the produced streams will cause a pair of values to be pulled from the original stream if necessary. Note that reading n values from one of the returned streams will cause n values to be buffered at the other stream.

Access to the original stream is thread safe, i.e. guarded by a lock.

Utility

5 declarations
valueintersperse :: a -> OutputStream a -> IO (OutputStream a)
#

The function intersperse v s wraps the OutputStream s, creating a new output stream that writes its input to s interspersed with the provided value v. See intersperse.

Example:

ghci> import Control.Monad ((>=>))
ghci> is <- Streams.fromList ["nom", "nom", "nom"::ByteString]
ghci> Streams.outputToList (Streams.intersperse "burp!" >=> Streams.System.IO.Streams.connect is)
["nom","burp!","nom","burp!","nom"]