From: Roman Leshchinskiy
Date: Sat, 14 May 2011 13:49:34 +0000 (+0000)
Subject: Add replicatePrimM and specialise replicateM
X-Git-Url: http://git.haskell.org/darcs-mirrors/vector.git/commitdiff_plain/7efe289566bea0219f8c872ad818d57d250bd671
Add replicatePrimM and specialise replicateM
---
diff --git a/Data/Vector.hs b/Data/Vector.hs
index 48a0e7f..ca03ef3 100644
--- a/Data/Vector.hs
+++ b/Data/Vector.hs
@@ -49,7 +49,7 @@ module Data.Vector (
empty, singleton, replicate, generate,
-- ** Monadic initialisation
- replicateM, create,
+ replicateM, replicatePrimM, create,
-- ** 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.
+--
+-- /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
+-- | /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.
--
-- @
diff --git a/Data/Vector/Generic.hs b/Data/Vector/Generic.hs
index 3a94a3b..e5b3e15 100644
--- a/Data/Vector/Generic.hs
+++ b/Data/Vector/Generic.hs
@@ -39,7 +39,7 @@ module Data.Vector.Generic (
empty, singleton, replicate, generate,
-- ** Monadic initialisation
- replicateM, create,
+ replicateM, replicatePrimM, create,
-- ** 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.
+--
+-- /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)
--- FIXME: specialise for ST and IO?
{-# 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.
--
-- @
diff --git a/Data/Vector/Generic/Mutable.hs b/Data/Vector/Generic/Mutable.hs
index 161098a..b1e8b43 100644
--- a/Data/Vector/Generic/Mutable.hs
+++ b/Data/Vector/Generic/Mutable.hs
@@ -30,7 +30,7 @@ module Data.Vector.Generic.Mutable (
-- * Construction
-- ** Initialisation
- new, unsafeNew, replicate, clone,
+ new, unsafeNew, replicate, replicateM, clone,
-- ** 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
+-- | 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 #-}
diff --git a/Data/Vector/Mutable.hs b/Data/Vector/Mutable.hs
index 51d8e73..e4e50de 100644
--- a/Data/Vector/Mutable.hs
+++ b/Data/Vector/Mutable.hs
@@ -31,7 +31,7 @@ module Data.Vector.Mutable (
-- * Construction
-- ** Initialisation
- new, unsafeNew, replicate, clone,
+ new, unsafeNew, replicate, replicateM, clone,
-- ** Growing
grow, unsafeGrow,
@@ -264,6 +264,12 @@ replicate :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
{-# 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 #-}
diff --git a/Data/Vector/Primitive.hs b/Data/Vector/Primitive.hs
index 6ffa72a..cb2138f 100644
--- a/Data/Vector/Primitive.hs
+++ b/Data/Vector/Primitive.hs
@@ -42,7 +42,7 @@ module Data.Vector.Primitive (
empty, singleton, replicate, generate,
-- ** Monadic initialisation
- replicateM, create,
+ replicateM, replicatePrimM, create,
-- ** 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.
+--
+-- /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
+-- | /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.
--
-- @
diff --git a/Data/Vector/Primitive/Mutable.hs b/Data/Vector/Primitive/Mutable.hs
index 9068cb8..624dd4b 100644
--- a/Data/Vector/Primitive/Mutable.hs
+++ b/Data/Vector/Primitive/Mutable.hs
@@ -31,7 +31,7 @@ module Data.Vector.Primitive.Mutable (
-- * Construction
-- ** Initialisation
- new, unsafeNew, replicate, clone,
+ new, unsafeNew, replicate, replicateM, clone,
-- ** Growing
grow, unsafeGrow,
@@ -202,6 +202,12 @@ replicate :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
{-# 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)
diff --git a/Data/Vector/Storable.hs b/Data/Vector/Storable.hs
index b820dba..f11d91b 100644
--- a/Data/Vector/Storable.hs
+++ b/Data/Vector/Storable.hs
@@ -39,7 +39,7 @@ module Data.Vector.Storable (
empty, singleton, replicate, generate,
-- ** Monadic initialisation
- replicateM, create,
+ replicateM, replicatePrimM, create,
-- ** 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.
+--
+-- /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
+-- | /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.
--
-- @
diff --git a/Data/Vector/Storable/Mutable.hs b/Data/Vector/Storable/Mutable.hs
index d437a54..991f003 100644
--- a/Data/Vector/Storable/Mutable.hs
+++ b/Data/Vector/Storable/Mutable.hs
@@ -31,7 +31,7 @@ module Data.Vector.Storable.Mutable(
-- * Construction
-- ** Initialisation
- new, unsafeNew, replicate, clone,
+ new, unsafeNew, replicate, replicateM, clone,
-- ** Growing
grow, unsafeGrow,
@@ -238,6 +238,12 @@ replicate :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a
{-# 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)
diff --git a/Data/Vector/Unboxed.hs b/Data/Vector/Unboxed.hs
index 3753c98..cff2278 100644
--- a/Data/Vector/Unboxed.hs
+++ b/Data/Vector/Unboxed.hs
@@ -62,7 +62,7 @@ module Data.Vector.Unboxed (
empty, singleton, replicate, generate,
-- ** Monadic initialisation
- replicateM, create,
+ replicateM, replicatePrimM, create,
-- ** 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.
+--
+-- /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
+-- | /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.
--
-- @
diff --git a/Data/Vector/Unboxed/Mutable.hs b/Data/Vector/Unboxed/Mutable.hs
index 60fbfa9..47b22f7 100644
--- a/Data/Vector/Unboxed/Mutable.hs
+++ b/Data/Vector/Unboxed/Mutable.hs
@@ -29,7 +29,7 @@ module Data.Vector.Unboxed.Mutable (
-- * Construction
-- ** Initialisation
- new, unsafeNew, replicate, clone,
+ new, unsafeNew, replicate, replicateM, clone,
-- ** Growing
grow, unsafeGrow,
@@ -160,6 +160,12 @@ replicate :: (PrimMonad m, Unbox a) => Int -> a -> m (MVector (PrimState m) a)
{-# 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)