This is related but somewhat tangential -- <div><br><div>  <b>Why isn&#39;t there a tryReadChan?</b>  It looks like it would be implementable with the current Chan representation in terms of tryTakeMVar.  Especially since isEmptyChan is deprecated this would be nice to have.</div>


<div><br></div><div>Because of missing tryReadChan there is no non-blocking way to read data resident in a Chan (i.e. flush it -- in this case because I was in an exception handler and wanted to flush out what was left in memory in a Chan).  I found myself rolling my own in the form of the following data structure to get around this:</div>


<div><br></div><div><div><br></div><div><font face="&#39;courier new&#39;, monospace">-- Chan&#39;s don&#39;t quite do the trick.  Here&#39;s something simpler.  It</font></div><div><font face="&#39;courier new&#39;, monospace">-- keeps a buffer of elemnts and an MVar to signal &quot;end of stream&quot;.</font></div>


<div><font face="&#39;courier new&#39;, monospace">-- This it separates blocking behavior from data access.</font></div><div><font face="&#39;courier new&#39;, monospace">data Buffer a = Buf (MVar ()) (IORef [a])</font></div>


<div><font face="&#39;courier new&#39;, monospace"><br></font></div><div><font face="&#39;courier new&#39;, monospace">newBuffer :: IO (Buffer a)</font></div><div><font face="&#39;courier new&#39;, monospace">newBuffer = do</font></div>


<div><font face="&#39;courier new&#39;, monospace">  mv  &lt;- newEmptyMVar</font></div><div><font face="&#39;courier new&#39;, monospace">  ref &lt;- newIORef []</font></div><div><font face="&#39;courier new&#39;, monospace">  return (Buf mv ref)</font></div>


<div><font face="&#39;courier new&#39;, monospace"><br></font></div><div><font face="&#39;courier new&#39;, monospace">writeBuffer :: Buffer a -&gt; a -&gt; IO ()</font></div><div><font face="&#39;courier new&#39;, monospace">writeBuffer (Buf mv ref) x = do</font></div>


<div><font face="&#39;courier new&#39;, monospace">  b &lt;- isEmptyMVar mv</font></div><div><font face="&#39;courier new&#39;, monospace">  if b</font></div><div><font face="&#39;courier new&#39;, monospace">     then atomicModifyIORef ref (\ ls -&gt; (x:ls,()))</font></div>


<div><font face="&#39;courier new&#39;, monospace">   else error &quot;writeBuffer: cannot write to closed Buffer&quot;</font></div><div><font face="&#39;courier new&#39;, monospace"><br></font></div><div><font face="&#39;courier new&#39;, monospace">-- | Signal completion. </font></div>


<div><font face="&#39;courier new&#39;, monospace">closeBuffer :: Buffer a -&gt; IO ()</font></div><div><font face="&#39;courier new&#39;, monospace">closeBuffer (Buf mv _) = putMVar mv ()</font></div><div><font face="&#39;courier new&#39;, monospace"><br>


</font></div><div><font face="&#39;courier new&#39;, monospace">peekBuffer :: Buffer a -&gt; IO [a]</font></div><div><font face="&#39;courier new&#39;, monospace">peekBuffer (Buf _ ref) = liftM reverse $ readIORef ref </font></div>


<div><font face="&#39;courier new&#39;, monospace"><br></font></div><div><font face="&#39;courier new&#39;, monospace">-- Returns a lazy list, just like getChanContents:</font></div><div><font face="&#39;courier new&#39;, monospace">getBufferContents :: Buffer a -&gt; IO [a]</font></div>


<div><font face="&#39;courier new&#39;, monospace">getBufferContents buf@(Buf mv ref) = do</font></div><div><font face="&#39;courier new&#39;, monospace">  chan &lt;- newChan </font></div><div><font face="&#39;courier new&#39;, monospace">  let loop = do </font></div>


<div><font face="&#39;courier new&#39;, monospace"><span style="white-space:pre-wrap">        </span> grabbed &lt;- atomicModifyIORef ref (\ ls -&gt; ([], reverse ls))</font></div><div><font face="&#39;courier new&#39;, monospace"><span style="white-space:pre-wrap">        </span> mapM_ (writeChan chan . Just) grabbed</font></div>


<div><font face="&#39;courier new&#39;, monospace"><span style="white-space:pre-wrap">        </span> mayb &lt;- tryTakeMVar mv -- Check if we&#39;re done.</font></div><div><font face="&#39;courier new&#39;, monospace"><span style="white-space:pre-wrap">        </span> case mayb of </font></div>


<div><font face="&#39;courier new&#39;, monospace"><span style="white-space:pre-wrap">        </span>   Nothing -&gt; threadDelay 10000 &gt;&gt; loop</font></div><div><font face="&#39;courier new&#39;, monospace"><span style="white-space:pre-wrap">        </span>   Just () -&gt; writeChan chan Nothing</font></div>


<div><font face="&#39;courier new&#39;, monospace">  forkIO loop</font></div><div><font face="&#39;courier new&#39;, monospace">  ls &lt;- getChanContents chan</font></div><div><font face="&#39;courier new&#39;, monospace">  return (map fromJust $ </font></div>


<div><font face="&#39;courier new&#39;, monospace"><span style="white-space:pre-wrap">        </span>  takeWhile isJust ls)</font></div><div><font face="&#39;courier new&#39;, monospace"><br></font></div></div>
<div><br></div>
</div>