`rpar` is an evaluation strategy from `Control.Parallel.Strategies`. It creates a spark for an argument: a request that its evaluation may run in parallel, while the surrounding `Eval` computation can continue. Use it when independent pure work can overlap without changing the algorithm’s result. section 13.4.2 section 13.5
A strategy describes how a value should be evaluated. `r0` performs no evaluation, `rseq` evaluates an argument, `rpar` sparks parallel evaluation, and `rdeepseq` fully evaluates an argument. Evaluation with `rseq` reaches weak head normal form, so list elements can remain unevaluated thunks; `rdeepseq` instead forces normal form. section 13.4.2
Spark one value
Run an `Eval` computation with `runEval`. Binding the result of `rpar x` creates a spark for `x`, but returning does not wait for that evaluation to finish. runEval $ do x' <- rpar x return x' section 13.4.3
A spark points to a thunk and is placed in a spark pool. Haskell execution contexts (HECs), managed by the runtime system in operating-system threads, take sparks from that pool using work stealing. A spark may fizzle if its result is demanded before parallel evaluation finishes, or be a dud if its value was already evaluated. section 13.4.3
Figure 13.5 Haskell execution contexts and spark pools
The diagram relates `rpar` to the spark pool and the HECs that can evaluate queued sparks in parallel. section 13.4.3
Spark every element of a mapped list
`evalList rpar` applies `rpar` to each list element. It can be attached with `using` or passed to `withStrategy`. map (^ 100) [1 .. 1000] `using` evalList rpar withStrategy (evalList rpar) $ map (^ 100) [1 .. 1000] section 13.4.3
Avoid treating one spark per tiny item as an automatic speedup:
- Too many sparks can overflow the spark pool, leaving parallel execution ineffective. section 13.4.3 section 13.5
- Split work into larger chunks, then evaluate those chunks in parallel; a vector strategy can use `parListChunk` with `rseq` for chunk evaluation. section 13.4.3 section 13.5
- Do not immediately force the value sequentially after sparking it, since that defeats the purpose of parallel evaluation. section 13.4.3
For image-style mapping over a vector, chunking reduces a very large spark count to a bounded number of larger jobs. This keeps the pure mapping design while making the evaluation strategy, rather than the image-processing algorithm, responsible for parallel execution. section 13.4.3 section 13.5
