<div dir="ltr"><div>As soon as I sent this, I think I hit on the answer. There's no getting away from having to write a strategy like this:</div><div><br></div><div><font face="monospace, monospace">evalActualsWith :: Strategy [ActualShift] -> Strategy User</font></div><div><font face="monospace, monospace">evalActualsWith strat user = do</font></div><div><font face="monospace, monospace">  actuals' <- strat $ actuals user</font></div><div><font face="monospace, monospace">  return $ user { actuals = actuals' }</font></div><div><br></div><div>But once I've written that it's a simple case of the following:</div><div><br></div><div><font face="monospace, monospace">parActuals :: Strategy User</font></div><div><font face="monospace, monospace">parActuals = evalActualsWith $ rparWith $ evalTraversable rseq</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">updateActuals :: User -> User</font></div><div><font face="monospace, monospace">updateActuals user = users { actuals = newActuals } `using` parActuals</font></div><div><font face="monospace, monospace">  where ...</font></div><div><br></div><div>I think that's the same thing, right?</div><div><br></div><div>Cheers,</div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 29 December 2015 at 09:55, David Turner <span dir="ltr"><<a href="mailto:dct25-561bs@mythic-beasts.com" target="_blank">dct25-561bs@mythic-beasts.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<div><br></div><div>I'd like to use the Control.Parallel.Strategies machinery to evaluate parts of a big record-based data structure in the background. The following code is the sort of thing that I've ended up with - it makes a spark that forces the <span style="font-family:monospace,monospace">actuals </span>field of a <font face="monospace, monospace">user</font> object, in the sense that it forces all of the elements to WHNF. (At least, that's what I hope it's doing!)</div><div><div><br></div><div><div><font face="monospace, monospace">updateActuals user = runEval $ do</font></div><div><font face="monospace, monospace">  newActuals <- rparWith (evalTraversable rseq)</font></div><div><font face="monospace, monospace">              $ calculateActuals user</font></div><div><font face="monospace, monospace">  return user { actuals = newActuals }</font></div></div><div><br></div><div>However, I'm concerned that <span style="font-family:monospace,monospace">runEval</span> is marked as "for Strategy programmers" and that I should be using some collection of combinators instead of dropping down to this level. But I just can't work out how to combine the available combinators to do the same thing. In particular, all the articles I've found about this seem to end up adding <span style="font-family:monospace,monospace">`using` something </span>to the end of one key line of code to achieve near-perfect parallelisation, but now that I come to do it myself I'm stuck! I think I'm looking for something like:</div><div><br></div><div><div><font face="monospace, monospace">updateActuals user = user { actuals = newActuals } `using` ...</font></div></div><div><font face="monospace, monospace"><br></font></div><div>Can anyone help me fill in the blank there?<br></div></div><div><br></div><div>Many thanks,</div><div><br></div><div>David</div><div><br></div><div><br></div></div>
</blockquote></div><br></div>