The Par monad and schedules
The parallel package restricts us to expressing our computations as lazy data structures. Moreover, such computations must always be pure, so no parallel IO is possible. Sometimes this isn't feasible and we would like to express more control. Somewhat inherently, more control implies less expressiveness. This trade-off is made in the monad-par package.
The core interface in Control.Monad.Par consists of:
data Par a -- instance Monad runPar :: Par a → a fork :: Par () → Par ()
The monad-par library defines its own context for computations, namely Par. The second important operation, next to executing the computation via runPar, is fork, which forks a computation so it happens in parallel.
Communication between computations in Par happens via IVar:
data IVar a new :: Par (IVar a) get :: IVar a → Par a put :: NFData a => IVar a → a → Par ()
To run two computations, c1 and c2, in parallel and return their results in a tuple, we would write:
-- file: ivar-testing.hs import...