Add replicatePrimM and specialise replicateM
authorRoman Leshchinskiy <rl@cse.unsw.edu.au>
Sat, 14 May 2011 13:49:34 +0000 (13:49 +0000)
committerRoman Leshchinskiy <rl@cse.unsw.edu.au>
Sat, 14 May 2011 13:49:34 +0000 (13:49 +0000)
Data/Vector.hs
Data/Vector/Generic.hs
Data/Vector/Generic/Mutable.hs
Data/Vector/Mutable.hs
Data/Vector/Primitive.hs
Data/Vector/Primitive/Mutable.hs
Data/Vector/Storable.hs
Data/Vector/Storable/Mutable.hs
Data/Vector/Unboxed.hs
Data/Vector/Unboxed/Mutable.hs

index 48a0e7f..ca03ef3 100644 (file)
@@ -49,7 +49,7 @@ module Data.Vector (
   empty, singleton, replicate, generate,
 
   -- ** Monadic initialisation
   empty, singleton, replicate, generate,
 
   -- ** Monadic initialisation
-  replicateM, create,
+  replicateM, replicatePrimM, create,
 
   -- ** Unfolding
   unfoldr, unfoldrN,
 
   -- ** Unfolding
   unfoldr, unfoldrN,
@@ -541,10 +541,21 @@ concat = G.concat
 
 -- | /O(n)/ Execute the monadic action the given number of times and store the
 -- results in a vector.
 
 -- | /O(n)/ Execute the monadic action the given number of times and store the
 -- results in a vector.
+--
+-- /NOTE:/ This function is inefficient because it has to be implemented via
+-- lists. It is specialised to 'replicatePrimM' for 'IO' and 'ST' but
+-- in general, it is better to use the latter directly.
 replicateM :: Monad m => Int -> m a -> m (Vector a)
 {-# INLINE replicateM #-}
 replicateM = G.replicateM
 
 replicateM :: Monad m => Int -> m a -> m (Vector a)
 {-# INLINE replicateM #-}
 replicateM = G.replicateM
 
+-- | /O(n)/ Execute the monadic action the given number of times and store the
+-- results in a vector. This function is significantly more efficient that
+-- 'replicateM' but supports only primitive monads (i.e., 'IO' and 'ST').
+replicatePrimM :: PrimMonad m => Int -> m a -> m (Vector a)
+{-# INLINE replicatePrimM #-}
+replicatePrimM = G.replicatePrimM
+
 -- | Execute the monadic action and freeze the resulting vector.
 --
 -- @
 -- | Execute the monadic action and freeze the resulting vector.
 --
 -- @
index 3a94a3b..e5b3e15 100644 (file)
@@ -39,7 +39,7 @@ module Data.Vector.Generic (
   empty, singleton, replicate, generate,
 
   -- ** Monadic initialisation
   empty, singleton, replicate, generate,
 
   -- ** Monadic initialisation
-  replicateM, create,
+  replicateM, replicatePrimM, create,
 
   -- ** Unfolding
   unfoldr, unfoldrN,
 
   -- ** Unfolding
   unfoldr, unfoldrN,
@@ -619,11 +619,37 @@ concat vs = unstream (Stream.flatten mk step (Exact n) (Stream.fromList vs))
 
 -- | /O(n)/ Execute the monadic action the given number of times and store the
 -- results in a vector.
 
 -- | /O(n)/ Execute the monadic action the given number of times and store the
 -- results in a vector.
+--
+-- /NOTE:/ This function is inefficient because it has to be implemented via
+-- lists. It is specialised to 'replicatePrimM' for 'IO' and 'ST' but
+-- in general, it is better to use the latter directly.
 replicateM :: (Monad m, Vector v a) => Int -> m a -> m (v a)
 replicateM :: (Monad m, Vector v a) => Int -> m a -> m (v a)
--- FIXME: specialise for ST and IO?
 {-# INLINE replicateM #-}
 replicateM n m = fromListN n `Monad.liftM` Monad.replicateM n m
 
 {-# INLINE replicateM #-}
 replicateM n m = fromListN n `Monad.liftM` Monad.replicateM n m
 
+-- | /O(n)/ Execute the monadic action the given number of times and store the
+-- results in a vector. This function is significantly more efficient that
+-- 'replicateM' but supports only primitive monads (i.e., 'IO' and 'ST').
+replicatePrimM :: (PrimMonad m, Vector v a) => Int -> m a -> m (v a)
+{-# INLINE replicatePrimM #-}
+replicatePrimM n m = M.replicateM n m >>= unsafeFreeze
+
+-- FIXME: the next two functions are only necessary for the specialisations
+replicatePrimM_IO :: Vector v a => Int -> IO a -> IO (v a)
+{-# INLINE replicatePrimM_IO #-}
+replicatePrimM_IO = replicatePrimM
+
+replicatePrimM_ST :: Vector v a => Int -> ST s a -> ST s (v a)
+{-# INLINE replicatePrimM_ST #-}
+replicatePrimM_ST = replicatePrimM
+
+{-# RULES
+
+"replicateM(IO)" replicateM = replicatePrimM_IO
+"replicateM(ST)" replicateM = replicatePrimM_ST
+
+ #-}
+
 -- | Execute the monadic action and freeze the resulting vector.
 --
 -- @
 -- | Execute the monadic action and freeze the resulting vector.
 --
 -- @
index 161098a..b1e8b43 100644 (file)
@@ -30,7 +30,7 @@ module Data.Vector.Generic.Mutable (
   -- * Construction
 
   -- ** Initialisation
   -- * Construction
 
   -- ** Initialisation
-  new, unsafeNew, replicate, clone,
+  new, unsafeNew, replicate, replicateM, clone,
 
   -- ** Growing
   grow, unsafeGrow,
 
   -- ** Growing
   grow, unsafeGrow,
@@ -497,6 +497,12 @@ replicate :: (PrimMonad m, MVector v a) => Int -> a -> m (v (PrimState m) a)
 {-# INLINE replicate #-}
 replicate n x = basicUnsafeReplicate (delay_inline max 0 n) x
 
 {-# INLINE replicate #-}
 replicate n x = basicUnsafeReplicate (delay_inline max 0 n) x
 
+-- | Create a mutable vector of the given length (0 if the length is negative)
+-- and fill it with values produced by repeatedly executing the monadic action.
+replicateM :: (PrimMonad m, MVector v a) => Int -> m a -> m (v (PrimState m) a)
+{-# INLINE replicateM #-}
+replicateM n m = munstream (MStream.replicateM n m)
+
 -- | Create a copy of a mutable vector.
 clone :: (PrimMonad m, MVector v a) => v (PrimState m) a -> m (v (PrimState m) a)
 {-# INLINE clone #-}
 -- | Create a copy of a mutable vector.
 clone :: (PrimMonad m, MVector v a) => v (PrimState m) a -> m (v (PrimState m) a)
 {-# INLINE clone #-}
index 51d8e73..e4e50de 100644 (file)
@@ -31,7 +31,7 @@ module Data.Vector.Mutable (
   -- * Construction
 
   -- ** Initialisation
   -- * Construction
 
   -- ** Initialisation
-  new, unsafeNew, replicate, clone,
+  new, unsafeNew, replicate, replicateM, clone,
 
   -- ** Growing
   grow, unsafeGrow,
 
   -- ** Growing
   grow, unsafeGrow,
@@ -264,6 +264,12 @@ replicate :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
 {-# INLINE replicate #-}
 replicate = G.replicate
 
 {-# INLINE replicate #-}
 replicate = G.replicate
 
+-- | Create a mutable vector of the given length (0 if the length is negative)
+-- and fill it with values produced by repeatedly executing the monadic action.
+replicateM :: PrimMonad m => Int -> m a -> m (MVector (PrimState m) a)
+{-# INLINE replicateM #-}
+replicateM = G.replicateM
+
 -- | Create a copy of a mutable vector.
 clone :: PrimMonad m => MVector (PrimState m) a -> m (MVector (PrimState m) a)
 {-# INLINE clone #-}
 -- | Create a copy of a mutable vector.
 clone :: PrimMonad m => MVector (PrimState m) a -> m (MVector (PrimState m) a)
 {-# INLINE clone #-}
index 6ffa72a..cb2138f 100644 (file)
@@ -42,7 +42,7 @@ module Data.Vector.Primitive (
   empty, singleton, replicate, generate,
 
   -- ** Monadic initialisation
   empty, singleton, replicate, generate,
 
   -- ** Monadic initialisation
-  replicateM, create,
+  replicateM, replicatePrimM, create,
 
   -- ** Unfolding
   unfoldr, unfoldrN,
 
   -- ** Unfolding
   unfoldr, unfoldrN,
@@ -539,10 +539,21 @@ concat = G.concat
 
 -- | /O(n)/ Execute the monadic action the given number of times and store the
 -- results in a vector.
 
 -- | /O(n)/ Execute the monadic action the given number of times and store the
 -- results in a vector.
+--
+-- /NOTE:/ This function is inefficient because it has to be implemented via
+-- lists. It is specialised to 'replicatePrimM' for 'IO' and 'ST' but
+-- in general, it is better to use the latter directly.
 replicateM :: (Monad m, Prim a) => Int -> m a -> m (Vector a)
 {-# INLINE replicateM #-}
 replicateM = G.replicateM
 
 replicateM :: (Monad m, Prim a) => Int -> m a -> m (Vector a)
 {-# INLINE replicateM #-}
 replicateM = G.replicateM
 
+-- | /O(n)/ Execute the monadic action the given number of times and store the
+-- results in a vector. This function is significantly more efficient that
+-- 'replicateM' but supports only primitive monads (i.e., 'IO' and 'ST').
+replicatePrimM :: (PrimMonad m, Prim a) => Int -> m a -> m (Vector a)
+{-# INLINE replicatePrimM #-}
+replicatePrimM = G.replicatePrimM
+
 -- | Execute the monadic action and freeze the resulting vector.
 --
 -- @
 -- | Execute the monadic action and freeze the resulting vector.
 --
 -- @
index 9068cb8..624dd4b 100644 (file)
@@ -31,7 +31,7 @@ module Data.Vector.Primitive.Mutable (
   -- * Construction
 
   -- ** Initialisation
   -- * Construction
 
   -- ** Initialisation
-  new, unsafeNew, replicate, clone,
+  new, unsafeNew, replicate, replicateM, clone,
 
   -- ** Growing
   grow, unsafeGrow,
 
   -- ** Growing
   grow, unsafeGrow,
@@ -202,6 +202,12 @@ replicate :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
 {-# INLINE replicate #-}
 replicate = G.replicate
 
 {-# INLINE replicate #-}
 replicate = G.replicate
 
+-- | Create a mutable vector of the given length (0 if the length is negative)
+-- and fill it with values produced by repeatedly executing the monadic action.
+replicateM :: (PrimMonad m, Prim a) => Int -> m a -> m (MVector (PrimState m) a)
+{-# INLINE replicateM #-}
+replicateM = G.replicateM
+
 -- | Create a copy of a mutable vector.
 clone :: (PrimMonad m, Prim a)
       => MVector (PrimState m) a -> m (MVector (PrimState m) a)
 -- | Create a copy of a mutable vector.
 clone :: (PrimMonad m, Prim a)
       => MVector (PrimState m) a -> m (MVector (PrimState m) a)
index b820dba..f11d91b 100644 (file)
@@ -39,7 +39,7 @@ module Data.Vector.Storable (
   empty, singleton, replicate, generate,
 
   -- ** Monadic initialisation
   empty, singleton, replicate, generate,
 
   -- ** Monadic initialisation
-  replicateM, create,
+  replicateM, replicatePrimM, create,
 
   -- ** Unfolding
   unfoldr, unfoldrN,
 
   -- ** Unfolding
   unfoldr, unfoldrN,
@@ -548,10 +548,21 @@ concat = G.concat
 
 -- | /O(n)/ Execute the monadic action the given number of times and store the
 -- results in a vector.
 
 -- | /O(n)/ Execute the monadic action the given number of times and store the
 -- results in a vector.
+--
+-- /NOTE:/ This function is inefficient because it has to be implemented via
+-- lists. It is specialised to 'replicatePrimM' for 'IO' and 'ST' but
+-- in general, it is better to use the latter directly.
 replicateM :: (Monad m, Storable a) => Int -> m a -> m (Vector a)
 {-# INLINE replicateM #-}
 replicateM = G.replicateM
 
 replicateM :: (Monad m, Storable a) => Int -> m a -> m (Vector a)
 {-# INLINE replicateM #-}
 replicateM = G.replicateM
 
+-- | /O(n)/ Execute the monadic action the given number of times and store the
+-- results in a vector. This function is significantly more efficient that
+-- 'replicateM' but supports only primitive monads (i.e., 'IO' and 'ST').
+replicatePrimM :: (PrimMonad m, Storable a) => Int -> m a -> m (Vector a)
+{-# INLINE replicatePrimM #-}
+replicatePrimM = G.replicatePrimM
+
 -- | Execute the monadic action and freeze the resulting vector.
 --
 -- @
 -- | Execute the monadic action and freeze the resulting vector.
 --
 -- @
index d437a54..991f003 100644 (file)
@@ -31,7 +31,7 @@ module Data.Vector.Storable.Mutable(
   -- * Construction
 
   -- ** Initialisation
   -- * Construction
 
   -- ** Initialisation
-  new, unsafeNew, replicate, clone,
+  new, unsafeNew, replicate, replicateM, clone,
 
   -- ** Growing
   grow, unsafeGrow,
 
   -- ** Growing
   grow, unsafeGrow,
@@ -238,6 +238,12 @@ replicate :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a
 {-# INLINE replicate #-}
 replicate = G.replicate
 
 {-# INLINE replicate #-}
 replicate = G.replicate
 
+-- | Create a mutable vector of the given length (0 if the length is negative)
+-- and fill it with values produced by repeatedly executing the monadic action.
+replicateM :: (PrimMonad m, Storable a) => Int -> m a -> m (MVector (PrimState m) a)
+{-# INLINE replicateM #-}
+replicateM = G.replicateM
+
 -- | Create a copy of a mutable vector.
 clone :: (PrimMonad m, Storable a)
       => MVector (PrimState m) a -> m (MVector (PrimState m) a)
 -- | Create a copy of a mutable vector.
 clone :: (PrimMonad m, Storable a)
       => MVector (PrimState m) a -> m (MVector (PrimState m) a)
index 3753c98..cff2278 100644 (file)
@@ -62,7 +62,7 @@ module Data.Vector.Unboxed (
   empty, singleton, replicate, generate,
 
   -- ** Monadic initialisation
   empty, singleton, replicate, generate,
 
   -- ** Monadic initialisation
-  replicateM, create,
+  replicateM, replicatePrimM, create,
 
   -- ** Unfolding
   unfoldr, unfoldrN,
 
   -- ** Unfolding
   unfoldr, unfoldrN,
@@ -518,10 +518,21 @@ concat = G.concat
 
 -- | /O(n)/ Execute the monadic action the given number of times and store the
 -- results in a vector.
 
 -- | /O(n)/ Execute the monadic action the given number of times and store the
 -- results in a vector.
+--
+-- /NOTE:/ This function is inefficient because it has to be implemented via
+-- lists. It is specialised to 'replicatePrimM' for 'IO' and 'ST' but
+-- in general, it is better to use the latter directly.
 replicateM :: (Monad m, Unbox a) => Int -> m a -> m (Vector a)
 {-# INLINE replicateM #-}
 replicateM = G.replicateM
 
 replicateM :: (Monad m, Unbox a) => Int -> m a -> m (Vector a)
 {-# INLINE replicateM #-}
 replicateM = G.replicateM
 
+-- | /O(n)/ Execute the monadic action the given number of times and store the
+-- results in a vector. This function is significantly more efficient that
+-- 'replicateM' but supports only primitive monads (i.e., 'IO' and 'ST').
+replicatePrimM :: (PrimMonad m, Unbox a) => Int -> m a -> m (Vector a)
+{-# INLINE replicatePrimM #-}
+replicatePrimM = G.replicatePrimM
+
 -- | Execute the monadic action and freeze the resulting vector.
 --
 -- @
 -- | Execute the monadic action and freeze the resulting vector.
 --
 -- @
index 60fbfa9..47b22f7 100644 (file)
@@ -29,7 +29,7 @@ module Data.Vector.Unboxed.Mutable (
   -- * Construction
 
   -- ** Initialisation
   -- * Construction
 
   -- ** Initialisation
-  new, unsafeNew, replicate, clone,
+  new, unsafeNew, replicate, replicateM, clone,
 
   -- ** Growing
   grow, unsafeGrow,
 
   -- ** Growing
   grow, unsafeGrow,
@@ -160,6 +160,12 @@ replicate :: (PrimMonad m, Unbox a) => Int -> a -> m (MVector (PrimState m) a)
 {-# INLINE replicate #-}
 replicate = G.replicate
 
 {-# INLINE replicate #-}
 replicate = G.replicate
 
+-- | Create a mutable vector of the given length (0 if the length is negative)
+-- and fill it with values produced by repeatedly executing the monadic action.
+replicateM :: (PrimMonad m, Unbox a) => Int -> m a -> m (MVector (PrimState m) a)
+{-# INLINE replicateM #-}
+replicateM = G.replicateM
+
 -- | Create a copy of a mutable vector.
 clone :: (PrimMonad m, Unbox a)
       => MVector (PrimState m) a -> m (MVector (PrimState m) a)
 -- | Create a copy of a mutable vector.
 clone :: (PrimMonad m, Unbox a)
       => MVector (PrimState m) a -> m (MVector (PrimState m) a)