-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Parallel programming library -- -- This package provides a library for parallel programming. @package parallel @version 2.2.0.1 -- | Parallel Constructs module Control.Parallel -- | Indicates that it may be beneficial to evaluate the first argument in -- parallel with the second. Returns the value of the second argument. -- -- a `par` b is exactly equivalent semantically to -- b. -- -- par is generally used when the value of a is likely -- to be required later, but not immediately. Also it is a good idea to -- ensure that a is not a trivial computation, otherwise the -- cost of spawning it in parallel overshadows the benefits obtained by -- running it in parallel. -- -- Note that actual parallelism is only supported by certain -- implementations (GHC with the -threaded option, and GPH, for -- now). On other implementations, par a b = b. par :: a -> b -> b -- | Semantically identical to seq, but with a subtle operational -- difference: seq is strict in both its arguments, so the -- compiler may, for example, rearrange a `seq` b into -- b `seq` a `seq` b. This is normally no problem -- when using seq to express strictness, but it can be a problem -- when annotating code for parallelism, because we need more control -- over the order of evaluation; we may want to evaluate a -- before b, because we know that b has already been -- sparked in parallel with par. -- -- This is why we have pseq. In contrast to seq, -- pseq is only strict in its first argument (as far as the -- compiler is concerned), which restricts the transformations that the -- compiler can do, and ensures that the user can retain control of the -- evaluation order. pseq :: a -> b -> b -- | Evaluates its first argument to head normal form, and then returns its -- second argument as the result. seq :: a -> b -> b -- | Parallel Evaluation Strategies, or Strategies for short, specify a way -- to evaluate a structure with components in sequence or in parallel. -- -- Strategies are for expressing deterministic parallelism: the -- result of the program is unaffected by evaluating in parallel. For -- non-deterministic parallel programming, see Control.Concurrent. -- -- Strategies let you separate the description of parallelism from the -- logic of your program, enabling modular parallelism. -- -- Version 1.x -- -- The original Strategies design is described in -- http://www.macs.hw.ac.uk/~dsg/gph/papers/html/Strategies/strategies.html -- and the code was written by Phil Trinder, Hans-Wolfgang Loidl, Kevin -- Hammond et al. -- -- Version 2.x -- -- 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 Haskell" -- http://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). -- -- The other changes in version 2.x are: -- -- module Control.Parallel.Strategies -- | 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. type Strategy a = a -> Eval a -- | evaluate a value using the given Strategy. -- --
--   using x s = s x
--   
using :: a -> Strategy a -> a -- | evaluate a value using the given Strategy. This is simply -- using with the arguments reversed, and is equal to '($)'. withStrategy :: Strategy a -> a -> a -- | A Strategy that simply evaluates its argument to Weak Head -- Normal Form (i.e. evaluates it as far as the topmost constructor). rwhnf :: Strategy a -- | A Strategy that fully evaluates its argument -- --
--   rdeepseq a = rnf a `pseq` a
--   
rdeepseq :: NFData a => Strategy a -- | A Strategy that does no evaluation of its argument r0 :: Strategy a -- | A Strategy that evaluates its argument in parallel rpar :: Strategy a seqPair :: Strategy a -> Strategy b -> Strategy (a, b) parPair :: Strategy a -> Strategy b -> Strategy (a, b) seqTriple :: Strategy a -> Strategy b -> Strategy c -> Strategy (a, b, c) parTriple :: Strategy a -> Strategy b -> Strategy c -> Strategy (a, b, c) -- | A strategy that traverses a container data type with an instance of -- Traversable, and evaluates each of the elements in -- left-to-right sequence using the supplied strategy. seqTraverse :: Traversable t => Strategy a -> Strategy (t a) -- | A strategy that traverses a container data type with an instance of -- Traversable, and sparks each of the elements using the supplied -- strategy. parTraverse :: Traversable t => Strategy a -> Strategy (t a) -- | Spark each of the elements of a list using the given strategy. -- Equivalent to parTraverse at the list type. parList :: Strategy a -> Strategy [a] -- | Evaluate each of the elements of a list sequentially from left to -- right using the given strategy. Equivalent to seqTraverse at -- the list type. seqList :: Strategy a -> Strategy [a] parListN :: Int -> Strategy a -> Strategy [a] parListChunk :: Int -> Strategy a -> Strategy [a] parMap :: Strategy b -> (a -> b) -> [a] -> [b] -- | Applies a strategy to the nth element of list when the head is -- demanded. More precisely: -- -- -- -- The idea is to provide a `rolling buffer' of length n. It is a better -- than parList for a lazy stream, because parList will -- evaluate the entire list, whereas parBuffer will only evaluate -- a fixed number of elements ahead. parBuffer :: Int -> Strategy a -> [a] -> [a] -- | version of parList specialised to rwhnf. This version is -- much simpler, and may be faster than 'parList rwhnf'. You should never -- need to use this directly, since 'parList rwhnf' is automatically -- optimised to parListWHNF. It is here for experimentation -- purposes only. parListWHNF :: Strategy [a] -- | version of parBuffer specialised to rwhnf. You should -- never need to use this directly, since 'parBuffer rwhnf' is -- automatically optimised to parBufferWHNF. It is here for -- experimentation purposes only. parBufferWHNF :: Int -> Strategy [a] -- | Sequential function application. The argument is evaluated using the -- given strategy before it is given to the function. ($|) :: (a -> b) -> Strategy a -> a -> b -- | Parallel function application. The argument is evaluated using the -- given strategy, in parallel with the function application. ($||) :: (a -> b) -> Strategy a -> a -> b -- | Sequential function composition. The result of the second function is -- evaluated using the given strategy, and then given to the first -- function. (.|) :: (b -> c) -> Strategy b -> (a -> b) -> (a -> c) -- | Parallel function composition. The result of the second function is -- evaluated using the given strategy, in parallel with the application -- of the first function. (.||) :: (b -> c) -> Strategy b -> (a -> b) -> (a -> c) -- | 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. (-|) :: (a -> b) -> Strategy b -> (b -> c) -> (a -> c) -- | 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. (-||) :: (a -> b) -> Strategy b -> (b -> c) -> (a -> c) -- | Eval is an Applicative Functor that makes it easier to define -- parallel strategies that involve traversing structures. -- -- a Seq value will be evaluated strictly in sequence in its -- context, whereas a Par value wraps an expression that may be -- evaluated in parallel. The Applicative instance allows sequential -- composition, making it possible to describe an evaluateion strategy by -- composing Par and Seq with <*>. -- -- For example, -- --
--   parList :: Strategy a -> Strategy [a]
--   parList strat = traverse (Par . (`using` strat))
--   
-- --
--   seqPair :: Strategy a -> Strategy b -> Strategy (a,b)
--   seqPair f g (a,b) = pure (,) <$> f a <*> g b
--   
data Eval a Seq :: a -> Eval a Par :: a -> Eval a Lazy :: a -> Eval a unEval :: Eval a -> a -- | A class of types that can be fully evaluated. class NFData a rnf :: NFData a => a -> () type Done = () demanding :: a -> Done -> a sparking :: a -> Done -> a (>|) :: Done -> Done -> Done (>||) :: Done -> Done -> Done instance Monad Eval instance Applicative Eval instance Functor Eval