Fix INLINE pragmas
[darcs-mirrors/vector.git] / Data / Vector / Generic.hs
index e628d6b..0d9f6cb 100644 (file)
@@ -85,6 +85,10 @@ module Data.Vector.Generic (
   -- * Conversion to/from lists
   toList, fromList, fromListN,
 
+  -- * Monadic operations
+  replicateM, mapM, mapM_, forM, forM_, zipWithM, zipWithM_, filterM,
+  foldM, foldM', fold1M, fold1M',
+
   -- * Destructive operations
   create, modify, copy, unsafeCopy,
 
@@ -114,6 +118,7 @@ import           Data.Vector.Fusion.Util
 
 import Control.Monad.ST ( ST, runST )
 import Control.Monad.Primitive
+import qualified Control.Monad as Monad
 import Prelude hiding ( length, null,
                         replicate, (++),
                         head, last,
@@ -125,7 +130,8 @@ import Prelude hiding ( length, null,
                         foldl, foldl1, foldr, foldr1,
                         all, any, and, or, sum, product, maximum, minimum,
                         scanl, scanl1, scanr, scanr1,
-                        enumFromTo, enumFromThenTo )
+                        enumFromTo, enumFromThenTo,
+                        mapM, mapM_ )
 
 import Data.Typeable ( Typeable1, gcast1 )
 import Data.Data ( Data, DataType, mkNorepType )
@@ -177,10 +183,6 @@ unstream s = new (New.unstream s)
 "clone/new [Vector]" forall p.
   clone (new p) = p
 
- #-}
-
-{-# RULES
-
 "inplace [Vector]"
   forall (f :: forall m. Monad m => MStream m a -> MStream m a) m.
   New.unstream (inplace f (stream (new m))) = New.transform f m
@@ -217,15 +219,11 @@ unstreamR s = new (New.unstreamR s)
 "New.unstreamR/streamR/new [Vector]" forall p.
   New.unstreamR (streamR (new p)) = p
 
- #-}
-
-{-# RULES
-
-"inplace [Vector]"
+"inplace right [Vector]"
   forall (f :: forall m. Monad m => MStream m a -> MStream m a) m.
   New.unstreamR (inplace f (streamR (new m))) = New.transformR f m
 
-"uninplace [Vector]"
+"uninplace right [Vector]"
   forall (f :: forall m. Monad m => MStream m a -> MStream m a) m.
   streamR (new (New.transformR f m)) = inplace f (streamR (new m))
 
@@ -506,7 +504,7 @@ unsafeDrop n v = unsafeSlice n (length v - n) v
 
 unsafeAccum_stream
   :: Vector v a => (a -> b -> a) -> v a -> Stream (Int,b) -> v a
-{-# INLINE unsafeAccum_stream #-}
+{-# INLINE_STREAM unsafeAccum_stream #-}
 unsafeAccum_stream f v s = s `seq` modify (\mv -> M.unsafeAccum f mv s) v
 
 unsafeAccum :: Vector v a => (a -> b -> a) -> v a -> [(Int,b)] -> v a
@@ -525,7 +523,7 @@ unsafeAccumulate_ f v is xs
   = unsafeAccum_stream f v (Stream.zipWith (,) (stream is) (stream xs))
 
 accum_stream :: Vector v a => (a -> b -> a) -> v a -> Stream (Int,b) -> v a
-{-# INLINE accum_stream #-}
+{-# INLINE_STREAM accum_stream #-}
 accum_stream f v s = s `seq` modify (\mv -> M.accum f mv s) v
 
 accum :: Vector v a => (a -> b -> a) -> v a -> [(Int,b)] -> v a
@@ -545,7 +543,7 @@ accumulate_ f v is xs = accum_stream f v (Stream.zipWith (,) (stream is)
                                         
 
 unsafeUpdate_stream :: Vector v a => v a -> Stream (Int,a) -> v a
-{-# INLINE unsafeUpdate_stream #-}
+{-# INLINE_STREAM unsafeUpdate_stream #-}
 unsafeUpdate_stream v s = s `seq` modify (\mv -> M.unsafeUpdate mv s) v
 
 unsafeUpd :: Vector v a => v a -> [(Int, a)] -> v a
@@ -562,7 +560,7 @@ unsafeUpdate_ v is w
   = unsafeUpdate_stream v (Stream.zipWith (,) (stream is) (stream w))
 
 update_stream :: Vector v a => v a -> Stream (Int,a) -> v a
-{-# INLINE update_stream #-}
+{-# INLINE_STREAM update_stream #-}
 update_stream v s = s `seq` modify (\mv -> M.update mv s) v
 
 (//) :: Vector v a => v a -> [(Int, a)] -> v a
@@ -1243,6 +1241,84 @@ fromListN :: Vector v a => Int -> [a] -> v a
 {-# INLINE fromListN #-}
 fromListN n = unstream . Stream.fromListN n
 
+unstreamM :: (Vector v a, Monad m) => MStream m a -> m (v a)
+{-# INLINE_STREAM unstreamM #-}
+unstreamM s = do
+                xs <- MStream.toList s
+                return $ unstream $ Stream.unsafeFromList (MStream.size s) xs
+
+-- Monadic operations
+-- ------------------
+
+-- FIXME: specialise various combinators for ST and IO?
+
+-- | Perform the monadic action the given number of times and store the
+-- results in a vector.
+replicateM :: (Monad m, Vector v a) => Int -> m a -> m (v a)
+{-# INLINE replicateM #-}
+replicateM n m = fromListN n `Monad.liftM` Monad.replicateM n m
+
+-- | Apply the monadic action to all elements of the vector, yielding a vector
+-- of results
+mapM :: (Monad m, Vector v a, Vector v b) => (a -> m b) -> v a -> m (v b)
+{-# INLINE mapM #-}
+mapM f = unstreamM . Stream.mapM f . stream
+
+-- | Apply the monadic action to all elements of a vector and ignore the
+-- results
+mapM_ :: (Monad m, Vector v a) => (a -> m b) -> v a -> m ()
+{-# INLINE mapM_ #-}
+mapM_ f = Stream.mapM_ f . stream
+
+-- | Apply the monadic action to all elements of the vector, yielding a vector
+-- of results
+forM :: (Monad m, Vector v a, Vector v b) => v a -> (a -> m b) -> m (v b)
+{-# INLINE forM #-}
+forM as f = mapM f as
+
+-- | Apply the monadic action to all elements of a vector and ignore the
+-- results
+forM_ :: (Monad m, Vector v a) => v a -> (a -> m b) -> m ()
+{-# INLINE forM_ #-}
+forM_ as f = mapM_ f as
+
+-- | Zip the two vectors with the monadic action and yield a vector of results
+zipWithM :: (Monad m, Vector v a, Vector v b, Vector v c)
+         => (a -> b -> m c) -> v a -> v b -> m (v c)
+{-# INLINE zipWithM #-}
+zipWithM f as bs = unstreamM $ Stream.zipWithM f (stream as) (stream bs)
+
+-- | Zip the two vectors with the monadic action and ignore the results
+zipWithM_ :: (Monad m, Vector v a, Vector v b)
+          => (a -> b -> m c) -> v a -> v b -> m ()
+{-# INLINE zipWithM_ #-}
+zipWithM_ f as bs = Stream.zipWithM_ f (stream as) (stream bs)
+
+-- | Drop elements that do not satisfy the monadic predicate
+filterM :: (Monad m, Vector v a) => (a -> m Bool) -> v a -> m (v a)
+{-# INLINE filterM #-}
+filterM f = unstreamM . Stream.filterM f . stream
+
+-- | Monadic fold
+foldM :: (Monad m, Vector v b) => (a -> b -> m a) -> a -> v b -> m a
+{-# INLINE foldM #-}
+foldM m z = Stream.foldM m z . stream
+
+-- | Monadic fold over non-empty vectors
+fold1M :: (Monad m, Vector v a) => (a -> a -> m a) -> v a -> m a
+{-# INLINE fold1M #-}
+fold1M m = Stream.fold1M m . stream
+
+-- | Monadic fold with strict accumulator
+foldM' :: (Monad m, Vector v b) => (a -> b -> m a) -> a -> v b -> m a
+{-# INLINE foldM' #-}
+foldM' m z = Stream.foldM' m z . stream
+
+-- | Monad fold over non-empty vectors with strict accumulator
+fold1M' :: (Monad m, Vector v a) => (a -> a -> m a) -> v a -> m a
+{-# INLINE fold1M' #-}
+fold1M' m = Stream.fold1M' m . stream
+
 -- Destructive operations
 -- ----------------------
 
@@ -1251,7 +1327,7 @@ create :: Vector v a => (forall s. ST s (Mutable v s a)) -> v a
 {-# INLINE create #-}
 create p = new (New.create p)
 
--- | Apply a destructive operation to a vector. The operation is applied to a
+-- | Apply a destructive operation to a vector. The operation modifies a
 -- copy of the vector unless it can be safely performed in place.
 modify :: Vector v a => (forall s. Mutable v s a -> ST s ()) -> v a -> v a
 {-# INLINE modify #-}