Added splitAt functions (contributed by Bas van Dijk)
authorRoman Leshchinskiy <rl@cse.unsw.edu.au>
Wed, 11 May 2011 20:04:37 +0000 (20:04 +0000)
committerRoman Leshchinskiy <rl@cse.unsw.edu.au>
Wed, 11 May 2011 20:04:37 +0000 (20:04 +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 257012a..bccf383 100644 (file)
@@ -40,7 +40,7 @@ module Data.Vector (
   unsafeIndexM, unsafeHeadM, unsafeLastM,
 
   -- ** Extracting subvectors (slicing)
-  slice, init, tail, take, drop,
+  slice, init, tail, take, drop, splitAt,
   unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
 
   -- * Construction
@@ -155,7 +155,7 @@ import Control.Monad.Primitive
 import Prelude hiding ( length, null,
                         replicate, (++), concat,
                         head, last,
-                        init, tail, take, drop, reverse,
+                        init, tail, take, drop, splitAt, reverse,
                         map, concatMap,
                         zipWith, zipWith3, zip, zip3, unzip, unzip3,
                         filter, takeWhile, dropWhile, span, break,
@@ -387,6 +387,14 @@ drop :: Int -> Vector a -> Vector a
 {-# INLINE drop #-}
 drop = G.drop
 
+-- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying.
+--
+-- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@
+-- but slightly more efficient.
+{-# INLINE splitAt #-}
+splitAt :: Int -> Vector a -> (Vector a, Vector a)
+splitAt = G.splitAt
+
 -- | /O(1)/ Yield a slice of the vector without copying. The vector must
 -- contain at least @i+n@ elements but this is not checked.
 unsafeSlice :: Int   -- ^ @i@ starting index
index 1fd8937..3a7836e 100644 (file)
@@ -30,7 +30,7 @@ module Data.Vector.Generic (
   unsafeIndexM, unsafeHeadM, unsafeLastM,
 
   -- ** Extracting subvectors (slicing)
-  slice, init, tail, take, drop,
+  slice, init, tail, take, drop, splitAt,
   unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
 
   -- * Construction
@@ -170,7 +170,7 @@ import qualified Data.List as List
 import Prelude hiding ( length, null,
                         replicate, (++), concat,
                         head, last,
-                        init, tail, take, drop, reverse,
+                        init, tail, take, drop, splitAt, reverse,
                         map, concat, concatMap,
                         zipWith, zipWith3, zip, zip3, unzip, unzip3,
                         filter, takeWhile, dropWhile, span, break,
@@ -405,6 +405,20 @@ drop n v = unsafeSlice (delay_inline min n' len)
   where n' = max n 0
         len = length v
 
+-- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying.
+--
+-- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@
+-- but slightly more efficient.
+{-# INLINE_STREAM splitAt #-}
+splitAt :: Vector v a => Int -> v a -> (v a, v a)
+splitAt n v = ( unsafeSlice 0 m v
+              , unsafeSlice m (delay_inline max 0 (len - n')) v
+              )
+    where
+      m   = delay_inline min n' len
+      n'  = max n 0
+      len = length v
+
 -- | /O(1)/ Yield a slice of the vector without copying. The vector must
 -- contain at least @i+n@ elements but this is not checked.
 unsafeSlice :: Vector v a => Int   -- ^ @i@ starting index
index 7837140..d5d5e94 100644 (file)
@@ -21,7 +21,7 @@ module Data.Vector.Generic.Mutable (
   length, null,
 
   -- ** Extracting subvectors
-  slice, init, tail, take, drop,
+  slice, init, tail, take, drop, splitAt,
   unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
 
   -- ** Overlapping
@@ -68,7 +68,7 @@ import           Data.Vector.Fusion.Util        ( delay_inline )
 import Control.Monad.Primitive ( PrimMonad, PrimState )
 
 import Prelude hiding ( length, null, replicate, reverse, map, read,
-                        take, drop, init, tail )
+                        take, drop, splitAt, init, tail )
 
 #include "vector.h"
 
@@ -411,6 +411,16 @@ drop n v = unsafeSlice (min m n') (max 0 (m - n')) v
     n' = max n 0
     m  = length v
 
+{-# INLINE splitAt #-}
+splitAt :: MVector v a => Int -> v s a -> (v s a, v s a)
+splitAt n v = ( unsafeSlice 0 m v
+              , unsafeSlice m (max 0 (len - n')) v
+              )
+    where
+      m   = min n' len
+      n'  = max n 0
+      len = length v
+
 init :: MVector v a => v s a -> v s a
 {-# INLINE init #-}
 init v = slice 0 (length v - 1) v
index 2d58dc4..9b866ff 100644 (file)
@@ -22,7 +22,7 @@ module Data.Vector.Mutable (
   length, null,
 
   -- ** Extracting subvectors
-  slice, init, tail, take, drop,
+  slice, init, tail, take, drop, splitAt,
   unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
 
   -- ** Overlapping
@@ -57,7 +57,7 @@ import           Data.Primitive.Array
 import           Control.Monad.Primitive
 
 import Prelude hiding ( length, null, replicate, reverse, map, read,
-                        take, drop, init, tail )
+                        take, drop, splitAt, init, tail )
 
 import Data.Typeable ( Typeable )
 
@@ -139,6 +139,10 @@ drop :: Int -> MVector s a -> MVector s a
 {-# INLINE drop #-}
 drop = G.drop
 
+{-# INLINE splitAt #-}
+splitAt :: Int -> MVector s a -> (MVector s a, MVector s a)
+splitAt = G.splitAt
+
 init :: MVector s a -> MVector s a
 {-# INLINE init #-}
 init = G.init
index 0ae435d..6ffa72a 100644 (file)
@@ -33,7 +33,7 @@ module Data.Vector.Primitive (
   unsafeIndexM, unsafeHeadM, unsafeLastM,
 
   -- ** Extracting subvectors (slicing)
-  slice, init, tail, take, drop,
+  slice, init, tail, take, drop, splitAt,
   unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
 
   -- * Construction
@@ -145,7 +145,7 @@ import Control.Monad.Primitive
 import Prelude hiding ( length, null,
                         replicate, (++), concat,
                         head, last,
-                        init, tail, take, drop, reverse,
+                        init, tail, take, drop, splitAt, reverse,
                         map, concatMap,
                         zipWith, zipWith3, zip, zip3, unzip, unzip3,
                         filter, takeWhile, dropWhile, span, break,
@@ -388,6 +388,14 @@ drop :: Prim a => Int -> Vector a -> Vector a
 {-# INLINE drop #-}
 drop = G.drop
 
+-- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying.
+--
+-- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@
+-- but slightly more efficient.
+{-# INLINE splitAt #-}
+splitAt :: Prim a => Int -> Vector a -> (Vector a, Vector a)
+splitAt = G.splitAt
+
 -- | /O(1)/ Yield a slice of the vector without copying. The vector must
 -- contain at least @i+n@ elements but this is not checked.
 unsafeSlice :: Prim a => Int   -- ^ @i@ starting index
index 4fc8d38..fec69f6 100644 (file)
@@ -22,7 +22,7 @@ module Data.Vector.Primitive.Mutable (
   length, null,
 
   -- ** Extracting subvectors
-  slice, init, tail, take, drop,
+  slice, init, tail, take, drop, splitAt,
   unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
 
   -- ** Overlapping
@@ -59,7 +59,7 @@ import           Control.Monad.Primitive
 import           Control.Monad ( liftM )
 
 import Prelude hiding ( length, null, replicate, reverse, map, read,
-                        take, drop, init, tail )
+                        take, drop, splitAt, init, tail )
 
 import Data.Typeable ( Typeable )
 
@@ -131,6 +131,10 @@ drop :: Prim a => Int -> MVector s a -> MVector s a
 {-# INLINE drop #-}
 drop = G.drop
 
+splitAt :: Prim a => Int -> MVector s a -> (MVector s a, MVector s a)
+{-# INLINE splitAt #-}
+splitAt = G.splitAt
+
 init :: Prim a => MVector s a -> MVector s a
 {-# INLINE init #-}
 init = G.init
index cf5b9bb..b820dba 100644 (file)
@@ -30,7 +30,7 @@ module Data.Vector.Storable (
   unsafeIndexM, unsafeHeadM, unsafeLastM,
 
   -- ** Extracting subvectors (slicing)
-  slice, init, tail, take, drop,
+  slice, init, tail, take, drop, splitAt,
   unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
 
   -- * Construction
@@ -148,7 +148,7 @@ import Control.Monad.Primitive
 import Prelude hiding ( length, null,
                         replicate, (++), concat,
                         head, last,
-                        init, tail, take, drop, reverse,
+                        init, tail, take, drop, splitAt, reverse,
                         map, concatMap,
                         zipWith, zipWith3, zip, zip3, unzip, unzip3,
                         filter, takeWhile, dropWhile, span, break,
@@ -397,6 +397,14 @@ drop :: Storable a => Int -> Vector a -> Vector a
 {-# INLINE drop #-}
 drop = G.drop
 
+-- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying.
+--
+-- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@
+-- but slightly more efficient.
+{-# INLINE splitAt #-}
+splitAt :: Storable a => Int -> Vector a -> (Vector a, Vector a)
+splitAt = G.splitAt
+
 -- | /O(1)/ Yield a slice of the vector without copying. The vector must
 -- contain at least @i+n@ elements but this is not checked.
 unsafeSlice :: Storable a => Int   -- ^ @i@ starting index
index 967da9c..409885e 100644 (file)
@@ -22,7 +22,7 @@ module Data.Vector.Storable.Mutable(
   length, null,
 
   -- ** Extracting subvectors
-  slice, init, tail, take, drop,
+  slice, init, tail, take, drop, splitAt,
   unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
 
   -- ** Overlapping
@@ -67,7 +67,7 @@ import Foreign.C.Types ( CInt )
 import Control.Monad.Primitive
 
 import Prelude hiding ( length, null, replicate, reverse, map, read,
-                        take, drop, init, tail )
+                        take, drop, splitAt, init, tail )
 
 import Data.Typeable ( Typeable )
 
@@ -149,6 +149,10 @@ drop :: Storable a => Int -> MVector s a -> MVector s a
 {-# INLINE drop #-}
 drop = G.drop
 
+splitAt :: Storable a => Int -> MVector s a -> (MVector s a, MVector s a)
+{-# INLINE splitAt #-}
+splitAt = G.splitAt
+
 init :: Storable a => MVector s a -> MVector s a
 {-# INLINE init #-}
 init = G.init
index d44f202..7906d71 100644 (file)
@@ -53,7 +53,7 @@ module Data.Vector.Unboxed (
   unsafeIndexM, unsafeHeadM, unsafeLastM,
 
   -- ** Extracting subvectors (slicing)
-  slice, init, tail, take, drop,
+  slice, init, tail, take, drop, splitAt,
   unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
 
   -- * Construction
@@ -166,7 +166,7 @@ import Control.Monad.Primitive
 import Prelude hiding ( length, null,
                         replicate, (++), concat,
                         head, last,
-                        init, tail, take, drop, reverse,
+                        init, tail, take, drop, splitAt, reverse,
                         map, concatMap,
                         zipWith, zipWith3, zip, zip3, unzip, unzip3,
                         filter, takeWhile, dropWhile, span, break,
@@ -363,6 +363,14 @@ drop :: Unbox a => Int -> Vector a -> Vector a
 {-# INLINE drop #-}
 drop = G.drop
 
+-- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying.
+--
+-- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@
+-- but slightly more efficient.
+{-# INLINE splitAt #-}
+splitAt :: Unbox a => Int -> Vector a -> (Vector a, Vector a)
+splitAt = G.splitAt
+
 -- | /O(1)/ Yield a slice of the vector without copying. The vector must
 -- contain at least @i+n@ elements but this is not checked.
 unsafeSlice :: Unbox a => Int   -- ^ @i@ starting index
index b0994ab..c959b2f 100644 (file)
@@ -20,7 +20,7 @@ module Data.Vector.Unboxed.Mutable (
   length, null,
 
   -- ** Extracting subvectors
-  slice, init, tail, take, drop,
+  slice, init, tail, take, drop, splitAt,
   unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
 
   -- ** Overlapping
@@ -60,7 +60,7 @@ import qualified Data.Vector.Generic.Mutable as G
 import Control.Monad.Primitive
 
 import Prelude hiding ( length, null, replicate, reverse, map, read,
-                        take, drop, init, tail,
+                        take, drop, splitAt, init, tail,
                         zip, zip3, unzip, unzip3 )
 
 #include "vector.h"
@@ -94,6 +94,10 @@ drop :: Unbox a => Int -> MVector s a -> MVector s a
 {-# INLINE drop #-}
 drop = G.drop
 
+splitAt :: Unbox a => Int -> MVector s a -> (MVector s a, MVector s a)
+{-# INLINE splitAt #-}
+splitAt = G.splitAt
+
 init :: Unbox a => MVector s a -> MVector s a
 {-# INLINE init #-}
 init = G.init