Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>How about separating traversal from any other processing? Perhaps create a work queue (<code>MailboxProcessor</code> is a good starting point) and, as the tree is traversed, enqueue additional work for background processing. It doesn't solve the parallel traversal problem (which seems tricky to get right for all cases) but with additional processing relegated to the background, it should go pretty quickly. You can experiment with the number of background workers until you find a good degree of parallelism. This all assumes the amount of work to be done for each node is non-trivial.</p> <h3>EDIT</h3> <p>Here's some code. I'm sure it can be improved. I had to hammer it out pretty quickly. But this shows the basic concept. It only has one "background worker," i.e., the <code>MailboxProcessor</code>. I'll leave updating it to use multiple workers to the imagination.</p> <pre><code>type Msg&lt;'a, 'b&gt; = | Work of 'a | Done of 'b type MapTransformer(f) = let results = ResizeArray() let m = MailboxProcessor.Start(fun payload -&gt; let rec loop() = async { let! msg = payload.Receive() match msg with | Work work -&gt; results.Add(f work) return! loop() | Done (channel : AsyncReplyChannel&lt;_&gt;) -&gt; channel.Reply(results :&gt; seq&lt;_&gt;) } loop()) member this.Enqueue(item) = m.Post(Work item) member this.Results = m.PostAndReply(fun c -&gt; Done c) let uberMap tree = let m = MapTransformer(fun x -&gt; x + 1) tree |&gt; List.iter (fun x -&gt; m.Enqueue(x)) m.Results uberMap [1; 2; 3] //outputs [2; 3; 4] </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload