<br><br>
<div><span class="gmail_quote">On 11/27/07, <b class="gmail_sendername">Matthew Brecknell</b> &lt;<a href="mailto:haskell@brecknell.org">haskell@brecknell.org</a>&gt; wrote:</span>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">&gt; wait_first :: [Wait a] -&gt; IO (a, [Wait a])<br>&gt; wait_first [] = error &quot;wait_first: nothing to wait for&quot;
<br>&gt; wait_first ws = atomically (do_wait ws) where<br>&gt;&nbsp;&nbsp; do_wait [] = retry<br>&gt;&nbsp;&nbsp; do_wait (Wait w : ws) = do<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; r &lt;- readTVar w<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; case r of<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Nothing -&gt; fmap (second (Wait w:)) (do_wait ws)
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Just s -&gt; return (s,ws)</blockquote>
<div>&nbsp;</div>
<div>Interesting, although this seems like a perfect use for &quot;orelse&quot;:</div>
<div>&nbsp;</div>
<div>&gt; wait_stm :: Wait a -&gt; STM a</div>
<div>&gt; wait_stm (Wait w) = readTVar w &gt;&gt;= maybe retry return</div>
<div>&nbsp;</div>
<div>&gt; wait :: Wait a -&gt; IO a</div>
<div>&gt; wait w = atomically $ wait_stm w</div>
<div>&nbsp;</div>
<div>&gt; wait_first :: [Wait a] -&gt; IO (a, [Wait a])</div>
<div>&gt; wait_first [] = error &quot;wait_first: nothing to wait for&quot;</div>
<div>&gt; wait_first ws = atomically (do_wait ws) where</div>
<div>&gt;&nbsp;&nbsp;&nbsp; do_wait [] = retry</div>
<div>&gt;&nbsp;&nbsp;&nbsp; do_wait (w : ws) = do</div>
<div>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r &lt;- wait_stm w</div>
<div>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (r, ws)</div>
<div>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; `orelse` fmap (second (w:)) (do_wait ws)</div>
<div>&nbsp;</div><br>&nbsp;</div>