<div>In stream processing frameworks this is a (common) non-deterministic merge operation.</div><div><br></div><div>Because it&#39;s nondeterministic it would need to happen in IO:</div><div><br></div><div>  parCompletionOrder :: [a] -&gt; IO [a]</div>

<div><br></div><div>But it can be nonblocking (returns immediately, and &quot;lazy IO&quot; happens in the background).</div><div><br></div><div>The Chan library has a primitive, <span class="Apple-style-span" style="font-family:monospace;font-size:14px;line-height:16px"><a name="v:getChanContents" class="def" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;text-decoration:none;font-weight:bold">getChanContents</a></span>, that encapsulates the lazy IO and makes this very easy to do:</div>

<div><br></div><div><a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent-Chan.html">http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent-Chan.html</a></div><div>
<br>
</div><div>Thus &quot;parCompletionOrder&quot; (or whatever it&#39;s called) would only need to fork an IO thread for each element, and have all threads write to a single channel as soon as they are done. (Where done is either evaluating shallowly (weak-head-normal-form) or deeply (full normal form).)</div>

<div><br></div><div>Then the main thread invokes getChanContents and voila.</div><div><br></div><div>Cheers,</div><div>  -Ryan</div><br><br><div class="gmail_quote">On Mon, Feb 6, 2012 at 6:24 PM, Edward Amsden <span dir="ltr">&lt;<a href="mailto:eca7215@cs.rit.edu">eca7215@cs.rit.edu</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Conal Elliot did something like this for his FRP system in the paper<br>
Push-Pull Functional Reactive Programming [1]. It involved a hack in<br>
which unsafePerformIO was used to spawn two threads to evaluate two<br>
events for occurrences, and return whichever returned first.<br>
<br>
Recall though, that monads aren&#39;t magic (despite frequent appearances<br>
to the contrary.) They are just functional structures that have to<br>
obey all of the normal restrictions of a pure functional language,<br>
including referential transparency. The entire point of Haskell&#39;s<br>
parallelism constructs is to make the returned values independent of<br>
parallel evaluation order. You&#39;re not going to escape that by using a<br>
monad, unless its one like IO which exists to order side-effects and<br>
isolate them in the type system.<br>
<br>
<br>
[1] <a href="http://conal.net/papers/push-pull-frp/" target="_blank">http://conal.net/papers/push-pull-frp/</a><br>
<div><div class="h5"><br>
<br>
On Mon, Feb 6, 2012 at 5:46 PM, Victor Miller &lt;<a href="mailto:victorsmiller@gmail.com">victorsmiller@gmail.com</a>&gt; wrote:<br>
&gt; Suppose that we have a list [a] of computations that we want to evaluate in<br>
&gt; parallel.  I would like to have something (probably a monad) which would<br>
&gt; return the list in order (roughly) of finishing:<br>
&gt;<br>
&gt; Say the monad is M.  It would be something like the state monad, in that it<br>
&gt; would be implemented by a state transformer function.  In this case the<br>
&gt; state would the set of computations to be evaluated.<br>
&gt;<br>
&gt; we might have a function<br>
&gt;<br>
&gt;<br>
&gt; include :: [a] -&gt; M a ()<br>
&gt;<br>
&gt; which would say that the monad&#39;s responsibility would be to evaluate all the<br>
&gt; members of a in parallel.  We might also have a function<br>
&gt;<br>
&gt; strategy :: Strategy -&gt; M a ()<br>
&gt;<br>
&gt; which would indicate the parallel strategy to be used.<br>
&gt;<br>
&gt; The key thing would be function, completed, which produces a list of all the<br>
&gt; computations to be evaluated as a list roughly in order of completion.<br>
&gt;<br>
&gt; That is, if, inside the M monad we finished the do with<br>
&gt;<br>
&gt; completed<br>
&gt;<br>
&gt; then we would have a value M a [a]<br>
&gt;<br>
&gt; which would be the list in order of completion.<br>
&gt;<br>
&gt; Since everything is lazy we could ask for the head of the list, and it would<br>
&gt; be the first value whose computation finished.<br>
&gt;<br>
&gt; Does such a thing exist?<br>
&gt;<br>
&gt;<br>
&gt; Victor<br>
&gt;<br>
&gt;<br>
&gt;<br>
</div></div>&gt; _______________________________________________<br>
&gt; Haskell-Cafe mailing list<br>
&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
<br>
--<br>
Edward Amsden<br>
Student<br>
Computer Science<br>
Rochester Institute of Technology<br>
<a href="http://www.edwardamsden.com" target="_blank">www.edwardamsden.com</a><br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</font></span></blockquote></div><br>