A spark is a runtime request to evaluate a Haskell thunk speculatively in parallel. It points at unevaluated work rather than holding a separate result. The runtime places sparks in a pool, where Haskell execution contexts (HECs), each roughly associated with an operating-system thread, can pick them up through work stealing. section 13.4.3
Create a spark with `rpar` inside the `Eval` monad, then use `runEval` to obtain the enclosing result. `rpar` returns without waiting, so parallel work is only useful when later demand gives it time to finish. A spark can fizzle if its value is demanded too soon, be a dud if already evaluated, or be garbage-collected before execution; the runtime handles these cases. section 13.4.3
Spark independent list work
Apply a strategy to computations that can be evaluated independently. `map (^ 100) [1 .. 1000] `using` evalList rpar` requests parallel evaluation of list elements; `withStrategy (evalList rpar)` provides the same strategy-oriented style. section 13.4.3
Granularity matters. Sparking every pixel operation in an image mapping can overflow the spark pool, leaving little effective parallelism. Split the vector into larger chunks, evaluate chunks with `rseq`, and spark those chunks instead. This reduces spark creation while allowing pure collection processing to run deterministically in parallel without changing the algorithm. section 13.4.3 section 13.5
Figure 13.5 Haskell execution contexts and spark pools
Shows HECs drawing work from a shared spark pool through work stealing. section 13.4.3
Chunked image-vector strategy
`parVectorChunk` converts a vector to a list, applies `parListChunk size rseq`, then rebuilds the vector. Using it around pixel mapping creates roughly one spark per chunk rather than one per pixel. section 13.4.3
