liveBook · Manning

Strategy type

As explained in Learn Haskell by Example

A Strategy is a type synonym for a function that specifies how a value should be evaluated through the Eval monad.

A `Strategy` describes how a value should be evaluated, separately from the algorithm that computes it. In `Control.Parallel.Strategies`, it is a type synonym for `a -> Eval a`: a function that receives a value and returns an `Eval` action specifying evaluation work. This lets pure code keep its result and logic while adding a plan for sequential or parallel evaluation. section 13.4.2 section 13.5

Prebuilt strategies express common evaluation choices:

  • `r0` performs no evaluation. section 13.4.2
  • `rseq` evaluates an argument to weak head normal form: enough to reveal its first data constructor, without necessarily evaluating contained values. section 13.4.2
  • `rpar` creates a spark, making an argument available for parallel evaluation by the runtime. section 13.4.2 section 13.4.3
  • `rdeepseq` forces full evaluation to normal form, including data beneath the outer constructor. section 13.4.2

`Eval` collects the evaluation plan, and `runEval` retrieves its value. A spark created with `rpar` is only an opportunity for parallel work: it may fizzle if the caller demands the result before the spark finishes, or be a dud when the value was already evaluated. Haskell execution contexts take sparks from a shared pool through work stealing; runtime details such as garbage collection of unused sparks are handled automatically. section 13.4.3 section 13.4.3

Apply a strategy across a collection

`evalList` lifts a strategy for one element into a strategy for a list. For example, `map (^ 100) [1 .. 1000] \`using\` evalList rpar` maps first and requests parallel evaluation of the resulting elements. `withStrategy` provides the same idea in a function-style form. For vectors, creating a spark per pixel can overflow the spark pool; splitting a vector into larger chunks and applying `rseq` per chunk produces a practical parallel mapping strategy. section 13.4.3 section 13.4.3 section 13.4.3

Figure 13.5 Haskell execution contexts and spark pools
figure

The execution-context diagram shows how `rpar` feeds sparks into a pool that available Haskell execution contexts can steal and evaluate. section 13.4.3

Evaluation strategies support deterministic parallelism: the algorithm remains unchanged while its evaluation order is made explicit. They work best when work is large enough to justify each spark. Too many tiny sparks can overflow the pool and reduce effectiveness, so divide collection work into larger chunks before evaluating those chunks in parallel. section 13.5 section 13.5

How Learn Haskell by Example covers it

How deep it goes
Defines `Strategy` as `a -> Eval a`, contrasts evaluation depths, and defers deeper treatment of weak head normal form.
Examples
Demonstrates parallel list mapping with `evalList rpar` and chunked `Vector` mapping with `parVectorChunk`.
What you can do after
Apply it via `Control.Parallel.Strategies` to add deterministic parallelism and avoid excessive tiny sparks through chunking.
How it connects
Connects `Strategy` to Eval, runEval, rpar, rseq, rdeepseq, sparks, weak head normal form, and normal form.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Haskell by Example. The section links point to the parts of the book it draws on.