Add scanl1 and scanl1'
authorRoman Leshchinskiy <rl@cse.unsw.edu.au>
Sat, 12 Sep 2009 12:30:51 +0000 (12:30 +0000)
committerRoman Leshchinskiy <rl@cse.unsw.edu.au>
Sat, 12 Sep 2009 12:30:51 +0000 (12:30 +0000)
Data/Vector.hs
Data/Vector/Fusion/Stream.hs
Data/Vector/Fusion/Stream/Monadic.hs
Data/Vector/IVector.hs
Data/Vector/Unboxed.hs

index fa84be3..08384d4 100644 (file)
@@ -54,7 +54,7 @@ module Data.Vector (
   -- * Scans
   prescanl, prescanl',
   postscanl, postscanl',
-  scanl, scanl',
+  scanl, scanl', scanl1, scanl1',
 
   -- * Enumeration
   enumFromTo, enumFromThenTo,
@@ -83,7 +83,7 @@ import Prelude hiding ( length, null,
                         elem, notElem,
                         foldl, foldl1, foldr, foldr1,
                         and, or, sum, product, minimum, maximum,
-                        scanl,
+                        scanl, scanl1,
                         enumFromTo, enumFromThenTo )
 
 import qualified Prelude
@@ -442,6 +442,16 @@ scanl' :: (a -> b -> a) -> a -> Vector b -> Vector a
 {-# INLINE scanl' #-}
 scanl' = IV.scanl'
 
+-- | Scan over a non-empty 'Vector'
+scanl1 :: (a -> a -> a) -> Vector a -> Vector a
+{-# INLINE scanl1 #-}
+scanl1 = IV.scanl1
+
+-- | Scan over a non-empty 'Vector' with a strict accumulator
+scanl1' :: (a -> a -> a) -> Vector a -> Vector a
+{-# INLINE scanl1' #-}
+scanl1' = IV.scanl1'
+
 -- Enumeration
 -- -----------
 
index fd04d48..eac6f1a 100644 (file)
@@ -58,6 +58,7 @@ module Data.Vector.Fusion.Stream (
   prescanl, prescanl',
   postscanl, postscanl',
   scanl, scanl',
+  scanl1, scanl1',
 
   -- * Conversions
   toList, fromList, liftStream,
@@ -81,7 +82,7 @@ import Prelude hiding ( length, null,
                         elem, notElem,
                         foldl, foldl1, foldr, foldr1,
                         and, or,
-                        scanl,
+                        scanl, scanl1,
                         mapM_ )
 
 -- | The type of pure streams 
@@ -355,6 +356,17 @@ scanl' :: (a -> b -> a) -> a -> Stream b -> Stream a
 {-# INLINE scanl' #-}
 scanl' = M.scanl'
 
+-- | Scan over a non-empty 'Stream'
+scanl1 :: (a -> a -> a) -> Stream a -> Stream a
+{-# INLINE scanl1 #-}
+scanl1 = M.scanl1
+
+-- | Scan over a non-empty 'Stream' with a strict accumulator
+scanl1' :: (a -> a -> a) -> Stream a -> Stream a
+{-# INLINE scanl1' #-}
+scanl1' = M.scanl1'
+
+
 -- Comparisons
 -- -----------
 
index c31eae5..955da6c 100644 (file)
@@ -59,6 +59,7 @@ module Data.Vector.Fusion.Stream.Monadic (
   prescanl, prescanlM, prescanl', prescanlM',
   postscanl, postscanlM, postscanl', postscanlM',
   scanl, scanlM, scanl', scanlM',
+  scanl1, scanl1M, scanl1', scanl1M',
 
   -- * Conversions
   toList, fromList
@@ -77,7 +78,7 @@ import Prelude hiding ( length, null,
                         elem, notElem,
                         foldl, foldl1, foldr, foldr1,
                         and, or,
-                        scanl )
+                        scanl, scanl1 )
 import qualified Prelude
 
 -- | Result of taking a single step in a stream
@@ -852,6 +853,62 @@ scanlM' :: Monad m => (a -> b -> m a) -> a -> Stream m b -> Stream m a
 {-# INLINE scanlM' #-}
 scanlM' f z s = z `seq` (z `cons` postscanlM f z s)
 
+-- | Scan over a non-empty 'Stream'
+scanl1 :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
+{-# INLINE scanl1 #-}
+scanl1 f = scanl1M (\x y -> return (f x y))
+
+-- | Scan over a non-empty 'Stream' with a monadic operator
+scanl1M :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
+{-# INLINE_STREAM scanl1M #-}
+scanl1M f (Stream step s sz) = Stream step' (s, Nothing) sz
+  where
+    {-# INLINE step' #-}
+    step' (s, Nothing) = do
+                           r <- step s
+                           case r of
+                             Yield x s' -> return $ Yield x (s', Just x)
+                             Skip    s' -> return $ Skip (s', Nothing)
+                             Done       -> errorEmptyStream "scanl1M"
+
+    step' (s, Just x) = do
+                          r <- step s
+                          case r of
+                            Yield y s' -> do
+                                            z <- f x y
+                                            return $ Yield z (s', Just z)
+                            Skip    s' -> return $ Skip (s', Just x)
+                            Done       -> return Done
+
+-- | Scan over a non-empty 'Stream' with a strict accumulator
+scanl1' :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
+{-# INLINE scanl1' #-}
+scanl1' f = scanl1M' (\x y -> return (f x y))
+
+-- | Scan over a non-empty 'Stream' with a strict accumulator and a monadic
+-- operator
+scanl1M' :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
+{-# INLINE_STREAM scanl1M' #-}
+scanl1M' f (Stream step s sz) = Stream step' (s, Nothing) sz
+  where
+    {-# INLINE step' #-}
+    step' (s, Nothing) = do
+                           r <- step s
+                           case r of
+                             Yield x s' -> x `seq` return (Yield x (s', Just x))
+                             Skip    s' -> return $ Skip (s', Nothing)
+                             Done       -> errorEmptyStream "scanl1M"
+
+    step' (s, Just x) = x `seq`
+                        do
+                          r <- step s
+                          case r of
+                            Yield y s' -> do
+                                            z <- f x y
+                                            z `seq` return (Yield z (s', Just z))
+                            Skip    s' -> return $ Skip (s', Just x)
+                            Done       -> return Done
+
 -- Conversions
 -- -----------
 
index 4832f60..4f7f94d 100644 (file)
@@ -60,7 +60,7 @@ module Data.Vector.IVector (
   -- * Scans
   prescanl, prescanl',
   postscanl, postscanl',
-  scanl, scanl',
+  scanl, scanl', scanl1, scanl1',
 
   -- * Enumeration
   enumFromTo, enumFromThenTo,
@@ -105,7 +105,7 @@ import Prelude hiding ( length, null,
                         elem, notElem,
                         foldl, foldl1, foldr, foldr1,
                         and, or, sum, product, maximum, minimum,
-                        scanl,
+                        scanl, scanl1,
                         enumFromTo, enumFromThenTo )
 
 -- | Class of immutable vectors.
@@ -676,6 +676,16 @@ scanl' :: (IVector v a, IVector v b) => (a -> b -> a) -> a -> v b -> v a
 {-# INLINE scanl' #-}
 scanl' f z = unstream . Stream.scanl' f z . stream
 
+-- | Scan over a non-empty vector
+scanl1 :: IVector v a => (a -> a -> a) -> v a -> v a
+{-# INLINE scanl1 #-}
+scanl1 f = unstream . inplace (MStream.scanl1 f) . stream
+
+-- | Scan over a non-empty vector with a strict accumulator
+scanl1' :: IVector v a => (a -> a -> a) -> v a -> v a
+{-# INLINE scanl1' #-}
+scanl1' f = unstream . inplace (MStream.scanl1' f) . stream
+
 -- Enumeration
 -- -----------
 
index e0b628c..c8dc272 100644 (file)
@@ -54,7 +54,7 @@ module Data.Vector.Unboxed (
   -- * Scans
   prescanl, prescanl',
   postscanl, postscanl',
-  scanl, scanl',
+  scanl, scanl', scanl1, scanl1',
 
   -- * Enumeration
   enumFromTo, enumFromThenTo,
@@ -84,7 +84,7 @@ import Prelude hiding ( length, null,
                         elem, notElem,
                         foldl, foldl1, foldr, foldr1,
                         and, or, sum, product, minimum, maximum,
-                        scanl,
+                        scanl, scanl1,
                         enumFromTo, enumFromThenTo )
 
 import qualified Prelude
@@ -413,6 +413,16 @@ scanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector b -> Vector a
 {-# INLINE scanl' #-}
 scanl' = IV.scanl'
 
+-- | Scan over a non-empty 'Vector'
+scanl1 :: Unbox a => (a -> a -> a) -> Vector a -> Vector a
+{-# INLINE scanl1 #-}
+scanl1 = IV.scanl1
+
+-- | Scan over a non-empty 'Vector' with a strict accumulator
+scanl1' :: Unbox a => (a -> a -> a) -> Vector a -> Vector a
+{-# INLINE scanl1' #-}
+scanl1' = IV.scanl1'
+
 -- Enumeration
 -- -----------