Sophie

Sophie

distrib > Fedora > 20 > x86_64 > by-pkgid > a7a26a7beab8aa14bdfa46e2f30fdf46 > files > 146

ghc-io-streams-devel-1.1.4.5-1.fc20.x86_64.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
<title>src/System/IO/Streams/Combinators.hs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
<pre><a name="line-1"></a><span class='hs-comment'>-- | Generic stream manipulations</span>
<a name="line-2"></a>
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE BangPatterns       #-}</span>
<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE DeriveDataTypeable #-}</span>
<a name="line-5"></a>
<a name="line-6"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>System</span><span class='hs-varop'>.</span><span class='hs-conid'>IO</span><span class='hs-varop'>.</span><span class='hs-conid'>Streams</span><span class='hs-varop'>.</span><span class='hs-conid'>Combinators</span>
<a name="line-7"></a> <span class='hs-layout'>(</span> <span class='hs-comment'>-- * Folds</span>
<a name="line-8"></a>   <span class='hs-varid'>inputFoldM</span>
<a name="line-9"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>outputFoldM</span>
<a name="line-10"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>fold</span>
<a name="line-11"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>foldM</span>
<a name="line-12"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>any</span>
<a name="line-13"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>all</span>
<a name="line-14"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>maximum</span>
<a name="line-15"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>minimum</span>
<a name="line-16"></a>
<a name="line-17"></a>   <span class='hs-comment'>-- * Unfolds</span>
<a name="line-18"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>unfoldM</span>
<a name="line-19"></a>
<a name="line-20"></a>   <span class='hs-comment'>-- * Maps</span>
<a name="line-21"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>map</span>
<a name="line-22"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>mapM</span>
<a name="line-23"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>mapM_</span>
<a name="line-24"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>contramap</span>
<a name="line-25"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>contramapM</span>
<a name="line-26"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>contramapM_</span>
<a name="line-27"></a>
<a name="line-28"></a>   <span class='hs-comment'>-- * Filter</span>
<a name="line-29"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>filter</span>
<a name="line-30"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>filterM</span>
<a name="line-31"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>filterOutput</span>
<a name="line-32"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>filterOutputM</span>
<a name="line-33"></a>
<a name="line-34"></a>   <span class='hs-comment'>-- * Takes and drops</span>
<a name="line-35"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>give</span>
<a name="line-36"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>take</span>
<a name="line-37"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>drop</span>
<a name="line-38"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>ignore</span>
<a name="line-39"></a>
<a name="line-40"></a>   <span class='hs-comment'>-- * Zip and unzip</span>
<a name="line-41"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>zip</span>
<a name="line-42"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>zipWith</span>
<a name="line-43"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>zipWithM</span>
<a name="line-44"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>unzip</span>
<a name="line-45"></a>
<a name="line-46"></a>   <span class='hs-comment'>-- * Utility</span>
<a name="line-47"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>intersperse</span>
<a name="line-48"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>skipToEof</span>
<a name="line-49"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>ignoreEof</span>
<a name="line-50"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>atEndOfInput</span>
<a name="line-51"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>atEndOfOutput</span>
<a name="line-52"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-53"></a>
<a name="line-54"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-55"></a><span class='hs-keyword'>import</span>           <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Concurrent</span><span class='hs-varop'>.</span><span class='hs-conid'>MVar</span>    <span class='hs-layout'>(</span><span class='hs-varid'>newMVar</span><span class='hs-layout'>,</span> <span class='hs-varid'>withMVar</span><span class='hs-layout'>)</span>
<a name="line-56"></a><span class='hs-keyword'>import</span>           <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span>              <span class='hs-layout'>(</span><span class='hs-varid'>liftM</span><span class='hs-layout'>,</span> <span class='hs-varid'>void</span><span class='hs-layout'>,</span> <span class='hs-varid'>when</span><span class='hs-layout'>)</span>
<a name="line-57"></a><span class='hs-keyword'>import</span>           <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-varop'>.</span><span class='hs-conid'>IO</span><span class='hs-varop'>.</span><span class='hs-conid'>Class</span>     <span class='hs-layout'>(</span><span class='hs-varid'>liftIO</span><span class='hs-layout'>)</span>
<a name="line-58"></a><span class='hs-keyword'>import</span>           <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Int</span>                   <span class='hs-layout'>(</span><span class='hs-conid'>Int64</span><span class='hs-layout'>)</span>
<a name="line-59"></a><span class='hs-keyword'>import</span>           <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>IORef</span>                 <span class='hs-layout'>(</span><span class='hs-varid'>atomicModifyIORef</span><span class='hs-layout'>,</span> <span class='hs-varid'>modifyIORef</span><span class='hs-layout'>,</span> <span class='hs-varid'>newIORef</span><span class='hs-layout'>,</span> <span class='hs-varid'>readIORef</span><span class='hs-layout'>,</span> <span class='hs-varid'>writeIORef</span><span class='hs-layout'>)</span>
<a name="line-60"></a><span class='hs-keyword'>import</span>           <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Maybe</span>                 <span class='hs-layout'>(</span><span class='hs-varid'>isJust</span><span class='hs-layout'>)</span>
<a name="line-61"></a><span class='hs-keyword'>import</span>           <span class='hs-conid'>Prelude</span>                    <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-varid'>all</span><span class='hs-layout'>,</span> <span class='hs-varid'>any</span><span class='hs-layout'>,</span> <span class='hs-varid'>drop</span><span class='hs-layout'>,</span> <span class='hs-varid'>filter</span><span class='hs-layout'>,</span> <span class='hs-varid'>map</span><span class='hs-layout'>,</span> <span class='hs-varid'>mapM</span><span class='hs-layout'>,</span> <span class='hs-varid'>mapM_</span><span class='hs-layout'>,</span> <span class='hs-varid'>maximum</span><span class='hs-layout'>,</span> <span class='hs-varid'>minimum</span><span class='hs-layout'>,</span> <span class='hs-varid'>read</span><span class='hs-layout'>,</span> <span class='hs-varid'>take</span><span class='hs-layout'>,</span> <span class='hs-varid'>unzip</span><span class='hs-layout'>,</span> <span class='hs-varid'>zip</span><span class='hs-layout'>,</span> <span class='hs-varid'>zipWith</span><span class='hs-layout'>)</span>
<a name="line-62"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-63"></a><span class='hs-keyword'>import</span>           <span class='hs-conid'>System</span><span class='hs-varop'>.</span><span class='hs-conid'>IO</span><span class='hs-varop'>.</span><span class='hs-conid'>Streams</span><span class='hs-varop'>.</span><span class='hs-conid'>Internal</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>OutputStream</span><span class='hs-layout'>,</span> <span class='hs-varid'>fromGenerator</span><span class='hs-layout'>,</span> <span class='hs-varid'>makeInputStream</span><span class='hs-layout'>,</span> <span class='hs-varid'>makeOutputStream</span><span class='hs-layout'>,</span> <span class='hs-varid'>read</span><span class='hs-layout'>,</span> <span class='hs-varid'>unRead</span><span class='hs-layout'>,</span> <span class='hs-varid'>write</span><span class='hs-layout'>,</span> <span class='hs-varid'>yield</span><span class='hs-layout'>)</span>
<a name="line-64"></a>
<a name="line-65"></a>
<a name="line-66"></a><a name="outputFoldM"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-67"></a><span class='hs-comment'>-- | A side-effecting fold over an 'OutputStream', as a stream transformer.</span>
<a name="line-68"></a><span class='hs-comment'>--</span>
<a name="line-69"></a><span class='hs-comment'>-- The IO action returned by 'outputFoldM' can be used to fetch the updated</span>
<a name="line-70"></a><span class='hs-comment'>-- seed value. Example:</span>
<a name="line-71"></a><span class='hs-comment'>--</span>
<a name="line-72"></a><span class='hs-comment'>-- @</span>
<a name="line-73"></a><span class='hs-comment'>-- ghci&gt; is &lt;- Streams.'System.IO.Streams.List.fromList' [1, 2, 3::Int]</span>
<a name="line-74"></a><span class='hs-comment'>-- ghci&gt; (os, getList) &lt;- Streams.'System.IO.Streams.List.listOutputStream'</span>
<a name="line-75"></a><span class='hs-comment'>-- ghci&gt; (os', getSeed) \&lt;- Streams.'outputFoldM' (\\x y -&gt; return (x+y)) 0 os</span>
<a name="line-76"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.connect' is os'</span>
<a name="line-77"></a><span class='hs-comment'>-- ghci&gt; getList</span>
<a name="line-78"></a><span class='hs-comment'>-- [1,2,3]</span>
<a name="line-79"></a><span class='hs-comment'>-- ghci&gt; getSeed</span>
<a name="line-80"></a><span class='hs-comment'>-- 6</span>
<a name="line-81"></a><span class='hs-comment'>-- @</span>
<a name="line-82"></a><span class='hs-definition'>outputFoldM</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>           <span class='hs-comment'>-- ^ fold function</span>
<a name="line-83"></a>            <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span>                          <span class='hs-comment'>-- ^ initial seed</span>
<a name="line-84"></a>            <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>OutputStream</span> <span class='hs-varid'>b</span>             <span class='hs-comment'>-- ^ output stream</span>
<a name="line-85"></a>            <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>OutputStream</span> <span class='hs-varid'>b</span><span class='hs-layout'>,</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>  <span class='hs-comment'>-- ^ returns a new stream as well as</span>
<a name="line-86"></a>                                          <span class='hs-comment'>-- an IO action to fetch the updated</span>
<a name="line-87"></a>                                          <span class='hs-comment'>-- seed value.</span>
<a name="line-88"></a><span class='hs-definition'>outputFoldM</span> <span class='hs-varid'>f</span> <span class='hs-varid'>initial</span> <span class='hs-varid'>stream</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-89"></a>    <span class='hs-varid'>ref</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newIORef</span> <span class='hs-varid'>initial</span>
<a name="line-90"></a>    <span class='hs-varid'>os</span>  <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>makeOutputStream</span> <span class='hs-layout'>(</span><span class='hs-varid'>wr</span> <span class='hs-varid'>ref</span><span class='hs-layout'>)</span>
<a name="line-91"></a>    <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>os</span><span class='hs-layout'>,</span> <span class='hs-varid'>fetch</span> <span class='hs-varid'>ref</span><span class='hs-layout'>)</span>
<a name="line-92"></a>
<a name="line-93"></a>  <span class='hs-keyword'>where</span>
<a name="line-94"></a>    <span class='hs-varid'>wr</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>Nothing</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>write</span> <span class='hs-conid'>Nothing</span> <span class='hs-varid'>stream</span>
<a name="line-95"></a>    <span class='hs-varid'>wr</span> <span class='hs-varid'>ref</span> <span class='hs-varid'>mb</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-96"></a>        <span class='hs-varop'>!</span><span class='hs-varid'>z</span>  <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>readIORef</span> <span class='hs-varid'>ref</span>
<a name="line-97"></a>        <span class='hs-varop'>!</span><span class='hs-varid'>z'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>f</span> <span class='hs-varid'>z</span> <span class='hs-varid'>x</span>
<a name="line-98"></a>        <span class='hs-varid'>writeIORef</span> <span class='hs-varid'>ref</span> <span class='hs-varid'>z'</span>
<a name="line-99"></a>        <span class='hs-varid'>write</span> <span class='hs-varid'>mb</span> <span class='hs-varid'>stream</span>
<a name="line-100"></a>
<a name="line-101"></a>    <span class='hs-varid'>fetch</span> <span class='hs-varid'>ref</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>atomicModifyIORef</span> <span class='hs-varid'>ref</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>initial</span><span class='hs-layout'>,</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span>
<a name="line-102"></a>
<a name="line-103"></a>
<a name="line-104"></a><a name="inputFoldM"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-105"></a><span class='hs-comment'>-- | A side-effecting fold over an 'InputStream', as a stream transformer.</span>
<a name="line-106"></a><span class='hs-comment'>--</span>
<a name="line-107"></a><span class='hs-comment'>-- The IO action returned by 'inputFoldM' can be used to fetch the updated seed</span>
<a name="line-108"></a><span class='hs-comment'>-- value. Example:</span>
<a name="line-109"></a><span class='hs-comment'>--</span>
<a name="line-110"></a><span class='hs-comment'>-- @</span>
<a name="line-111"></a><span class='hs-comment'>-- ghci&gt; is &lt;- Streams.'System.IO.Streams.List.fromList' [1, 2, 3::Int]</span>
<a name="line-112"></a><span class='hs-comment'>-- ghci&gt; (is', getSeed) \&lt;- Streams.'inputFoldM' (\\x y -&gt; return (x+y)) 0 is</span>
<a name="line-113"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.List.toList' is'</span>
<a name="line-114"></a><span class='hs-comment'>-- [1,2,3]</span>
<a name="line-115"></a><span class='hs-comment'>-- ghci&gt; getSeed</span>
<a name="line-116"></a><span class='hs-comment'>-- 6</span>
<a name="line-117"></a><span class='hs-comment'>-- @</span>
<a name="line-118"></a><span class='hs-definition'>inputFoldM</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>          <span class='hs-comment'>-- ^ fold function</span>
<a name="line-119"></a>           <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span>                         <span class='hs-comment'>-- ^ initial seed</span>
<a name="line-120"></a>           <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>b</span>             <span class='hs-comment'>-- ^ input stream</span>
<a name="line-121"></a>           <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>b</span><span class='hs-layout'>,</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>  <span class='hs-comment'>-- ^ returns a new stream as well as an</span>
<a name="line-122"></a>                                        <span class='hs-comment'>-- IO action to fetch the updated seed</span>
<a name="line-123"></a>                                        <span class='hs-comment'>-- value.</span>
<a name="line-124"></a><span class='hs-definition'>inputFoldM</span> <span class='hs-varid'>f</span> <span class='hs-varid'>initial</span> <span class='hs-varid'>stream</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-125"></a>    <span class='hs-varid'>ref</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newIORef</span> <span class='hs-varid'>initial</span>
<a name="line-126"></a>    <span class='hs-varid'>is</span>  <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>makeInputStream</span> <span class='hs-layout'>(</span><span class='hs-varid'>rd</span> <span class='hs-varid'>ref</span><span class='hs-layout'>)</span>
<a name="line-127"></a>    <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>is</span><span class='hs-layout'>,</span> <span class='hs-varid'>fetch</span> <span class='hs-varid'>ref</span><span class='hs-layout'>)</span>
<a name="line-128"></a>
<a name="line-129"></a>  <span class='hs-keyword'>where</span>
<a name="line-130"></a>    <span class='hs-varid'>twiddle</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span>
<a name="line-131"></a>
<a name="line-132"></a>    <span class='hs-varid'>twiddle</span> <span class='hs-varid'>ref</span> <span class='hs-varid'>mb</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-133"></a>        <span class='hs-varop'>!</span><span class='hs-varid'>z</span>  <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>readIORef</span> <span class='hs-varid'>ref</span>
<a name="line-134"></a>        <span class='hs-varop'>!</span><span class='hs-varid'>z'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>f</span> <span class='hs-varid'>z</span> <span class='hs-varid'>x</span>
<a name="line-135"></a>        <span class='hs-varid'>writeIORef</span> <span class='hs-varid'>ref</span> <span class='hs-varid'>z'</span>
<a name="line-136"></a>        <span class='hs-varid'>return</span> <span class='hs-varid'>mb</span>
<a name="line-137"></a>
<a name="line-138"></a>    <span class='hs-varid'>rd</span> <span class='hs-varid'>ref</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>stream</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>twiddle</span> <span class='hs-varid'>ref</span>
<a name="line-139"></a>
<a name="line-140"></a>    <span class='hs-varid'>fetch</span> <span class='hs-varid'>ref</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>atomicModifyIORef</span> <span class='hs-varid'>ref</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>initial</span><span class='hs-layout'>,</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span>
<a name="line-141"></a>
<a name="line-142"></a>
<a name="line-143"></a><a name="fold"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-144"></a><span class='hs-comment'>-- | A left fold over an input stream. The input stream is fully consumed. See</span>
<a name="line-145"></a><span class='hs-comment'>-- 'Prelude.foldl'.</span>
<a name="line-146"></a><span class='hs-comment'>--</span>
<a name="line-147"></a><span class='hs-comment'>-- Example:</span>
<a name="line-148"></a><span class='hs-comment'>--</span>
<a name="line-149"></a><span class='hs-comment'>-- @</span>
<a name="line-150"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.fromList' [1..10] &gt;&gt;= Streams.'fold' (+) 0</span>
<a name="line-151"></a><span class='hs-comment'>-- 55</span>
<a name="line-152"></a><span class='hs-comment'>-- @</span>
<a name="line-153"></a><span class='hs-definition'>fold</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>s</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>       <span class='hs-comment'>-- ^ fold function</span>
<a name="line-154"></a>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>s</span>                   <span class='hs-comment'>-- ^ initial seed</span>
<a name="line-155"></a>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span>       <span class='hs-comment'>-- ^ input stream</span>
<a name="line-156"></a>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>s</span>
<a name="line-157"></a><span class='hs-definition'>fold</span> <span class='hs-varid'>f</span> <span class='hs-varid'>seed</span> <span class='hs-varid'>stream</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>seed</span>
<a name="line-158"></a>  <span class='hs-keyword'>where</span>
<a name="line-159"></a>    <span class='hs-varid'>go</span> <span class='hs-varop'>!</span><span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>stream</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>go</span> <span class='hs-varop'>.</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-160"></a>
<a name="line-161"></a>
<a name="line-162"></a><a name="foldM"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-163"></a><span class='hs-comment'>-- | A side-effecting left fold over an input stream. The input stream is fully</span>
<a name="line-164"></a><span class='hs-comment'>-- consumed. See 'Prelude.foldl'.</span>
<a name="line-165"></a><span class='hs-comment'>--</span>
<a name="line-166"></a><span class='hs-comment'>-- Example:</span>
<a name="line-167"></a><span class='hs-comment'>--</span>
<a name="line-168"></a><span class='hs-comment'>-- @</span>
<a name="line-169"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.fromList' [1..10] &gt;&gt;= Streams.'foldM' (\x y -&gt; 'return' (x + y)) 0</span>
<a name="line-170"></a><span class='hs-comment'>-- 55</span>
<a name="line-171"></a><span class='hs-comment'>-- @</span>
<a name="line-172"></a><span class='hs-definition'>foldM</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>s</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>       <span class='hs-comment'>-- ^ fold function</span>
<a name="line-173"></a>      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>s</span>                      <span class='hs-comment'>-- ^ initial seed</span>
<a name="line-174"></a>      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span>          <span class='hs-comment'>-- ^ input stream</span>
<a name="line-175"></a>      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>s</span>
<a name="line-176"></a><span class='hs-definition'>foldM</span> <span class='hs-varid'>f</span> <span class='hs-varid'>seed</span> <span class='hs-varid'>stream</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>seed</span>
<a name="line-177"></a>  <span class='hs-keyword'>where</span>
<a name="line-178"></a>    <span class='hs-varid'>go</span> <span class='hs-varop'>!</span><span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>stream</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>go</span> <span class='hs-varop'>=&lt;&lt;</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-179"></a>
<a name="line-180"></a>
<a name="line-181"></a><a name="any"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-182"></a><span class='hs-comment'>-- | @any predicate stream@ returns 'True' if any element in @stream@ matches</span>
<a name="line-183"></a><span class='hs-comment'>-- the predicate.</span>
<a name="line-184"></a><span class='hs-comment'>--</span>
<a name="line-185"></a><span class='hs-comment'>-- 'any' consumes as few elements as possible, ending consumption if an element</span>
<a name="line-186"></a><span class='hs-comment'>-- satisfies the predicate.</span>
<a name="line-187"></a><span class='hs-comment'>--</span>
<a name="line-188"></a><span class='hs-comment'>-- @</span>
<a name="line-189"></a><span class='hs-comment'>-- ghci&gt; is &lt;- Streams.'System.IO.Streams.List.fromList' [1, 2, 3]</span>
<a name="line-190"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.Combinators.any' (&gt; 0) is    -- Consumes one element</span>
<a name="line-191"></a><span class='hs-comment'>-- True</span>
<a name="line-192"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.read' is</span>
<a name="line-193"></a><span class='hs-comment'>-- Just 2</span>
<a name="line-194"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.Combinators.any' even is     -- Only 3 remains</span>
<a name="line-195"></a><span class='hs-comment'>-- False</span>
<a name="line-196"></a><span class='hs-comment'>-- @</span>
<a name="line-197"></a><span class='hs-definition'>any</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>Bool</span>
<a name="line-198"></a><span class='hs-definition'>any</span> <span class='hs-varid'>predicate</span> <span class='hs-varid'>stream</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span>
<a name="line-199"></a>  <span class='hs-keyword'>where</span>
<a name="line-200"></a>    <span class='hs-varid'>go</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-201"></a>        <span class='hs-varid'>mElem</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>read</span> <span class='hs-varid'>stream</span>
<a name="line-202"></a>        <span class='hs-keyword'>case</span> <span class='hs-varid'>mElem</span> <span class='hs-keyword'>of</span>
<a name="line-203"></a>            <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-conid'>False</span>
<a name="line-204"></a>            <span class='hs-conid'>Just</span> <span class='hs-varid'>e</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>predicate</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>return</span> <span class='hs-conid'>True</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>go</span>
<a name="line-205"></a>
<a name="line-206"></a>
<a name="line-207"></a><a name="all"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-208"></a><span class='hs-comment'>-- | @all predicate stream@ returns 'True' if every element in @stream@ matches</span>
<a name="line-209"></a><span class='hs-comment'>-- the predicate.</span>
<a name="line-210"></a><span class='hs-comment'>--</span>
<a name="line-211"></a><span class='hs-comment'>-- 'all' consumes as few elements as possible, ending consumption if any element</span>
<a name="line-212"></a><span class='hs-comment'>-- fails the predicate.</span>
<a name="line-213"></a><span class='hs-comment'>--</span>
<a name="line-214"></a><span class='hs-comment'>-- @</span>
<a name="line-215"></a><span class='hs-comment'>-- ghci&gt; is &lt;- Streams.'System.IO.Streams.List.fromList' [1, 2, 3]</span>
<a name="line-216"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.Combinators.all' (&lt; 0) is    -- Consumes one element</span>
<a name="line-217"></a><span class='hs-comment'>-- False</span>
<a name="line-218"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.read' is</span>
<a name="line-219"></a><span class='hs-comment'>-- Just 2</span>
<a name="line-220"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.Combinators.all' odd is      -- Only 3 remains</span>
<a name="line-221"></a><span class='hs-comment'>-- True</span>
<a name="line-222"></a><span class='hs-comment'>-- @</span>
<a name="line-223"></a><span class='hs-definition'>all</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>Bool</span>
<a name="line-224"></a><span class='hs-definition'>all</span> <span class='hs-varid'>predicate</span> <span class='hs-varid'>stream</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span>
<a name="line-225"></a>  <span class='hs-keyword'>where</span>
<a name="line-226"></a>    <span class='hs-varid'>go</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-227"></a>        <span class='hs-varid'>mElem</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>read</span> <span class='hs-varid'>stream</span>
<a name="line-228"></a>        <span class='hs-keyword'>case</span> <span class='hs-varid'>mElem</span> <span class='hs-keyword'>of</span>
<a name="line-229"></a>            <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-conid'>True</span>
<a name="line-230"></a>            <span class='hs-conid'>Just</span> <span class='hs-varid'>e</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>predicate</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>go</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>return</span> <span class='hs-conid'>False</span>
<a name="line-231"></a>
<a name="line-232"></a>
<a name="line-233"></a><a name="maximum"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-234"></a><span class='hs-comment'>-- | @maximum stream@ returns the greatest element in @stream@ or 'Nothing' if</span>
<a name="line-235"></a><span class='hs-comment'>-- the stream is empty.</span>
<a name="line-236"></a><span class='hs-comment'>--</span>
<a name="line-237"></a><span class='hs-comment'>-- 'maximum' consumes the entire stream.</span>
<a name="line-238"></a><span class='hs-comment'>--</span>
<a name="line-239"></a><span class='hs-comment'>-- @</span>
<a name="line-240"></a><span class='hs-comment'>-- ghci&gt; is &lt;- Streams.'System.IO.Streams.List.fromList' [1, 2, 3]</span>
<a name="line-241"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.Combinators.maximum' is</span>
<a name="line-242"></a><span class='hs-comment'>-- 3</span>
<a name="line-243"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.read' is     -- The stream is now empty</span>
<a name="line-244"></a><span class='hs-comment'>-- Nothing</span>
<a name="line-245"></a><span class='hs-comment'>-- @</span>
<a name="line-246"></a><span class='hs-definition'>maximum</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>Maybe</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-247"></a><span class='hs-definition'>maximum</span> <span class='hs-varid'>stream</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-248"></a>    <span class='hs-varid'>mElem0</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>read</span> <span class='hs-varid'>stream</span>
<a name="line-249"></a>    <span class='hs-keyword'>case</span> <span class='hs-varid'>mElem0</span> <span class='hs-keyword'>of</span>
<a name="line-250"></a>        <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span>
<a name="line-251"></a>        <span class='hs-conid'>Just</span> <span class='hs-varid'>e</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e</span>
<a name="line-252"></a>  <span class='hs-keyword'>where</span>
<a name="line-253"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>oldElem</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-254"></a>        <span class='hs-varid'>mElem</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>read</span> <span class='hs-varid'>stream</span>
<a name="line-255"></a>        <span class='hs-keyword'>case</span> <span class='hs-varid'>mElem</span> <span class='hs-keyword'>of</span>
<a name="line-256"></a>            <span class='hs-conid'>Nothing</span>      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>oldElem</span><span class='hs-layout'>)</span>
<a name="line-257"></a>            <span class='hs-conid'>Just</span> <span class='hs-varid'>newElem</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>max</span> <span class='hs-varid'>oldElem</span> <span class='hs-varid'>newElem</span><span class='hs-layout'>)</span>
<a name="line-258"></a>
<a name="line-259"></a>
<a name="line-260"></a><a name="minimum"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-261"></a><span class='hs-comment'>-- | @minimum stream@ returns the greatest element in @stream@</span>
<a name="line-262"></a><span class='hs-comment'>--</span>
<a name="line-263"></a><span class='hs-comment'>-- 'minimum' consumes the entire stream.</span>
<a name="line-264"></a><span class='hs-comment'>--</span>
<a name="line-265"></a><span class='hs-comment'>-- @</span>
<a name="line-266"></a><span class='hs-comment'>-- ghci&gt; is &lt;- Streams.'System.IO.Streams.List.fromList' [1, 2, 3]</span>
<a name="line-267"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.Combinators.minimum' is</span>
<a name="line-268"></a><span class='hs-comment'>-- 1</span>
<a name="line-269"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.read' is    -- The stream is now empty</span>
<a name="line-270"></a><span class='hs-comment'>-- Nothing</span>
<a name="line-271"></a><span class='hs-comment'>-- @</span>
<a name="line-272"></a><span class='hs-definition'>minimum</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>Maybe</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-273"></a><span class='hs-definition'>minimum</span> <span class='hs-varid'>stream</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-274"></a>    <span class='hs-varid'>mElem0</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>read</span> <span class='hs-varid'>stream</span>
<a name="line-275"></a>    <span class='hs-keyword'>case</span> <span class='hs-varid'>mElem0</span> <span class='hs-keyword'>of</span>
<a name="line-276"></a>        <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span>
<a name="line-277"></a>        <span class='hs-conid'>Just</span> <span class='hs-varid'>e</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e</span>
<a name="line-278"></a>  <span class='hs-keyword'>where</span>
<a name="line-279"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>oldElem</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-280"></a>        <span class='hs-varid'>mElem</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>read</span> <span class='hs-varid'>stream</span>
<a name="line-281"></a>        <span class='hs-keyword'>case</span> <span class='hs-varid'>mElem</span> <span class='hs-keyword'>of</span>
<a name="line-282"></a>            <span class='hs-conid'>Nothing</span>      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>oldElem</span><span class='hs-layout'>)</span>
<a name="line-283"></a>            <span class='hs-conid'>Just</span> <span class='hs-varid'>newElem</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>go</span> <span class='hs-layout'>(</span><span class='hs-varid'>min</span> <span class='hs-varid'>oldElem</span> <span class='hs-varid'>newElem</span><span class='hs-layout'>)</span>
<a name="line-284"></a>
<a name="line-285"></a>
<a name="line-286"></a><a name="unfoldM"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-287"></a><span class='hs-comment'>-- | @unfoldM f seed@ builds an 'InputStream' from successively applying @f@ to</span>
<a name="line-288"></a><span class='hs-comment'>-- the @seed@ value, continuing if @f@ produces 'Just' and halting on</span>
<a name="line-289"></a><span class='hs-comment'>-- 'Nothing'.</span>
<a name="line-290"></a><span class='hs-comment'>--</span>
<a name="line-291"></a><span class='hs-comment'>-- @</span>
<a name="line-292"></a><span class='hs-comment'>-- ghci&gt; is \&lt;- Streams.'System.IO.Streams.Combinators.unfoldM' (\n -&gt; return $ if n &lt; 3 then Just (n, n + 1) else Nothing) 0</span>
<a name="line-293"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.List.toList' is</span>
<a name="line-294"></a><span class='hs-comment'>-- [0,1,2]</span>
<a name="line-295"></a><span class='hs-comment'>-- @</span>
<a name="line-296"></a><span class='hs-definition'>unfoldM</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-297"></a><span class='hs-definition'>unfoldM</span> <span class='hs-varid'>f</span> <span class='hs-varid'>seed</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fromGenerator</span> <span class='hs-layout'>(</span><span class='hs-varid'>go</span> <span class='hs-varid'>seed</span><span class='hs-layout'>)</span>
<a name="line-298"></a>  <span class='hs-keyword'>where</span>
<a name="line-299"></a>    <span class='hs-varid'>go</span> <span class='hs-varid'>oldSeed</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-300"></a>       <span class='hs-varid'>m</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>liftIO</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span> <span class='hs-varid'>oldSeed</span><span class='hs-layout'>)</span>
<a name="line-301"></a>       <span class='hs-keyword'>case</span> <span class='hs-varid'>m</span> <span class='hs-keyword'>of</span>
<a name="line-302"></a>           <span class='hs-conid'>Nothing</span>           <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>()</span>
<a name="line-303"></a>           <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>newSeed</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-304"></a>               <span class='hs-varid'>yield</span> <span class='hs-varid'>a</span>
<a name="line-305"></a>               <span class='hs-varid'>go</span> <span class='hs-varid'>newSeed</span>
<a name="line-306"></a>
<a name="line-307"></a><a name="map"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-308"></a><span class='hs-comment'>-- | Maps a pure function over an 'InputStream'.</span>
<a name="line-309"></a><span class='hs-comment'>--</span>
<a name="line-310"></a><span class='hs-comment'>-- @map f s@ passes all output from @s@ through the function @f@.</span>
<a name="line-311"></a><span class='hs-comment'>--</span>
<a name="line-312"></a><span class='hs-comment'>-- Satisfies the following laws:</span>
<a name="line-313"></a><span class='hs-comment'>--</span>
<a name="line-314"></a><span class='hs-comment'>-- @</span>
<a name="line-315"></a><span class='hs-comment'>-- Streams.'map' (g . f) === Streams.'map' f &gt;=&gt; Streams.'map' g</span>
<a name="line-316"></a><span class='hs-comment'>-- Streams.'map' 'id' === Streams.'makeInputStream' . Streams.'read'</span>
<a name="line-317"></a><span class='hs-comment'>-- @</span>
<a name="line-318"></a><span class='hs-definition'>map</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span>
<a name="line-319"></a><span class='hs-definition'>map</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeInputStream</span> <span class='hs-varid'>g</span>
<a name="line-320"></a>  <span class='hs-keyword'>where</span>
<a name="line-321"></a>    <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>s</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>return</span> <span class='hs-varop'>.</span> <span class='hs-varid'>fmap</span> <span class='hs-varid'>f</span>
<a name="line-322"></a>
<a name="line-323"></a>
<a name="line-324"></a><a name="mapM"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-325"></a><span class='hs-comment'>-- | Maps an impure function over an 'InputStream'.</span>
<a name="line-326"></a><span class='hs-comment'>--</span>
<a name="line-327"></a><span class='hs-comment'>-- @mapM f s@ passes all output from @s@ through the IO action @f@.</span>
<a name="line-328"></a><span class='hs-comment'>--</span>
<a name="line-329"></a><span class='hs-comment'>-- Satisfies the following laws:</span>
<a name="line-330"></a><span class='hs-comment'>--</span>
<a name="line-331"></a><span class='hs-comment'>-- @</span>
<a name="line-332"></a><span class='hs-comment'>-- Streams.'mapM' (f &gt;=&gt; g) === Streams.'mapM' f &gt;=&gt; Streams.'mapM' g</span>
<a name="line-333"></a><span class='hs-comment'>-- Streams.'mapM' 'return' === Streams.'makeInputStream' . Streams.'read'</span>
<a name="line-334"></a><span class='hs-comment'>-- @</span>
<a name="line-335"></a><span class='hs-comment'>--</span>
<a name="line-336"></a><span class='hs-definition'>mapM</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span>
<a name="line-337"></a><span class='hs-definition'>mapM</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeInputStream</span> <span class='hs-varid'>g</span>
<a name="line-338"></a>  <span class='hs-keyword'>where</span>
<a name="line-339"></a>    <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-340"></a>        <span class='hs-varid'>mb</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>read</span> <span class='hs-varid'>s</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span>
<a name="line-341"></a>                               <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>liftM</span> <span class='hs-conid'>Just</span> <span class='hs-varop'>$</span> <span class='hs-varid'>f</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span>
<a name="line-342"></a>
<a name="line-343"></a>        <span class='hs-varid'>return</span> <span class='hs-varid'>mb</span>
<a name="line-344"></a>
<a name="line-345"></a>
<a name="line-346"></a><a name="mapM_"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-347"></a><span class='hs-comment'>-- | Maps a side effect over an 'InputStream'.</span>
<a name="line-348"></a><span class='hs-comment'>--</span>
<a name="line-349"></a><span class='hs-comment'>-- @mapM_ f s@ produces a new input stream that passes all output from @s@</span>
<a name="line-350"></a><span class='hs-comment'>-- through the side-effecting IO action @f@.</span>
<a name="line-351"></a><span class='hs-comment'>--</span>
<a name="line-352"></a><span class='hs-comment'>-- Example:</span>
<a name="line-353"></a><span class='hs-comment'>--</span>
<a name="line-354"></a><span class='hs-comment'>-- @</span>
<a name="line-355"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.fromList' [1,2,3] &gt;&gt;=</span>
<a name="line-356"></a><span class='hs-comment'>--       Streams.'mapM_' ('putStrLn' . 'show' . (*2)) &gt;&gt;=</span>
<a name="line-357"></a><span class='hs-comment'>--       Streams.'System.IO.Streams.toList'</span>
<a name="line-358"></a><span class='hs-comment'>-- 2</span>
<a name="line-359"></a><span class='hs-comment'>-- 4</span>
<a name="line-360"></a><span class='hs-comment'>-- 6</span>
<a name="line-361"></a><span class='hs-comment'>-- [1,2,3]</span>
<a name="line-362"></a><span class='hs-comment'>-- @</span>
<a name="line-363"></a><span class='hs-comment'>--</span>
<a name="line-364"></a><span class='hs-definition'>mapM_</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-365"></a><span class='hs-definition'>mapM_</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeInputStream</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span>
<a name="line-366"></a>    <span class='hs-varid'>mb</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>read</span> <span class='hs-varid'>s</span>
<a name="line-367"></a>    <span class='hs-keyword'>_</span>  <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>void</span> <span class='hs-varop'>.</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span> <span class='hs-varid'>mb</span>
<a name="line-368"></a>    <span class='hs-varid'>return</span> <span class='hs-varid'>mb</span>
<a name="line-369"></a>
<a name="line-370"></a>
<a name="line-371"></a><a name="contramap"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-372"></a><span class='hs-comment'>-- | Contravariant counterpart to 'map'.</span>
<a name="line-373"></a><span class='hs-comment'>--</span>
<a name="line-374"></a><span class='hs-comment'>-- @contramap f s@ passes all input to @s@ through the function @f@.</span>
<a name="line-375"></a><span class='hs-comment'>--</span>
<a name="line-376"></a><span class='hs-comment'>-- Satisfies the following laws:</span>
<a name="line-377"></a><span class='hs-comment'>--</span>
<a name="line-378"></a><span class='hs-comment'>-- @</span>
<a name="line-379"></a><span class='hs-comment'>-- Streams.'contramap' (g . f) === Streams.'contramap' g &gt;=&gt; Streams.'contramap' f</span>
<a name="line-380"></a><span class='hs-comment'>-- Streams.'contramap' 'id' === 'return'</span>
<a name="line-381"></a><span class='hs-comment'>-- @</span>
<a name="line-382"></a><span class='hs-definition'>contramap</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>OutputStream</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-383"></a><span class='hs-definition'>contramap</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeOutputStream</span> <span class='hs-varop'>$</span> <span class='hs-varid'>flip</span> <span class='hs-varid'>write</span> <span class='hs-varid'>s</span> <span class='hs-varop'>.</span> <span class='hs-varid'>fmap</span> <span class='hs-varid'>f</span>
<a name="line-384"></a>
<a name="line-385"></a>
<a name="line-386"></a><a name="contramapM"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-387"></a><span class='hs-comment'>-- | Contravariant counterpart to 'mapM'.</span>
<a name="line-388"></a><span class='hs-comment'>--</span>
<a name="line-389"></a><span class='hs-comment'>-- @contramapM f s@ passes all input to @s@ through the IO action @f@</span>
<a name="line-390"></a><span class='hs-comment'>--</span>
<a name="line-391"></a><span class='hs-comment'>-- Satisfies the following laws:</span>
<a name="line-392"></a><span class='hs-comment'>--</span>
<a name="line-393"></a><span class='hs-comment'>-- @</span>
<a name="line-394"></a><span class='hs-comment'>-- Streams.'contramapM' (f &gt;=&gt; g) = Streams.'contramapM' g &gt;=&gt; Streams.'contramapM' f</span>
<a name="line-395"></a><span class='hs-comment'>-- Streams.'contramapM' 'return' = 'return'</span>
<a name="line-396"></a><span class='hs-comment'>-- @</span>
<a name="line-397"></a><span class='hs-definition'>contramapM</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>OutputStream</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-398"></a><span class='hs-definition'>contramapM</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeOutputStream</span> <span class='hs-varid'>g</span>
<a name="line-399"></a>  <span class='hs-keyword'>where</span>
<a name="line-400"></a>    <span class='hs-varid'>g</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>write</span> <span class='hs-conid'>Nothing</span> <span class='hs-varid'>s</span>
<a name="line-401"></a>
<a name="line-402"></a>    <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-403"></a>        <span class='hs-varop'>!</span><span class='hs-varid'>y</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>f</span> <span class='hs-varid'>x</span>
<a name="line-404"></a>        <span class='hs-varid'>write</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span> <span class='hs-varid'>s</span>
<a name="line-405"></a>
<a name="line-406"></a>
<a name="line-407"></a><a name="contramapM_"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-408"></a><span class='hs-comment'>-- | Equivalent to 'mapM_' for output.</span>
<a name="line-409"></a><span class='hs-comment'>--</span>
<a name="line-410"></a><span class='hs-comment'>-- @contramapM f s@ passes all input to @s@ through the side-effecting IO</span>
<a name="line-411"></a><span class='hs-comment'>-- action @f@.</span>
<a name="line-412"></a><span class='hs-comment'>--</span>
<a name="line-413"></a><span class='hs-definition'>contramapM_</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-414"></a><span class='hs-definition'>contramapM_</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeOutputStream</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>mb</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-415"></a>    <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>void</span> <span class='hs-varop'>.</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span> <span class='hs-varid'>mb</span>
<a name="line-416"></a>    <span class='hs-varid'>write</span> <span class='hs-varid'>mb</span> <span class='hs-varid'>s</span>
<a name="line-417"></a>
<a name="line-418"></a>
<a name="line-419"></a><a name="skipToEof"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-420"></a><span class='hs-comment'>-- | Drives an 'InputStream' to end-of-stream, discarding all of the yielded</span>
<a name="line-421"></a><span class='hs-comment'>-- values.</span>
<a name="line-422"></a><span class='hs-definition'>skipToEof</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span>
<a name="line-423"></a><span class='hs-definition'>skipToEof</span> <span class='hs-varid'>str</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span>
<a name="line-424"></a>  <span class='hs-keyword'>where</span>
<a name="line-425"></a>    <span class='hs-varid'>go</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>str</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>const</span> <span class='hs-varid'>go</span><span class='hs-layout'>)</span>
<a name="line-426"></a><span class='hs-comment'>{-# INLINE skipToEof #-}</span>
<a name="line-427"></a>
<a name="line-428"></a>
<a name="line-429"></a><a name="filterM"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-430"></a><span class='hs-comment'>-- | Drops chunks from an input stream if they fail to match a given filter</span>
<a name="line-431"></a><span class='hs-comment'>-- predicate. See 'Prelude.filter'.</span>
<a name="line-432"></a><span class='hs-comment'>--</span>
<a name="line-433"></a><span class='hs-comment'>-- Items pushed back to the returned stream are propagated back upstream.</span>
<a name="line-434"></a><span class='hs-comment'>--</span>
<a name="line-435"></a><span class='hs-comment'>-- Example:</span>
<a name="line-436"></a><span class='hs-comment'>--</span>
<a name="line-437"></a><span class='hs-comment'>-- @</span>
<a name="line-438"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.fromList' [\"the\", \"quick\", \"brown\", \"fox\"] &gt;&gt;=</span>
<a name="line-439"></a><span class='hs-comment'>--       Streams.'filterM' ('return' . (/= \"brown\")) &gt;&gt;= Streams.'System.IO.Streams.toList'</span>
<a name="line-440"></a><span class='hs-comment'>-- [\"the\",\"quick\",\"fox\"]</span>
<a name="line-441"></a><span class='hs-comment'>-- @</span>
<a name="line-442"></a><span class='hs-definition'>filterM</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>Bool</span><span class='hs-layout'>)</span>
<a name="line-443"></a>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span>
<a name="line-444"></a>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-445"></a><span class='hs-definition'>filterM</span> <span class='hs-varid'>p</span> <span class='hs-varid'>src</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>prod</span> <span class='hs-varid'>pb</span>
<a name="line-446"></a>  <span class='hs-keyword'>where</span>
<a name="line-447"></a>    <span class='hs-varid'>prod</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>src</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>maybe</span> <span class='hs-varid'>eof</span> <span class='hs-varid'>chunk</span>
<a name="line-448"></a>
<a name="line-449"></a>    <span class='hs-varid'>chunk</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-450"></a>        <span class='hs-varid'>b</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>p</span> <span class='hs-varid'>s</span>
<a name="line-451"></a>        <span class='hs-keyword'>if</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>s</span>
<a name="line-452"></a>             <span class='hs-keyword'>else</span> <span class='hs-varid'>prod</span>
<a name="line-453"></a>
<a name="line-454"></a>    <span class='hs-varid'>eof</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span>
<a name="line-455"></a>
<a name="line-456"></a>    <span class='hs-varid'>pb</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unRead</span> <span class='hs-varid'>s</span> <span class='hs-varid'>src</span>
<a name="line-457"></a>
<a name="line-458"></a>
<a name="line-459"></a><a name="filter"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-460"></a><span class='hs-comment'>-- | Drops chunks from an input stream if they fail to match a given filter</span>
<a name="line-461"></a><span class='hs-comment'>-- predicate. See 'Prelude.filter'.</span>
<a name="line-462"></a><span class='hs-comment'>--</span>
<a name="line-463"></a><span class='hs-comment'>-- Items pushed back to the returned stream are propagated back upstream.</span>
<a name="line-464"></a><span class='hs-comment'>--</span>
<a name="line-465"></a><span class='hs-comment'>-- Example:</span>
<a name="line-466"></a><span class='hs-comment'>--</span>
<a name="line-467"></a><span class='hs-comment'>-- @</span>
<a name="line-468"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.fromList' [\"the\", \"quick\", \"brown\", \"fox\"] &gt;&gt;=</span>
<a name="line-469"></a><span class='hs-comment'>--       Streams.'filter' (/= \"brown\") &gt;&gt;= Streams.'System.IO.Streams.toList'</span>
<a name="line-470"></a><span class='hs-comment'>-- [\"the\",\"quick\",\"fox\"]</span>
<a name="line-471"></a><span class='hs-comment'>-- @</span>
<a name="line-472"></a><span class='hs-definition'>filter</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span><span class='hs-layout'>)</span>
<a name="line-473"></a>       <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span>
<a name="line-474"></a>       <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-475"></a><span class='hs-definition'>filter</span> <span class='hs-varid'>p</span> <span class='hs-varid'>src</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>prod</span> <span class='hs-varid'>pb</span>
<a name="line-476"></a>  <span class='hs-keyword'>where</span>
<a name="line-477"></a>    <span class='hs-varid'>prod</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>src</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>maybe</span> <span class='hs-varid'>eof</span> <span class='hs-varid'>chunk</span>
<a name="line-478"></a>
<a name="line-479"></a>    <span class='hs-varid'>chunk</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-480"></a>        <span class='hs-keyword'>let</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>p</span> <span class='hs-varid'>s</span>
<a name="line-481"></a>        <span class='hs-keyword'>if</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>s</span>
<a name="line-482"></a>             <span class='hs-keyword'>else</span> <span class='hs-varid'>prod</span>
<a name="line-483"></a>
<a name="line-484"></a>    <span class='hs-varid'>eof</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span>
<a name="line-485"></a>    <span class='hs-varid'>pb</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unRead</span> <span class='hs-varid'>s</span> <span class='hs-varid'>src</span>
<a name="line-486"></a>
<a name="line-487"></a>
<a name="line-488"></a><a name="intersperse"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-489"></a><span class='hs-comment'>-- | The function @intersperse v s@ wraps the 'OutputStream' @s@, creating a</span>
<a name="line-490"></a><span class='hs-comment'>-- new output stream that writes its input to @s@ interspersed with the</span>
<a name="line-491"></a><span class='hs-comment'>-- provided value @v@. See 'Data.List.intersperse'.</span>
<a name="line-492"></a><span class='hs-comment'>--</span>
<a name="line-493"></a><span class='hs-comment'>-- Example:</span>
<a name="line-494"></a><span class='hs-comment'>--</span>
<a name="line-495"></a><span class='hs-comment'>-- @</span>
<a name="line-496"></a><span class='hs-comment'>-- ghci&gt; import Control.Monad ((&gt;=&gt;))</span>
<a name="line-497"></a><span class='hs-comment'>-- ghci&gt; is &lt;- Streams.'System.IO.Streams.List.fromList' [\"nom\", \"nom\", \"nom\"::'ByteString']</span>
<a name="line-498"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.List.outputToList' (Streams.'intersperse' \"burp!\" &gt;=&gt; Streams.'System.IO.Streams.connect' is)</span>
<a name="line-499"></a><span class='hs-comment'>-- [\"nom\",\"burp!\",\"nom\",\"burp!\",\"nom\"]</span>
<a name="line-500"></a><span class='hs-comment'>-- @</span>
<a name="line-501"></a><span class='hs-definition'>intersperse</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-502"></a><span class='hs-definition'>intersperse</span> <span class='hs-varid'>sep</span> <span class='hs-varid'>os</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>newIORef</span> <span class='hs-conid'>False</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>makeOutputStream</span> <span class='hs-varop'>.</span> <span class='hs-varid'>f</span>
<a name="line-503"></a>  <span class='hs-keyword'>where</span>
<a name="line-504"></a>    <span class='hs-varid'>f</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>write</span> <span class='hs-conid'>Nothing</span> <span class='hs-varid'>os</span>
<a name="line-505"></a>    <span class='hs-varid'>f</span> <span class='hs-varid'>sendRef</span> <span class='hs-varid'>s</span>    <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-506"></a>        <span class='hs-varid'>b</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>readIORef</span> <span class='hs-varid'>sendRef</span>
<a name="line-507"></a>        <span class='hs-varid'>writeIORef</span> <span class='hs-varid'>sendRef</span> <span class='hs-conid'>True</span>
<a name="line-508"></a>        <span class='hs-varid'>when</span> <span class='hs-varid'>b</span> <span class='hs-varop'>$</span> <span class='hs-varid'>write</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>sep</span><span class='hs-layout'>)</span> <span class='hs-varid'>os</span>
<a name="line-509"></a>        <span class='hs-varid'>write</span> <span class='hs-varid'>s</span> <span class='hs-varid'>os</span>
<a name="line-510"></a>
<a name="line-511"></a>
<a name="line-512"></a><a name="zip"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-513"></a><span class='hs-comment'>-- | Combines two input streams. Continues yielding elements from both input</span>
<a name="line-514"></a><span class='hs-comment'>-- streams until one of them finishes.</span>
<a name="line-515"></a><span class='hs-definition'>zip</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-516"></a><span class='hs-definition'>zip</span> <span class='hs-varid'>src1</span> <span class='hs-varid'>src2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeInputStream</span> <span class='hs-varid'>src</span>
<a name="line-517"></a>  <span class='hs-keyword'>where</span>
<a name="line-518"></a>    <span class='hs-varid'>src</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>src1</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-layout'>(</span><span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-519"></a>            <span class='hs-varid'>read</span> <span class='hs-varid'>src2</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-layout'>(</span><span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>unRead</span> <span class='hs-varid'>a</span> <span class='hs-varid'>src1</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-520"></a>              <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>Just</span> <span class='hs-varop'>$!</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-521"></a>
<a name="line-522"></a>
<a name="line-523"></a><a name="zipWith"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-524"></a><span class='hs-comment'>-- | Combines two input streams using the supplied function. Continues yielding</span>
<a name="line-525"></a><span class='hs-comment'>-- elements from both input streams until one of them finishes.</span>
<a name="line-526"></a><span class='hs-definition'>zipWith</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span>
<a name="line-527"></a>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span>
<a name="line-528"></a>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>b</span>
<a name="line-529"></a>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span>
<a name="line-530"></a><span class='hs-definition'>zipWith</span> <span class='hs-varid'>f</span> <span class='hs-varid'>src1</span> <span class='hs-varid'>src2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeInputStream</span> <span class='hs-varid'>src</span>
<a name="line-531"></a>  <span class='hs-keyword'>where</span>
<a name="line-532"></a>    <span class='hs-varid'>src</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>src1</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-layout'>(</span><span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-533"></a>            <span class='hs-varid'>read</span> <span class='hs-varid'>src2</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-layout'>(</span><span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>unRead</span> <span class='hs-varid'>a</span> <span class='hs-varid'>src1</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-534"></a>              <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>Just</span> <span class='hs-varop'>$!</span> <span class='hs-varid'>f</span> <span class='hs-varid'>a</span> <span class='hs-varid'>b</span> <span class='hs-layout'>)</span> <span class='hs-layout'>)</span>
<a name="line-535"></a>
<a name="line-536"></a>
<a name="line-537"></a><a name="zipWithM"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-538"></a><span class='hs-comment'>-- | Combines two input streams using the supplied monadic function. Continues</span>
<a name="line-539"></a><span class='hs-comment'>-- yielding elements from both input streams until one of them finishes.</span>
<a name="line-540"></a><span class='hs-definition'>zipWithM</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span>
<a name="line-541"></a>         <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span>
<a name="line-542"></a>         <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>b</span>
<a name="line-543"></a>         <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span>
<a name="line-544"></a><span class='hs-definition'>zipWithM</span> <span class='hs-varid'>f</span> <span class='hs-varid'>src1</span> <span class='hs-varid'>src2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeInputStream</span> <span class='hs-varid'>src</span>
<a name="line-545"></a>  <span class='hs-keyword'>where</span>
<a name="line-546"></a>    <span class='hs-varid'>src</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>src1</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-layout'>(</span><span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-547"></a>            <span class='hs-varid'>read</span> <span class='hs-varid'>src2</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-layout'>(</span><span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>unRead</span> <span class='hs-varid'>a</span> <span class='hs-varid'>src1</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-548"></a>              <span class='hs-varid'>f</span> <span class='hs-varid'>a</span> <span class='hs-varid'>b</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>c</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>Just</span> <span class='hs-varop'>$!</span> <span class='hs-varid'>c</span> <span class='hs-layout'>)</span> <span class='hs-layout'>)</span>
<a name="line-549"></a>
<a name="line-550"></a>
<a name="line-551"></a><a name="filterOutput"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-552"></a><span class='hs-comment'>-- | Filters output to be sent to the given 'OutputStream' using a pure</span>
<a name="line-553"></a><span class='hs-comment'>-- function. See 'filter'.</span>
<a name="line-554"></a><span class='hs-comment'>--</span>
<a name="line-555"></a><span class='hs-comment'>-- Example:</span>
<a name="line-556"></a><span class='hs-comment'>--</span>
<a name="line-557"></a><span class='hs-comment'>-- @</span>
<a name="line-558"></a><span class='hs-comment'>-- ghci&gt; import qualified "Data.ByteString.Char8" as S</span>
<a name="line-559"></a><span class='hs-comment'>-- ghci&gt; os1 \&lt;- Streams.'System.IO.Streams.stdout' &gt;&gt;= Streams.'System.IO.Streams.unlines</span>
<a name="line-560"></a><span class='hs-comment'>-- ghci&gt; os2 \&lt;- os1 &gt;&gt;= Streams.'contramap' (S.pack . show) &gt;&gt;= Streams.'filterOutput' even</span>
<a name="line-561"></a><span class='hs-comment'>-- ghci&gt; Streams.'write' (Just 3) os2</span>
<a name="line-562"></a><span class='hs-comment'>-- ghci&gt; Streams.'write' (Just 4) os2</span>
<a name="line-563"></a><span class='hs-comment'>-- 4</span>
<a name="line-564"></a><span class='hs-comment'>-- @</span>
<a name="line-565"></a><span class='hs-comment'>{- Note: The example is a lie, because unlines has weird behavior -}</span>
<a name="line-566"></a><span class='hs-definition'>filterOutput</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-567"></a><span class='hs-definition'>filterOutput</span> <span class='hs-varid'>p</span> <span class='hs-varid'>output</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeOutputStream</span> <span class='hs-varid'>chunk</span>
<a name="line-568"></a>  <span class='hs-keyword'>where</span>
<a name="line-569"></a>    <span class='hs-varid'>chunk</span> <span class='hs-conid'>Nothing</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>write</span> <span class='hs-conid'>Nothing</span> <span class='hs-varid'>output</span>
<a name="line-570"></a>    <span class='hs-varid'>chunk</span> <span class='hs-varid'>ch</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>when</span> <span class='hs-layout'>(</span><span class='hs-varid'>p</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-varid'>write</span> <span class='hs-varid'>ch</span> <span class='hs-varid'>output</span>
<a name="line-571"></a>
<a name="line-572"></a>
<a name="line-573"></a><a name="filterOutputM"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-574"></a><span class='hs-comment'>-- | Filters output to be sent to the given 'OutputStream' using a predicate</span>
<a name="line-575"></a><span class='hs-comment'>-- function in IO. See 'filterM'.</span>
<a name="line-576"></a><span class='hs-comment'>--</span>
<a name="line-577"></a><span class='hs-comment'>-- Example:</span>
<a name="line-578"></a><span class='hs-comment'>--</span>
<a name="line-579"></a><span class='hs-comment'>-- @</span>
<a name="line-580"></a><span class='hs-comment'>-- ghci&gt; let check a = putStrLn a ("Allow " ++ show a ++ "?") &gt;&gt; readLn :: IO Bool</span>
<a name="line-581"></a><span class='hs-comment'>-- ghci&gt; import qualified Data.ByteString.Char8 as S</span>
<a name="line-582"></a><span class='hs-comment'>-- ghci&gt; os1 &lt;- Streams.'System.IO.Streams.unlines' Streams.'System.IO.Streams.stdout'</span>
<a name="line-583"></a><span class='hs-comment'>-- ghci&gt; os2 \&lt;- os1 &gt;&gt;= Streams.'contramap' (S.pack . show) &gt;&gt;= Streams.'filterOutputM' check</span>
<a name="line-584"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.write' (Just 3) os2</span>
<a name="line-585"></a><span class='hs-comment'>-- Allow 3?</span>
<a name="line-586"></a><span class='hs-comment'>-- False\&lt;Enter&gt;</span>
<a name="line-587"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.write' (Just 4) os2</span>
<a name="line-588"></a><span class='hs-comment'>-- Allow 4?</span>
<a name="line-589"></a><span class='hs-comment'>-- True\&lt;Enter&gt;</span>
<a name="line-590"></a><span class='hs-comment'>-- 4</span>
<a name="line-591"></a><span class='hs-comment'>-- @</span>
<a name="line-592"></a><span class='hs-definition'>filterOutputM</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>Bool</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-593"></a><span class='hs-definition'>filterOutputM</span> <span class='hs-varid'>p</span> <span class='hs-varid'>output</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeOutputStream</span> <span class='hs-varid'>chunk</span>
<a name="line-594"></a>  <span class='hs-keyword'>where</span>
<a name="line-595"></a>    <span class='hs-varid'>chunk</span> <span class='hs-conid'>Nothing</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>write</span> <span class='hs-conid'>Nothing</span> <span class='hs-varid'>output</span>
<a name="line-596"></a>    <span class='hs-varid'>chunk</span> <span class='hs-varid'>ch</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-597"></a>        <span class='hs-varid'>b</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>p</span> <span class='hs-varid'>x</span>
<a name="line-598"></a>        <span class='hs-keyword'>if</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>write</span> <span class='hs-varid'>ch</span> <span class='hs-varid'>output</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>()</span>
<a name="line-599"></a>
<a name="line-600"></a>
<a name="line-601"></a><a name="unzip"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-602"></a><span class='hs-comment'>-- | Takes apart a stream of pairs, producing a pair of input streams. Reading</span>
<a name="line-603"></a><span class='hs-comment'>-- from either of the produced streams will cause a pair of values to be pulled</span>
<a name="line-604"></a><span class='hs-comment'>-- from the original stream if necessary. Note that reading @n@ values from one</span>
<a name="line-605"></a><span class='hs-comment'>-- of the returned streams will cause @n@ values to be buffered at the other</span>
<a name="line-606"></a><span class='hs-comment'>-- stream.</span>
<a name="line-607"></a><span class='hs-comment'>--</span>
<a name="line-608"></a><span class='hs-comment'>-- Access to the original stream is thread safe, i.e. guarded by a lock.</span>
<a name="line-609"></a><span class='hs-definition'>unzip</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>InputStream</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span>
<a name="line-610"></a><span class='hs-definition'>unzip</span> <span class='hs-varid'>os</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-611"></a>    <span class='hs-varid'>lock</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newMVar</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>()</span>
<a name="line-612"></a>    <span class='hs-varid'>buf1</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newIORef</span> <span class='hs-varid'>id</span>
<a name="line-613"></a>    <span class='hs-varid'>buf2</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newIORef</span> <span class='hs-varid'>id</span>
<a name="line-614"></a>
<a name="line-615"></a>    <span class='hs-varid'>is1</span>  <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>makeInputStream</span> <span class='hs-varop'>$</span> <span class='hs-varid'>src</span> <span class='hs-varid'>lock</span> <span class='hs-varid'>id</span> <span class='hs-varid'>buf1</span> <span class='hs-varid'>buf2</span>
<a name="line-616"></a>    <span class='hs-varid'>is2</span>  <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>makeInputStream</span> <span class='hs-varop'>$</span> <span class='hs-varid'>src</span> <span class='hs-varid'>lock</span> <span class='hs-varid'>twist</span> <span class='hs-varid'>buf2</span> <span class='hs-varid'>buf1</span>
<a name="line-617"></a>
<a name="line-618"></a>    <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>is1</span><span class='hs-layout'>,</span> <span class='hs-varid'>is2</span><span class='hs-layout'>)</span>
<a name="line-619"></a>
<a name="line-620"></a>  <span class='hs-keyword'>where</span>
<a name="line-621"></a>    <span class='hs-varid'>twist</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-layout'>,</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-622"></a>
<a name="line-623"></a>    <span class='hs-varid'>src</span> <span class='hs-varid'>lock</span> <span class='hs-varid'>proj</span> <span class='hs-varid'>myBuf</span> <span class='hs-varid'>theirBuf</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>withMVar</span> <span class='hs-varid'>lock</span> <span class='hs-varop'>$</span> <span class='hs-varid'>const</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span>
<a name="line-624"></a>        <span class='hs-varid'>dl</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>readIORef</span> <span class='hs-varid'>myBuf</span>
<a name="line-625"></a>
<a name="line-626"></a>        <span class='hs-keyword'>case</span> <span class='hs-varid'>dl</span> <span class='hs-conid'>[]</span> <span class='hs-keyword'>of</span>
<a name="line-627"></a>          <span class='hs-conid'>[]</span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>more</span>
<a name="line-628"></a>          <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>writeIORef</span> <span class='hs-varid'>myBuf</span> <span class='hs-layout'>(</span><span class='hs-varid'>xs</span><span class='hs-varop'>++</span><span class='hs-layout'>)</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span>
<a name="line-629"></a>      <span class='hs-keyword'>where</span>
<a name="line-630"></a>        <span class='hs-varid'>more</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>os</span> <span class='hs-varop'>&gt;&gt;=</span>
<a name="line-631"></a>               <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span>
<a name="line-632"></a>                     <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-633"></a>                          <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>proj</span> <span class='hs-varid'>x</span>
<a name="line-634"></a>                          <span class='hs-varid'>modifyIORef</span> <span class='hs-varid'>theirBuf</span> <span class='hs-layout'>(</span><span class='hs-varop'>.</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-635"></a>                          <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-636"></a>
<a name="line-637"></a>
<a name="line-638"></a><a name="take"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-639"></a><span class='hs-comment'>-- | Wraps an 'InputStream', producing a new 'InputStream' that will produce at</span>
<a name="line-640"></a><span class='hs-comment'>-- most @n@ items, subsequently yielding end-of-stream forever.</span>
<a name="line-641"></a><span class='hs-comment'>--</span>
<a name="line-642"></a><span class='hs-comment'>-- Items pushed back to the returned 'InputStream' will be propagated upstream,</span>
<a name="line-643"></a><span class='hs-comment'>-- modifying the count of taken items accordingly.</span>
<a name="line-644"></a><span class='hs-comment'>--</span>
<a name="line-645"></a><span class='hs-comment'>-- Example:</span>
<a name="line-646"></a><span class='hs-comment'>--</span>
<a name="line-647"></a><span class='hs-comment'>-- @</span>
<a name="line-648"></a><span class='hs-comment'>-- ghci&gt; is &lt;- Streams.'fromList' [1..9::Int]</span>
<a name="line-649"></a><span class='hs-comment'>-- ghci&gt; is' &lt;- Streams.'take' 1 is</span>
<a name="line-650"></a><span class='hs-comment'>-- ghci&gt; Streams.'read' is'</span>
<a name="line-651"></a><span class='hs-comment'>-- Just 1</span>
<a name="line-652"></a><span class='hs-comment'>-- ghci&gt; Streams.'read' is'</span>
<a name="line-653"></a><span class='hs-comment'>-- Nothing</span>
<a name="line-654"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.peek' is</span>
<a name="line-655"></a><span class='hs-comment'>-- Just 2</span>
<a name="line-656"></a><span class='hs-comment'>-- ghci&gt; Streams.'unRead' 11 is'</span>
<a name="line-657"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.peek' is</span>
<a name="line-658"></a><span class='hs-comment'>-- Just 11</span>
<a name="line-659"></a><span class='hs-comment'>-- ghci&gt; Streams.'System.IO.Streams.peek' is'</span>
<a name="line-660"></a><span class='hs-comment'>-- Just 11</span>
<a name="line-661"></a><span class='hs-comment'>-- ghci&gt; Streams.'read' is'</span>
<a name="line-662"></a><span class='hs-comment'>-- Just 11</span>
<a name="line-663"></a><span class='hs-comment'>-- ghci&gt; Streams.'read' is'</span>
<a name="line-664"></a><span class='hs-comment'>-- Nothing</span>
<a name="line-665"></a><span class='hs-comment'>-- ghci&gt; Streams.'read' is</span>
<a name="line-666"></a><span class='hs-comment'>-- Just 2</span>
<a name="line-667"></a><span class='hs-comment'>-- ghci&gt; Streams.'toList' is</span>
<a name="line-668"></a><span class='hs-comment'>-- [3,4,5,6,7,8,9]</span>
<a name="line-669"></a><span class='hs-comment'>-- @</span>
<a name="line-670"></a><span class='hs-comment'>--</span>
<a name="line-671"></a><span class='hs-definition'>take</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int64</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-672"></a><span class='hs-definition'>take</span> <span class='hs-varid'>k0</span> <span class='hs-varid'>input</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-673"></a>    <span class='hs-varid'>kref</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newIORef</span> <span class='hs-varid'>k0</span>
<a name="line-674"></a>    <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>InputStream</span> <span class='hs-layout'>(</span><span class='hs-varid'>prod</span> <span class='hs-varid'>kref</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>pb</span> <span class='hs-varid'>kref</span><span class='hs-layout'>)</span>
<a name="line-675"></a>  <span class='hs-keyword'>where</span>
<a name="line-676"></a>    <span class='hs-varid'>prod</span> <span class='hs-varid'>kref</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-677"></a>        <span class='hs-varop'>!</span><span class='hs-varid'>k</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>readIORef</span> <span class='hs-varid'>kref</span>
<a name="line-678"></a>        <span class='hs-keyword'>if</span> <span class='hs-varid'>k</span> <span class='hs-varop'>&lt;=</span> <span class='hs-num'>0</span>
<a name="line-679"></a>          <span class='hs-keyword'>then</span> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span>
<a name="line-680"></a>          <span class='hs-keyword'>else</span> <span class='hs-keyword'>do</span>
<a name="line-681"></a>              <span class='hs-varid'>m</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>read</span> <span class='hs-varid'>input</span>
<a name="line-682"></a>              <span class='hs-varid'>when</span> <span class='hs-layout'>(</span><span class='hs-varid'>isJust</span> <span class='hs-varid'>m</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-varid'>modifyIORef</span> <span class='hs-varid'>kref</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>x</span> <span class='hs-comment'>-</span> <span class='hs-num'>1</span>
<a name="line-683"></a>              <span class='hs-varid'>return</span> <span class='hs-varid'>m</span>
<a name="line-684"></a>
<a name="line-685"></a>    <span class='hs-varid'>pb</span> <span class='hs-varid'>kref</span> <span class='hs-varop'>!</span><span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-686"></a>       <span class='hs-varid'>unRead</span> <span class='hs-varid'>s</span> <span class='hs-varid'>input</span>
<a name="line-687"></a>       <span class='hs-varid'>modifyIORef</span> <span class='hs-varid'>kref</span> <span class='hs-layout'>(</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span>
<a name="line-688"></a>
<a name="line-689"></a>
<a name="line-690"></a><a name="drop"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-691"></a><span class='hs-comment'>-- | Wraps an 'InputStream', producing a new 'InputStream' that will drop the</span>
<a name="line-692"></a><span class='hs-comment'>-- first @n@ items produced by the wrapped stream. See 'Prelude.drop'.</span>
<a name="line-693"></a><span class='hs-comment'>--</span>
<a name="line-694"></a><span class='hs-comment'>-- Items pushed back to the returned 'InputStream' will be propagated upstream,</span>
<a name="line-695"></a><span class='hs-comment'>-- modifying the count of dropped items accordingly.</span>
<a name="line-696"></a><span class='hs-definition'>drop</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int64</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-697"></a><span class='hs-definition'>drop</span> <span class='hs-varid'>k0</span> <span class='hs-varid'>input</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-698"></a>    <span class='hs-varid'>kref</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newIORef</span> <span class='hs-varid'>k0</span>
<a name="line-699"></a>    <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>InputStream</span> <span class='hs-layout'>(</span><span class='hs-varid'>prod</span> <span class='hs-varid'>kref</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>pb</span> <span class='hs-varid'>kref</span><span class='hs-layout'>)</span>
<a name="line-700"></a>  <span class='hs-keyword'>where</span>
<a name="line-701"></a>    <span class='hs-varid'>prod</span> <span class='hs-varid'>kref</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-702"></a>        <span class='hs-varop'>!</span><span class='hs-varid'>k</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>readIORef</span> <span class='hs-varid'>kref</span>
<a name="line-703"></a>        <span class='hs-keyword'>if</span> <span class='hs-varid'>k</span> <span class='hs-varop'>&lt;=</span> <span class='hs-num'>0</span>
<a name="line-704"></a>          <span class='hs-keyword'>then</span> <span class='hs-varid'>getInput</span> <span class='hs-varid'>kref</span>
<a name="line-705"></a>          <span class='hs-keyword'>else</span> <span class='hs-varid'>discard</span> <span class='hs-varid'>kref</span>
<a name="line-706"></a>
<a name="line-707"></a>    <span class='hs-varid'>getInput</span> <span class='hs-varid'>kref</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-708"></a>        <span class='hs-varid'>read</span> <span class='hs-varid'>input</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>c</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-709"></a>            <span class='hs-varid'>modifyIORef</span> <span class='hs-varid'>kref</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>x</span> <span class='hs-comment'>-</span> <span class='hs-num'>1</span><span class='hs-layout'>)</span>
<a name="line-710"></a>            <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span>
<a name="line-711"></a>
<a name="line-712"></a>    <span class='hs-varid'>discard</span> <span class='hs-varid'>kref</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>getInput</span> <span class='hs-varid'>kref</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>const</span> <span class='hs-varop'>$</span> <span class='hs-varid'>prod</span> <span class='hs-varid'>kref</span><span class='hs-layout'>)</span>
<a name="line-713"></a>
<a name="line-714"></a>    <span class='hs-varid'>pb</span> <span class='hs-varid'>kref</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-715"></a>        <span class='hs-varid'>unRead</span> <span class='hs-varid'>s</span> <span class='hs-varid'>input</span>
<a name="line-716"></a>        <span class='hs-varid'>modifyIORef</span> <span class='hs-varid'>kref</span> <span class='hs-layout'>(</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span>
<a name="line-717"></a>
<a name="line-718"></a>
<a name="line-719"></a><a name="give"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-720"></a><span class='hs-comment'>-- | Wraps an 'OutputStream', producing a new 'OutputStream' that will pass at</span>
<a name="line-721"></a><span class='hs-comment'>-- most @n@ items on to the wrapped stream, subsequently ignoring the rest of</span>
<a name="line-722"></a><span class='hs-comment'>-- the input.</span>
<a name="line-723"></a><span class='hs-comment'>--</span>
<a name="line-724"></a><span class='hs-definition'>give</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int64</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-725"></a><span class='hs-definition'>give</span> <span class='hs-varid'>k</span> <span class='hs-varid'>output</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>newIORef</span> <span class='hs-varid'>k</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>makeOutputStream</span> <span class='hs-varop'>.</span> <span class='hs-varid'>chunk</span>
<a name="line-726"></a>  <span class='hs-keyword'>where</span>
<a name="line-727"></a>    <span class='hs-varid'>chunk</span> <span class='hs-varid'>ref</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-728"></a>                    <span class='hs-varop'>!</span><span class='hs-varid'>n</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>readIORef</span> <span class='hs-varid'>ref</span>
<a name="line-729"></a>                    <span class='hs-keyword'>if</span> <span class='hs-varid'>n</span> <span class='hs-varop'>&lt;=</span> <span class='hs-num'>0</span>
<a name="line-730"></a>                      <span class='hs-keyword'>then</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>()</span>
<a name="line-731"></a>                      <span class='hs-keyword'>else</span> <span class='hs-keyword'>do</span>
<a name="line-732"></a>                          <span class='hs-varid'>writeIORef</span> <span class='hs-varid'>ref</span> <span class='hs-varop'>$!</span> <span class='hs-varid'>n</span> <span class='hs-comment'>-</span> <span class='hs-num'>1</span>
<a name="line-733"></a>                          <span class='hs-varid'>write</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-varid'>output</span>
<a name="line-734"></a>
<a name="line-735"></a>
<a name="line-736"></a><a name="ignore"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-737"></a><span class='hs-comment'>-- | Wraps an 'OutputStream', producing a new 'OutputStream' that will ignore</span>
<a name="line-738"></a><span class='hs-comment'>-- the first @n@ items received, subsequently passing the rest of the input on</span>
<a name="line-739"></a><span class='hs-comment'>-- to the wrapped stream.</span>
<a name="line-740"></a><span class='hs-comment'>--</span>
<a name="line-741"></a><span class='hs-definition'>ignore</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int64</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-742"></a><span class='hs-definition'>ignore</span> <span class='hs-varid'>k</span> <span class='hs-varid'>output</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>newIORef</span> <span class='hs-varid'>k</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>makeOutputStream</span> <span class='hs-varop'>.</span> <span class='hs-varid'>chunk</span>
<a name="line-743"></a>  <span class='hs-keyword'>where</span>
<a name="line-744"></a>    <span class='hs-varid'>chunk</span> <span class='hs-varid'>ref</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-745"></a>                    <span class='hs-varop'>!</span><span class='hs-varid'>n</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>readIORef</span> <span class='hs-varid'>ref</span>
<a name="line-746"></a>                    <span class='hs-keyword'>if</span> <span class='hs-varid'>n</span> <span class='hs-varop'>&gt;</span> <span class='hs-num'>0</span>
<a name="line-747"></a>                      <span class='hs-keyword'>then</span> <span class='hs-varid'>writeIORef</span> <span class='hs-varid'>ref</span> <span class='hs-varop'>$!</span> <span class='hs-varid'>n</span> <span class='hs-comment'>-</span> <span class='hs-num'>1</span>
<a name="line-748"></a>                      <span class='hs-keyword'>else</span> <span class='hs-varid'>write</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-varid'>output</span>
<a name="line-749"></a>
<a name="line-750"></a>
<a name="line-751"></a><a name="ignoreEof"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-752"></a><span class='hs-comment'>-- | Wraps an 'OutputStream', ignoring any end-of-stream 'Nothing' values</span>
<a name="line-753"></a><span class='hs-comment'>-- written to the returned stream.</span>
<a name="line-754"></a><span class='hs-comment'>--</span>
<a name="line-755"></a><span class='hs-comment'>-- /Since: 1.0.1.0/</span>
<a name="line-756"></a><span class='hs-comment'>--</span>
<a name="line-757"></a><span class='hs-definition'>ignoreEof</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-758"></a><span class='hs-definition'>ignoreEof</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeOutputStream</span> <span class='hs-varid'>f</span>
<a name="line-759"></a>  <span class='hs-keyword'>where</span>
<a name="line-760"></a>    <span class='hs-varid'>f</span> <span class='hs-conid'>Nothing</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>()</span>
<a name="line-761"></a>    <span class='hs-varid'>f</span> <span class='hs-varid'>x</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>write</span> <span class='hs-varid'>x</span> <span class='hs-varid'>s</span>
<a name="line-762"></a>
<a name="line-763"></a>
<a name="line-764"></a><a name="atEndOfInput"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-765"></a><span class='hs-comment'>-- | Wraps an 'InputStream', running the specified action when the stream</span>
<a name="line-766"></a><span class='hs-comment'>-- yields end-of-file.</span>
<a name="line-767"></a><span class='hs-comment'>--</span>
<a name="line-768"></a><span class='hs-comment'>-- /Since: 1.0.2.0/</span>
<a name="line-769"></a><span class='hs-comment'>--</span>
<a name="line-770"></a><span class='hs-definition'>atEndOfInput</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>InputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-771"></a><span class='hs-definition'>atEndOfInput</span> <span class='hs-varid'>m</span> <span class='hs-varid'>is</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$!</span> <span class='hs-conid'>InputStream</span> <span class='hs-varid'>prod</span> <span class='hs-varid'>pb</span>
<a name="line-772"></a>  <span class='hs-keyword'>where</span>
<a name="line-773"></a>    <span class='hs-varid'>prod</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>read</span> <span class='hs-varid'>is</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>maybe</span> <span class='hs-varid'>eof</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-varop'>.</span> <span class='hs-conid'>Just</span><span class='hs-layout'>)</span>
<a name="line-774"></a>    <span class='hs-varid'>eof</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>void</span> <span class='hs-varid'>m</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span>
<a name="line-775"></a>    <span class='hs-varid'>pb</span> <span class='hs-varid'>s</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unRead</span> <span class='hs-varid'>s</span> <span class='hs-varid'>is</span>
<a name="line-776"></a>
<a name="line-777"></a>
<a name="line-778"></a><a name="atEndOfOutput"></a><span class='hs-comment'>------------------------------------------------------------------------------</span>
<a name="line-779"></a><span class='hs-comment'>-- | Wraps an 'OutputStream', running the specified action when the stream</span>
<a name="line-780"></a><span class='hs-comment'>-- receives end-of-file.</span>
<a name="line-781"></a><span class='hs-comment'>--</span>
<a name="line-782"></a><span class='hs-comment'>-- /Since: 1.0.2.0/</span>
<a name="line-783"></a><span class='hs-comment'>--</span>
<a name="line-784"></a><span class='hs-definition'>atEndOfOutput</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>OutputStream</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-785"></a><span class='hs-definition'>atEndOfOutput</span> <span class='hs-varid'>m</span> <span class='hs-varid'>os</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>makeOutputStream</span> <span class='hs-varid'>f</span>
<a name="line-786"></a>  <span class='hs-keyword'>where</span>
<a name="line-787"></a>    <span class='hs-varid'>f</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>write</span> <span class='hs-conid'>Nothing</span> <span class='hs-varid'>os</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>void</span> <span class='hs-varid'>m</span>
<a name="line-788"></a>    <span class='hs-varid'>f</span> <span class='hs-varid'>x</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>write</span> <span class='hs-varid'>x</span> <span class='hs-varid'>os</span>
</pre></body>
</html>