Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Okay, here's a solution to the recursive factorial problem based on Tomas's solution to the waiting problem. I'm still not 100% satisfied with it; I feel like the inner method should return some kind of continuation tuple or something; maintaining the running total seems somehow like "cheating", but anyway:</p> <pre><code>open System.Threading open System let decr x = Thread.Sleep 1000 x - 1 let product x y = Thread.Sleep 1000 x * y let fact (n:int) :Async&lt;int&gt; = let rec fact2 (x:int) (xMinus1Op:Async&lt;int&gt;) (runningProduct:Async&lt;int&gt;) :Async&lt;int&gt; = async { if x = 0 then return! runningProduct else let! xMinus1 = xMinus1Op let! xMinus2Op = async {return decr xMinus1} |&gt; Async.StartChild let! prod = runningProduct let! runningProduct = async {return product x prod} |&gt; Async.StartChild // start both threads to execute simultaneously and feed them forward. return! fact2 xMinus1 xMinus2Op runningProduct } fact2 n (async{return decr n}) (async{return 1}) let start = Environment.TickCount let result = fact 10 |&gt; Async.RunSynchronously printfn "%A" &lt;| result printfn "%A" &lt;| Environment.TickCount - start //runs in 11 seconds, not 20. </code></pre> <p><strong>Edit: maybe it's more straightforward using tasks:</strong></p> <pre><code>let fact (n:int) :int = let rec fact2 (x:int) (xMinus1:int) (runningProduct:int) :int = if x = 0 then runningProduct else let xMinus2Op = new Task&lt;int&gt;(fun () -&gt; decr xMinus1) let runningProductOp = new Task&lt;int&gt;(fun () -&gt; product x runningProduct) xMinus2Op.Start() runningProductOp.Start() let xMinus2 = xMinus2Op.Result let runningProduct = runningProductOp.Result fact2 xMinus1 xMinus2 runningProduct fact2 n (decr n) (1) </code></pre> <p>No workflows necessary, just plain imperative code; it might even translate into C# easily.</p>
 

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