Parallel Evaluation Strategies, or Strategies for short, provide
ways to express parallel computations. Strategies have the following
key features:

Strategies express deterministic parallelism:
the result of the program is unaffected by evaluating in parallel.
The parallel tasks evaluated by a Strategy may have no side effects.
For non-deterministic parallel programming, see Control.Concurrent.

Strategies let you separate the description of the parallelism from the
logic of your program, enabling modular parallelism. The basic idea
is to build a lazy data structure representing the computation, and
then write a Strategy that describes how to traverse the data structure
and evaluate components of it sequentially or in parallel.

Strategies are compositional: larger strategies can be built
by gluing together smaller ones.

Monad and Applicative instances are provided, for quickly building
strategies that involve traversing structures in a regular way.

The strategy type

A Strategy is a function that embodies a parallel evaluation strategy.
The function traverses (parts of) its argument, evaluating subexpressions
in parallel or in sequence.

A Strategy may do an arbitrary amount of evaluation of its
argument, but should not return a value different from the one it
was passed.

Parallel computations may be discarded by the runtime system if the
program no longer requires their result, which is why a Strategy
function returns a new value equivalent to the old value. The
intention is that the program applies the Strategy to a
structure, and then uses the returned value, discarding the old
value. This idiom is expressed by the using function.

Sequential inverse function composition,
for those who read their programs from left to right.
The result of the first function is evaluated using the
given strategy, and then given to the second function.

Parallel inverse function composition,
for those who read their programs from left to right.
The result of the first function is evaluated using the
given strategy, in parallel with the application of the
second function.

API History

The strategies library has a long history. What follows is a
summary of how the current design evolved, and is mostly of
interest to those who are familiar with an older version, or need
to adapt old code to use the newer API.

Later, during work on the shared-memory implementation of
parallelism in GHC, we discovered that the original formulation of
Strategies had some problems, in particular it lead to space leaks
and difficulties expressing speculative parallelism. Details are in
the paper Runtime Support for Multicore Haskellhttp://www.haskell.org/~simonmar/papers/multicore-ghc.pdf.

This module has been rewritten in version 2. The main change is to
the 'Strategy a' type synonym, which was previously a -> Done and
is now a -> Eval a. This change helps to fix the space leak described
in "Runtime Support for Multicore Haskell". The problem is that
the runtime will currently retain the memory referenced by all
sparks, until they are evaluated. Hence, we must arrange to
evaluate all the sparks eventually, just in case they aren't
evaluated in parallel, so that they don't cause a space leak. This
is why we must return a "new" value after applying a Strategy,
so that the application can evaluate each spark created by the
Strategy.

The simple rule is this: you must use the result of applying
a Strategy if the strategy creates parallel sparks, and you
should probably discard the the original value. If you don't
do this, currently it may result in a space leak. In the
future (GHC 6.14), it will probably result in lost parallelism
instead, as we plan to change GHC so that unreferenced sparks
are discarded rather than retained (we can't make this change
until most code is switched over to this new version of
Strategies, because code using the old verison of Strategies
would be broken by the change in policy).

parList and parBuffer have versions specialised to rwhnf,
and there are transformation rules that automatically translate
e.g. parList rwnhf into a call to the optimised version.

NFData has been moved to Control.DeepSeq in the deepseq
package. Note that since the Strategy type changed, rnf
is no longer a Strategy: use rdeepseq instead.

Version 2.1 moved NFData into a separate package, deepseq.

Version 2.2 changed the type of Strategy to a -> Eval a, and
re-introduced the r0 strategy which was missing in version 2.1.

Version 2.3 simplified the Eval type, so that Eval is now just
the strict identity monad. This change and various other
improvements and refactorings are thanks to Patrick Maier who
noticed that Eval didn't satisfy the monad laws, and that a
simpler version would fix that problem.

(version 2.3 was not released on Hackage).

Version 3 introduced a major overhaul of the API, to match what is
presented in the paper

A strategy combinator for a particular type constructor
or constructor class T is called evalT..., parT... or seqT....

The seqT... combinators (residing in module
Control.Seq) yield sequential strategies.
Thus, seqT... combinators cannot spark, nor can the sequential
strategies to which they may be applied.
Examples: seqTuple2, seqListN, seqFoldable.

The evalT... combinators do not spark themselves, yet they may
be applied to strategies that do spark. (They may also be applied
to non-sparking strategies; however, in that case the corresponding
seqT... combinator might be a better choice.)
Examples: evalTuple2, evalListN, evalTraversable.

The parT... combinators, which are derived from their evalT...
counterparts, do spark. They may be applied to all strategies,
whether sparking or not.
Examples: parTuple2, parListN, parTraversable.

An exception to the type driven naming scheme are evalBuffer and
parBuffer, which are not named after their type constructor (lists)
but after their function (rolling buffer of fixed size).

Backwards compatibility

These functions and types are all deprecated, and will be
removed in a future release. In all cases they have been
either renamed or replaced with equivalent functionality.