diff --git a/Control/Parallel/Strategies.hs b/Control/Parallel/Strategies.hs
--- a/Control/Parallel/Strategies.hs
+++ b/Control/Parallel/Strategies.hs
@@ -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
diff --git a/parallel.cabal b/parallel.cabal
--- a/parallel.cabal
+++ b/parallel.cabal
@@ -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
