packages feed

parallel 3.1.0.1 → 3.2.0.0

raw patch · 2 files changed

+96/−33 lines, 2 filesdep ~deepseqPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: deepseq

API changes (from Hackage documentation)

- Control.Parallel.Strategies: Done :: a -> Eval a
+ Control.Parallel.Strategies: class NFData a
+ Control.Parallel.Strategies: rparWith :: Strategy a -> Strategy a
- Control.Parallel.Strategies: rpar :: Strategy a
+ Control.Parallel.Strategies: rpar :: a -> Eval a

Files

Control/Parallel/Strategies.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE MagicHash, UnboxedTuples #-} ----------------------------------------------------------------------------- -- | -- Module      :  Control.Parallel.Strategies@@ -49,6 +50,7 @@        , rseq        , rdeepseq          -- :: NFData a => Strategy a        , rpar              -- :: Strategy a+       , rparWith          -- :: Strategy a -> Strategy a           -- * Injection of sequential strategies        , evalSeq           -- :: Seq.Strategy a -> Strategy a@@ -110,7 +112,7 @@        , (-||)           -- * For Strategy programmers-       , Eval(Done)        -- instances: Monad, Functor, Applicative+       , Eval              -- instances: Monad, Functor, Applicative        , runEval           -- :: Eval a -> a        , @@ -129,7 +131,12 @@     seqTraverse, parTraverse,     seqList,     seqPair, parPair,-    seqTriple, parTriple+    seqTriple, parTriple,++    -- * For API completeness++    -- | so users of 'rdeepseq' aren't required to import Control.DeepSeq:+    NFData   ) where  import Data.Traversable@@ -140,6 +147,8 @@  import qualified Control.Seq +import GHC.Exts+ infixr 9 `dot`     -- same as (.) infixl 0 `using`   -- lowest precedence and associate to the left @@ -179,6 +188,24 @@ -- > evalPair f g (a,b) = pure (,) <$> f a <*> g b -- +#if __GLASGOW_HASKELL__ >= 702++newtype Eval a = Eval (State# RealWorld -> (# State# RealWorld, a #))+  -- GHC 7.2.1 added the seq# and spark# primitives, that we use in+  -- the Eval monad implementation in order to get the correct+  -- strictness behaviour.++-- | Pull the result out of the monad.+runEval :: Eval a -> a+runEval (Eval x) = case x realWorld# of (# _, a #) -> a++instance Monad Eval where+  return x = Eval $ \s -> (# s, x #)+  Eval x >>= k = Eval $ \s -> case x s of+                                (# s', a #) -> case lazy (k a) of+                                                      Eval f -> f s'+#else+ data Eval a = Done a  -- | Pull the result out of the monad.@@ -187,8 +214,13 @@  instance Monad Eval where   return x = Done x-  Done x >>= k = k x   -- Note: pattern 'Done x' makes '>>=' strict+  Done x >>= k = lazy (k x)   -- Note: pattern 'Done x' makes '>>=' strict +{-# RULES "lazy Done" forall x . lazy (Done x) = Done x #-}++#endif++ instance Functor Eval where   fmap = liftM @@ -315,7 +347,11 @@ -- > rseq == evalSeq Control.Seq.rseq -- rseq :: Strategy a-rseq x = x `pseq` return x+#if __GLASGOW_HASKELL__ >= 702+rseq x = Eval $ \s -> seq# x s+#else+rseq x = x `seq` return x+#endif  -- Proof of rseq == evalSeq Control.Seq.rseq --@@ -330,7 +366,7 @@ -- > rdeepseq == evalSeq Control.Seq.rdeepseq -- rdeepseq :: NFData a => Strategy a-rdeepseq x = rnf x `pseq` return x+rdeepseq x = do rseq (rnf x); return x  -- Proof of rdeepseq == evalSeq Control.Seq.rdeepseq --@@ -342,10 +378,36 @@ -- == rdeepseq  -- | 'rpar' sparks its argument (for evaluation in parallel).-rpar :: Strategy a-rpar x = x `par` return x+rpar :: a -> Eval a+#if __GLASGOW_HASKELL__ >= 702+rpar  x = Eval $ \s -> spark# x s+#else+rpar  x = case (par# x) of { _ -> Done x }+#endif+{-# INLINE rpar  #-} +-- | instead of saying @rpar `dot` strat@, you can say+-- @rparWith strat@.  Compared to 'rpar', 'rparWith'+--+--  * does not exit the `Eval` monad+--+--  * does not have a built-in `rseq`, so for example `rparWith r0`+--    behaves as you might expect (it is a strategy that creates a+--    spark that does no evaluation).+--+--+rparWith :: Strategy a -> Strategy a+#if __GLASGOW_HASKELL__ >= 702+rparWith s a = do l <- rpar r; return (case l of Lift x -> x)+  where r = case s a of+              Eval f -> case f realWorld# of+                          (# _, a' #) -> Lift a' +data Lift a = Lift a+#else+rparWith s a = do l <- rpar (s a); return (case l of Done x -> x)+#endif+ -- -------------------------------------------------------------------------- -- Strategy combinators for Traversable data types @@ -353,15 +415,12 @@ -- according to the given strategy. evalTraversable :: Traversable t => Strategy a -> Strategy (t a) evalTraversable = traverse+{-# INLINE evalTraversable #-}  -- | Like 'evalTraversable' but evaluates all elements in parallel. parTraversable :: Traversable t => Strategy a -> Strategy (t a)-parTraversable strat = evalTraversable (rpar `dot` strat)--{-# SPECIALISE evalTraversable :: Strategy a -> Strategy (Maybe a) #-}-{-# SPECIALISE parTraversable :: Strategy a -> Strategy (Maybe a) #-}-{-# SPECIALISE evalTraversable :: Strategy a -> Strategy [a] #-}-{-# SPECIALISE parTraversable :: Strategy a -> Strategy [a] #-}+parTraversable strat = evalTraversable (rparWith strat)+{-# INLINE parTraversable #-}  -- -------------------------------------------------------------------------- -- Strategies for lists@@ -381,7 +440,7 @@ parList :: Strategy a -> Strategy [a] parList = parTraversable -- Alternative definition via evalList:--- parList strat = evalList (rpar `dot` strat)+-- parList strat = evalList (rparWith strat)  -- | @'evaListSplitAt' n stratPref stratSuff@ evaluates the prefix -- (of length @n@) of a list according to @stratPref@ and its the suffix@@ -395,7 +454,7 @@  -- | Like 'evalListSplitAt' but evaluates both sublists in parallel. parListSplitAt :: Int -> Strategy [a] -> Strategy [a] -> Strategy [a]-parListSplitAt n stratPref stratSuff = evalListSplitAt n (rpar `dot` stratPref) (rpar `dot` stratSuff)+parListSplitAt n stratPref stratSuff = evalListSplitAt n (rparWith stratPref) (rparWith stratSuff)  -- | Evaluate the first n elements of a list according to the given strategy. evalListN :: Int -> Strategy a -> Strategy [a]@@ -403,7 +462,7 @@  -- | Like 'evalListN' but evaluates the first n elements in parallel. parListN :: Int -> Strategy a -> Strategy [a]-parListN n strat = evalListN n (rpar `dot` strat)+parListN n strat = evalListN n (rparWith strat)  -- | Evaluate the nth element of a list (if there is such) according to -- the given strategy.@@ -413,7 +472,7 @@  -- | Like 'evalListN' but evaluates the nth element in parallel. parListNth :: Int -> Strategy a -> Strategy [a]-parListNth n strat = evalListNth n (rpar `dot` strat)+parListNth n strat = evalListNth n (rparWith strat)  -- | Divides a list into chunks, and applies the strategy -- @'evalList' strat@ to each chunk in parallel.@@ -421,9 +480,13 @@ -- It is expected that this function will be replaced by a more -- generic clustering infrastructure in the future. --+-- If the chunk size is 1 or less, 'parListChunk' is equivalent to+-- 'parList'+-- parListChunk :: Int -> Strategy a -> Strategy [a]-parListChunk n strat xs =-  concat `fmap` parList (evalList strat) (chunk n xs)+parListChunk n strat xs+  | n <= 1    = parList strat xs+  | otherwise = concat `fmap` parList (evalList strat) (chunk n xs)  chunk :: Int -> [a] -> [[a]] chunk _ [] = []@@ -452,7 +515,7 @@  -- | A combination of 'parList' and 'map', encapsulating a common pattern: ----- > parMap strat f = withStrategy strat . map f+-- > parMap strat f = withStrategy (parList strat) . map f -- parMap :: Strategy b -> (a -> b) -> [a] -> [b] parMap strat f = (`using` parList strat) . map f @@ -505,7 +568,7 @@ parBuffer :: Int -> Strategy a -> Strategy [a] parBuffer n strat = parBufferWHNF n . map (withStrategy strat) -- Alternative definition via evalBuffer (may compromise firing of RULES):--- parBuffer n strat = evalBuffer n (rpar `dot` strat)+-- parBuffer n strat = evalBuffer n (rparWith strat)  -- Deforest the intermediate list in parBuffer/evalBuffer when it is -- unnecessary:@@ -552,35 +615,35 @@  parTuple2 :: Strategy a -> Strategy b -> Strategy (a,b) parTuple2 strat1 strat2 =-  evalTuple2 (rpar `dot` strat1) (rpar `dot` strat2)+  evalTuple2 (rparWith strat1) (rparWith strat2)  parTuple3 :: Strategy a -> Strategy b -> Strategy c -> Strategy (a,b,c) parTuple3 strat1 strat2 strat3 =-  evalTuple3 (rpar `dot` strat1) (rpar `dot` strat2) (rpar `dot` strat3)+  evalTuple3 (rparWith strat1) (rparWith strat2) (rparWith strat3)  parTuple4 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy (a,b,c,d) parTuple4 strat1 strat2 strat3 strat4 =-  evalTuple4 (rpar `dot` strat1) (rpar `dot` strat2) (rpar `dot` strat3) (rpar `dot` strat4)+  evalTuple4 (rparWith strat1) (rparWith strat2) (rparWith strat3) (rparWith strat4)  parTuple5 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy e -> Strategy (a,b,c,d,e) parTuple5 strat1 strat2 strat3 strat4 strat5 =-  evalTuple5 (rpar `dot` strat1) (rpar `dot` strat2) (rpar `dot` strat3) (rpar `dot` strat4) (rpar `dot` strat5)+  evalTuple5 (rparWith strat1) (rparWith strat2) (rparWith strat3) (rparWith strat4) (rparWith strat5)  parTuple6 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy e -> Strategy f -> Strategy (a,b,c,d,e,f) parTuple6 strat1 strat2 strat3 strat4 strat5 strat6 =-  evalTuple6 (rpar `dot` strat1) (rpar `dot` strat2) (rpar `dot` strat3) (rpar `dot` strat4) (rpar `dot` strat5) (rpar `dot` strat6)+  evalTuple6 (rparWith strat1) (rparWith strat2) (rparWith strat3) (rparWith strat4) (rparWith strat5) (rparWith strat6)  parTuple7 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy e -> Strategy f -> Strategy g -> Strategy (a,b,c,d,e,f,g) parTuple7 strat1 strat2 strat3 strat4 strat5 strat6 strat7 =-  evalTuple7 (rpar `dot` strat1) (rpar `dot` strat2) (rpar `dot` strat3) (rpar `dot` strat4) (rpar `dot` strat5) (rpar `dot` strat6) (rpar `dot` strat7)+  evalTuple7 (rparWith strat1) (rparWith strat2) (rparWith strat3) (rparWith strat4) (rparWith strat5) (rparWith strat6) (rparWith strat7)  parTuple8 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy e -> Strategy f -> Strategy g -> Strategy h -> Strategy (a,b,c,d,e,f,g,h) parTuple8 strat1 strat2 strat3 strat4 strat5 strat6 strat7 strat8 =-  evalTuple8 (rpar `dot` strat1) (rpar `dot` strat2) (rpar `dot` strat3) (rpar `dot` strat4) (rpar `dot` strat5) (rpar `dot` strat6) (rpar `dot` strat7) (rpar `dot` strat8)+  evalTuple8 (rparWith strat1) (rparWith strat2) (rparWith strat3) (rparWith strat4) (rparWith strat5) (rparWith strat6) (rparWith strat7) (rparWith strat8)  parTuple9 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy e -> Strategy f -> Strategy g -> Strategy h -> Strategy i -> Strategy (a,b,c,d,e,f,g,h,i) parTuple9 strat1 strat2 strat3 strat4 strat5 strat6 strat7 strat8 strat9 =-  evalTuple9 (rpar `dot` strat1) (rpar `dot` strat2) (rpar `dot` strat3) (rpar `dot` strat4) (rpar `dot` strat5) (rpar `dot` strat6) (rpar `dot` strat7) (rpar `dot` strat8) (rpar `dot` strat9)+  evalTuple9 (rparWith strat1) (rparWith strat2) (rparWith strat3) (rparWith strat4) (rparWith strat5) (rparWith strat6) (rparWith strat7) (rparWith strat8) (rparWith strat9)  -- -------------------------------------------------------------------------- -- Strategic function application
parallel.cabal view
@@ -1,5 +1,5 @@ name:		parallel-version:	3.1.0.1+version:        3.2.0.0 license:	BSD3 license-file:	LICENSE maintainer:	libraries@haskell.org@@ -11,8 +11,8 @@ cabal-version:  >=1.6  source-repository head-    type:     darcs-    location: http://darcs.haskell.org/packages/parallel/+    type:     git+    location: http://darcs.haskell.org/packages/parallel.git/  library {   exposed-modules:@@ -21,7 +21,7 @@         Control.Parallel.Strategies   extensions:	CPP BangPatterns   build-depends: base    >= 3 && < 5,-                 deepseq >= 1.1 && < 1.2,+                 deepseq >= 1.1 && < 1.3,                  containers >= 0.1 && < 0.5,                  array      >= 0.1 && < 0.4   ghc-options: -Wall