Added splitAt functions (contributed by Bas van Dijk)
[darcs-mirrors/vector.git] / Data / Vector.hs
index 26460cb..bccf383 100644 (file)
@@ -32,7 +32,7 @@ module Data.Vector (
   length, null,
 
   -- ** Indexing
-  (!), head, last,
+  (!), (!?), head, last,
   unsafeIndex, unsafeHead, unsafeLast,
 
   -- ** Monadic indexing
@@ -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
@@ -140,7 +140,7 @@ module Data.Vector (
   G.convert,
 
   -- ** Mutable vectors
-  thaw, thawMany, copy, unsafeCopy
+  freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy
 ) where
 
 import qualified Data.Vector.Generic as G
@@ -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,
@@ -192,10 +192,14 @@ instance Data a => Data (Vector a) where
 type instance G.Mutable Vector = MVector
 
 instance G.Vector Vector a where
-  {-# INLINE unsafeFreeze #-}
-  unsafeFreeze (MVector i n marr)
+  {-# INLINE basicUnsafeFreeze #-}
+  basicUnsafeFreeze (MVector i n marr)
     = Vector i n `liftM` unsafeFreezeArray marr
 
+  {-# INLINE basicUnsafeThaw #-}
+  basicUnsafeThaw (Vector i n arr)
+    = MVector i n `liftM` unsafeThawArray arr
+
   {-# INLINE basicLength #-}
   basicLength (Vector _ n _) = n
 
@@ -261,6 +265,11 @@ null = G.null
 {-# INLINE (!) #-}
 (!) = (G.!)
 
+-- | O(1) Safe indexing
+(!?) :: Vector a -> Int -> Maybe a
+{-# INLINE (!?) #-}
+(!?) = (G.!?)
+
 -- | /O(1)/ First element
 head :: Vector a -> a
 {-# INLINE head #-}
@@ -378,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
@@ -532,7 +549,8 @@ replicateM = G.replicateM
 -- @
 create :: (forall s. ST s (MVector s a)) -> Vector a
 {-# INLINE create #-}
-create = G.create
+-- NOTE: eta-expanded due to http://hackage.haskell.org/trac/ghc/ticket/4120
+create p = G.create p
 
 
 
@@ -708,7 +726,7 @@ unsafeBackpermute = G.unsafeBackpermute
 -- @
 modify :: (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a
 {-# INLINE modify #-}
-modify = G.modify
+modify p = G.modify p
 
 -- Mapping
 -- -------
@@ -1297,25 +1315,36 @@ fromListN = G.fromListN
 -- Conversions - Mutable vectors
 -- -----------------------------
 
+-- | /O(1)/ Unsafe convert a mutable vector to an immutable one without
+-- copying. The mutable vector may not be used after this operation.
+unsafeFreeze :: PrimMonad m => MVector (PrimState m) a -> m (Vector a)
+{-# INLINE unsafeFreeze #-}
+unsafeFreeze = G.unsafeFreeze
+
+-- | /O(1)/ Unsafely convert an immutable vector to a mutable one without
+-- copying. The immutable vector may not be used after this operation.
+unsafeThaw :: PrimMonad m => Vector a -> m (MVector (PrimState m) a)
+{-# INLINE unsafeThaw #-}
+unsafeThaw = G.unsafeThaw
+
 -- | /O(n)/ Yield a mutable copy of the immutable vector.
 thaw :: PrimMonad m => Vector a -> m (MVector (PrimState m) a)
 {-# INLINE thaw #-}
 thaw = G.thaw
 
--- | /O(n)/ Yield a mutable vector containing copies of each vector in the
--- list.
-thawMany :: PrimMonad m => [Vector a] -> m (MVector (PrimState m) a)
-{-# INLINE thawMany #-}
-thawMany = G.thawMany
+-- | /O(n)/ Yield an immutable copy of the mutable vector.
+freeze :: PrimMonad m => MVector (PrimState m) a -> m (Vector a)
+{-# INLINE freeze #-}
+freeze = G.freeze
 
 -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must
--- have the same length.
+-- have the same length. This is not checked.
 unsafeCopy :: PrimMonad m => MVector (PrimState m) a -> Vector a -> m ()
 {-# INLINE unsafeCopy #-}
 unsafeCopy = G.unsafeCopy
            
 -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must
--- have the same length. This is not checked.
+-- have the same length.
 copy :: PrimMonad m => MVector (PrimState m) a -> Vector a -> m ()
 {-# INLINE copy #-}
 copy = G.copy