
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:
evalActualsWith :: Strategy [ActualShift] -> Strategy User
evalActualsWith strat user = do
actuals' <- strat $ actuals user
return $ user { actuals = actuals' }
But once I've written that it's a simple case of the following:
parActuals :: Strategy User
parActuals = evalActualsWith $ rparWith $ evalTraversable rseq
updateActuals :: User -> User
updateActuals user = users { actuals = newActuals } `using` parActuals
where ...
I think that's the same thing, right?
Cheers,
On 29 December 2015 at 09:55, David Turner
Hi,
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 actuals field of a user object, in the sense that it forces all of the elements to WHNF. (At least, that's what I hope it's doing!)
updateActuals user = runEval $ do newActuals <- rparWith (evalTraversable rseq) $ calculateActuals user return user { actuals = newActuals }
However, I'm concerned that runEval 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 `using` something 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:
updateActuals user = user { actuals = newActuals } `using` ...
Can anyone help me fill in the blank there?
Many thanks,
David