liveBook · Manning

Eval

As explained in Learn Haskell by Example

The Eval monad is the computation context provided by Haskell's parallel evaluation support for composing controlled evaluations.

Eval is the computation context used by Control.Parallel.Strategies to describe an evaluation plan. A Strategy has type a -> Eval a: it specifies which values should be evaluated in parallel and which should be forced sequentially, while leaving the program’s algorithm unchanged. section 13.4.2 section 13.5

Run an Eval computation with runEval to obtain its value. Within the computation, rpar creates a spark for parallel evaluation, while rseq evaluates a value sequentially. A spark does not make return wait: if its result is demanded too soon, the spark can fizzle; an already evaluated value produces a dud. section 13.4.3

Choose evaluation strategies according to how much of a value must be forced:

  • r0 performs no evaluation. section 13.4.2
  • rseq evaluates only to weak head normal form, reaching at least the first data constructor; list elements may remain unevaluated thunks. section 13.4.2
  • rdeepseq forces a value completely to normal form. section 13.4.2
  • rpar creates a spark that an available Haskell execution context may take from the spark pool and evaluate. section 13.4.2 section 13.4.3

Parallel list mapping

Apply evalList rpar with using or withStrategy to spark each element of a mapped list, as in map (^ 100) [1 .. 1000] `using` evalList rpar. For larger image vectors, avoid creating one spark per pixel: split the vector into larger chunks and evaluate those chunks in parallel, reducing spark-pool overflow. section 13.4.3 section 13.5

Figure 13.5 Haskell execution contexts and spark pools
figure

The diagram shows how rpar fills a shared spark pool and how idle Haskell execution contexts use work stealing to pick up parallel work. section 13.4.3

Evaluation strategies provide parallelism rather than general concurrency. They are suited to the same pure computation being applied repeatedly, such as image processing over a collection. Runtime details handle cases where sparks are collected or evaluated before a worker reaches them, but spark counts still matter: too many sparks can make parallel execution ineffective. section 13.4.2 section 13.5

How Learn Haskell by Example covers it

How deep it goes
Defines Eval through Strategy and runEval, then explains sparks, weak head normal form, and chunking while deferring runtime-system details.
Examples
Demonstrates runEval with rpar, parallel list mapping via evalList rpar, and chunked Vector image mapping.
What it assumes
Introduces weak head normal form and thunks as needed to distinguish sequential from deep evaluation in lazy Haskell.
What you can do after
Apply it via Control.Parallel.Strategies to parallelize pure collection work while avoiding excessive sparks through chunking.
How it connects
Connects Eval with Control.Parallel.Strategies, Strategy, runEval, rpar, rseq, rdeepseq, weak head normal form, and sparks.

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.