vector 0.6 → 0.6.0.1
raw patch · 13 files changed
+4865/−3497 lines, 13 files
Files
- Changelog +30/−0
- Data/Vector.hs +1262/−1078
- Data/Vector/Generic.hs +1657/−1352
- Data/Vector/Generic/Base.hs +54/−8
- Data/Vector/Primitive.hs +591/−344
- Data/Vector/Storable.hs +592/−357
- Data/Vector/Unboxed.hs +642/−350
- Data/Vector/Unboxed/Base.hs +2/−0
- benchmarks/vector-benchmarks.cabal +2/−2
- internal/GenUnboxTuple.hs +4/−2
- internal/unbox-tuple-instances +20/−0
- tests/vector-tests.cabal +3/−3
- vector.cabal +6/−1
+ Changelog view
@@ -0,0 +1,30 @@+Changes 0.6 - 0.6.0.1++ * Improved documentation++Changes 0.5 - 0.6++ * More efficient representation of Storable vectors++ * Block copy operations used when possible++ * Typeable and Data instances++ * Monadic combinators (replicateM, mapM etc.)++ * Better support for recycling (see create and modify)++ * Performance improvements++Changes 0.4.2 - 0.5++ * Unboxed vectors of primitive types and tuples.++ * Redesigned interface between mutable and immutable vectors. It now+ includes the popular unsafeFreeze primitive.++ * Many new combinators.++ * Significant performance improvements. Unboxed vectors are usually faster+ than primitive unboxed DPH arrays.+
Data/Vector.hs view
@@ -23,1084 +23,1268 @@ -- module Data.Vector (-- -- * The pure and mutable array types- Vector, MVector,-- -- * Constructing vectors- empty,- singleton,- cons,- snoc,- (++),- replicate,- generate,- force,-- -- * Operations based on length information- length,- null,-- -- * Accessing individual elements- (!),- head,- last,-- -- ** Accessors in a monad- indexM,- headM,- lastM,-- -- ** Accessor functions with no bounds checking- unsafeIndex, unsafeHead, unsafeLast,- unsafeIndexM, unsafeHeadM, unsafeLastM,-- -- * Subvectors- init,- tail,- take,- drop,- slice,-- -- * Subvector construction without bounds checks- unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,-- -- * Permutations- accum, accumulate, accumulate_,- (//), update, update_,- backpermute, reverse,- unsafeAccum, unsafeAccumulate, unsafeAccumulate_,- unsafeUpd, unsafeUpdate, unsafeUpdate_,- unsafeBackpermute,-- -- * Mapping- map, imap, concatMap,-- -- * Zipping and unzipping- zipWith, zipWith3, zipWith4, zipWith5, zipWith6,- izipWith, izipWith3, izipWith4, izipWith5, izipWith6,- zip, zip3, zip4, zip5, zip6,- unzip, unzip3, unzip4, unzip5, unzip6,-- -- * Filtering- filter, ifilter, takeWhile, dropWhile,- partition, unstablePartition, span, break,-- -- * Searching- elem, notElem, find, findIndex, findIndices, elemIndex, elemIndices,-- -- * Folding- foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1',- ifoldl, ifoldl', ifoldr, ifoldr',-- -- * Specialised folds- all, any, and, or,- sum, product,- maximum, maximumBy, minimum, minimumBy,- minIndex, minIndexBy, maxIndex, maxIndexBy,-- -- * Unfolding- unfoldr, unfoldrN,-- -- * Scans- prescanl, prescanl',- postscanl, postscanl',- scanl, scanl', scanl1, scanl1',- prescanr, prescanr',- postscanr, postscanr',- scanr, scanr', scanr1, scanr1',-- -- * Enumeration- enumFromN, enumFromStepN, enumFromTo, enumFromThenTo,-- -- * 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-) where--import qualified Data.Vector.Generic as G-import Data.Vector.Mutable ( MVector(..) )-import Data.Primitive.Array-import qualified Data.Vector.Fusion.Stream as Stream--import Control.Monad ( liftM )-import Control.Monad.ST ( ST )-import Control.Monad.Primitive--import Prelude hiding ( length, null,- replicate, (++),- head, last,- init, tail, take, drop, reverse,- map, concatMap,- zipWith, zipWith3, zip, zip3, unzip, unzip3,- filter, takeWhile, dropWhile, span, break,- elem, notElem,- foldl, foldl1, foldr, foldr1,- all, any, and, or, sum, product, minimum, maximum,- scanl, scanl1, scanr, scanr1,- enumFromTo, enumFromThenTo,- mapM, mapM_ )--import qualified Prelude--import Data.Typeable ( Typeable )-import Data.Data ( Data(..) )---- | Boxed vectors, supporting efficient slicing.-data Vector a = Vector {-# UNPACK #-} !Int- {-# UNPACK #-} !Int- {-# UNPACK #-} !(Array a)- deriving ( Typeable )--instance Show a => Show (Vector a) where- show = (Prelude.++ " :: Data.Vector.Vector") . ("fromList " Prelude.++) . show . toList--instance Data a => Data (Vector a) where- gfoldl = G.gfoldl- toConstr _ = error "toConstr"- gunfold _ _ = error "gunfold"- dataTypeOf _ = G.mkType "Data.Vector.Vector"- dataCast1 = G.dataCast--type instance G.Mutable Vector = MVector--instance G.Vector Vector a where- {-# INLINE unsafeFreeze #-}- unsafeFreeze (MVector i n marr)- = Vector i n `liftM` unsafeFreezeArray marr-- {-# INLINE basicLength #-}- basicLength (Vector _ n _) = n-- {-# INLINE basicUnsafeSlice #-}- basicUnsafeSlice j n (Vector i _ arr) = Vector (i+j) n arr-- {-# INLINE basicUnsafeIndexM #-}- basicUnsafeIndexM (Vector i _ arr) j = indexArrayM arr (i+j)---- See http://trac.haskell.org/vector/ticket/12-instance Eq a => Eq (Vector a) where- {-# INLINE (==) #-}- xs == ys = Stream.eq (G.stream xs) (G.stream ys)-- {-# INLINE (/=) #-}- xs /= ys = not (Stream.eq (G.stream xs) (G.stream ys))---- See http://trac.haskell.org/vector/ticket/12-instance Ord a => Ord (Vector a) where- {-# INLINE compare #-}- compare xs ys = Stream.cmp (G.stream xs) (G.stream ys)-- {-# INLINE (<) #-}- xs < ys = Stream.cmp (G.stream xs) (G.stream ys) == LT-- {-# INLINE (<=) #-}- xs <= ys = Stream.cmp (G.stream xs) (G.stream ys) /= GT-- {-# INLINE (>) #-}- xs > ys = Stream.cmp (G.stream xs) (G.stream ys) == GT-- {-# INLINE (>=) #-}- xs >= ys = Stream.cmp (G.stream xs) (G.stream ys) /= LT---- Length--- ---------- |/O(1)/. Yield the length of a vector as an 'Int'-length :: Vector a -> Int-{-# INLINE length #-}-length = G.length---- |/O(1)/. 'null' tests whether the given array is empty.-null :: Vector a -> Bool-{-# INLINE null #-}-null = G.null---- Construction--- ---------------- |/O(1)/. 'empty' builds a vector of size zero.-empty :: Vector a-{-# INLINE empty #-}-empty = G.empty---- |/O(1)/, Vector with exactly one element-singleton :: a -> Vector a-{-# INLINE singleton #-}-singleton = G.singleton---- |/O(n)/. @'replicate' n e@ yields a vector of length @n@ storing @e@ at each position-replicate :: Int -> a -> Vector a-{-# INLINE replicate #-}-replicate = G.replicate---- |/O(n)/, Generate a vector of the given length by applying a (pure)--- generator function to each index-generate :: Int -> (Int -> a) -> Vector a-{-# INLINE generate #-}-generate = G.generate---- |/O(n)/, Prepend an element to an array.-cons :: a -> Vector a -> Vector a-{-# INLINE cons #-}-cons = G.cons---- |/O(n)/, Append an element to an array.-snoc :: Vector a -> a -> Vector a-{-# INLINE snoc #-}-snoc = G.snoc--infixr 5 ++---- |/O(n)/, Concatenate two vectors-(++) :: Vector a -> Vector a -> Vector a-{-# INLINE (++) #-}-(++) = (G.++)---- |/O(n)/, Create a copy of a vector.--- @force@ is useful when dealing with slices, as the garbage collector--- may be able to free the original vector if no further references are held.----force :: Vector a -> Vector a-{-# INLINE force #-}-force = G.force---- Accessing individual elements--- --------------------------------- |/O(1)/. Read the element in the vector at the given index.-(!) :: Vector a -> Int -> a-{-# INLINE (!) #-}-(!) = (G.!)---- |/O(1)/. 'head' returns the first element of the vector-head :: Vector a -> a-{-# INLINE head #-}-head = G.head---- |/O(n)/. 'last' yields the last element of an array.-last :: Vector a -> a-{-# INLINE last #-}-last = G.last---- |/O(1)/, Unsafe indexing without bounds checking------ By not performing bounds checks, this function may be faster when--- this function is used in an inner loop)----unsafeIndex :: Vector a -> Int -> a-{-# INLINE unsafeIndex #-}-unsafeIndex = G.unsafeIndex---- |/O(1)/, Yield the first element of a vector without checking if the vector is empty------ By not performing bounds checks, this function may be faster when--- this function is used in an inner loop)-unsafeHead :: Vector a -> a-{-# INLINE unsafeHead #-}-unsafeHead = G.unsafeHead---- | Yield the last element of a vector without checking if the vector is empty------ By not performing bounds checks, this function may be faster when--- this function is used in an inner loop)-unsafeLast :: Vector a -> a-{-# INLINE unsafeLast #-}-unsafeLast = G.unsafeLast---- | Monadic indexing which can be strict in the vector while remaining lazy in the element-indexM :: Monad m => Vector a -> Int -> m a-{-# INLINE indexM #-}-indexM = G.indexM---- | Monadic head which can be strict in the vector while remaining lazy in the element-headM :: Monad m => Vector a -> m a-{-# INLINE headM #-}-headM = G.headM---- | Monadic last which can be strict in the vector while remaining lazy in the element-lastM :: Monad m => Vector a -> m a-{-# INLINE lastM #-}-lastM = G.lastM---- | Unsafe monadic indexing without bounds checks-unsafeIndexM :: Monad m => Vector a -> Int -> m a-{-# INLINE unsafeIndexM #-}-unsafeIndexM = G.unsafeIndexM---- | Unsafe monadic head (access the first element) without bounds checks-unsafeHeadM :: Monad m => Vector a -> m a-{-# INLINE unsafeHeadM #-}-unsafeHeadM = G.unsafeHeadM---- | Unsafe monadic last (access the last element) without bounds checks-unsafeLastM :: Monad m => Vector a -> m a-{-# INLINE unsafeLastM #-}-unsafeLastM = G.unsafeLastM---- Subarrays--- ------------- | /O(1)/, Yield a part of the vector without copying it.----slice :: Int -- ^ starting index- -> Int -- ^ length- -> Vector a- -> Vector a-{-# INLINE slice #-}-slice = G.slice---- |/O(1)/, Yield all but the last element without copying.-init :: Vector a -> Vector a-{-# INLINE init #-}-init = G.init---- |/O(1), Yield all but the first element (without copying).-tail :: Vector a -> Vector a-{-# INLINE tail #-}-tail = G.tail---- |/O(1)/, Yield the first @n@ elements without copying.-take :: Int -> Vector a -> Vector a-{-# INLINE take #-}-take = G.take---- |/O(1)/, Yield all but the first @n@ elements without copying.-drop :: Int -> Vector a -> Vector a-{-# INLINE drop #-}-drop = G.drop---- |/O(1)/, Unsafely yield a part of the vector without copying it and without--- performing bounds checks.-unsafeSlice :: Int -- ^ starting index- -> Int -- ^ length- -> Vector a- -> Vector a-{-# INLINE unsafeSlice #-}-unsafeSlice = G.unsafeSlice---- |/O(1)/, Zero-copying 'init' without bounds checks.-unsafeInit :: Vector a -> Vector a-{-# INLINE unsafeInit #-}-unsafeInit = G.unsafeInit---- |/O(1)/, Zero-copying 'tail' without bounds checks.-unsafeTail :: Vector a -> Vector a-{-# INLINE unsafeTail #-}-unsafeTail = G.unsafeTail---- |/O(1)/, Zero-copying 'take' without bounds checks.-unsafeTake :: Int -> Vector a -> Vector a-{-# INLINE unsafeTake #-}-unsafeTake = G.unsafeTake---- |/O(1)/, Zero-copying 'drop' without bounds checks.-unsafeDrop :: Int -> Vector a -> Vector a-{-# INLINE unsafeDrop #-}-unsafeDrop = G.unsafeDrop---- Permutations--- ---------------- TODO there is no documentation for the accum* family of functions---- | TODO unsafeAccum.-unsafeAccum :: (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a-{-# INLINE unsafeAccum #-}-unsafeAccum = G.unsafeAccum---- | TODO unsafeAccumulate-unsafeAccumulate :: (a -> b -> a) -> Vector a -> Vector (Int,b) -> Vector a-{-# INLINE unsafeAccumulate #-}-unsafeAccumulate = G.unsafeAccumulate---- | TODO unsafeAccumulate_-unsafeAccumulate_- :: (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a-{-# INLINE unsafeAccumulate_ #-}-unsafeAccumulate_ = G.unsafeAccumulate_---- | TODO accum-accum :: (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a-{-# INLINE accum #-}-accum = G.accum---- | TODO accumulate-accumulate :: (a -> b -> a) -> Vector a -> Vector (Int,b) -> Vector a-{-# INLINE accumulate #-}-accumulate = G.accumulate---- | TODO accumulate_-accumulate_ :: (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a-{-# INLINE accumulate_ #-}-accumulate_ = G.accumulate_---- | TODO unsafeUpd-unsafeUpd :: Vector a -> [(Int, a)] -> Vector a-{-# INLINE unsafeUpd #-}-unsafeUpd = G.unsafeUpd---- | TODO unsafeUpdate-unsafeUpdate :: Vector a -> Vector (Int, a) -> Vector a-{-# INLINE unsafeUpdate #-}-unsafeUpdate = G.unsafeUpdate---- | TODO unsafeUpdate_-unsafeUpdate_ :: Vector a -> Vector Int -> Vector a -> Vector a-{-# INLINE unsafeUpdate_ #-}-unsafeUpdate_ = G.unsafeUpdate_---- | TODO (//)-(//) :: Vector a -> [(Int, a)] -> Vector a-{-# INLINE (//) #-}-(//) = (G.//)---- | TODO update-update :: Vector a -> Vector (Int, a) -> Vector a-{-# INLINE update #-}-update = G.update---- | TODO update_-update_ :: Vector a -> Vector Int -> Vector a -> Vector a-{-# INLINE update_ #-}-update_ = G.update_---- | backpermute, courtesy Blelloch. The back-permute is a gather\/get operation.-backpermute :: Vector a -> Vector Int -> Vector a-{-# INLINE backpermute #-}-backpermute = G.backpermute---- | TODO unsafeBackpermute-unsafeBackpermute :: Vector a -> Vector Int -> Vector a-{-# INLINE unsafeBackpermute #-}-unsafeBackpermute = G.unsafeBackpermute---- | /O(n)/, reverse the elements of the given vector.-reverse :: Vector a -> Vector a-{-# INLINE reverse #-}-reverse = G.reverse---- Mapping--- ----------- | /O(n)/, Map a function over a vector-map :: (a -> b) -> Vector a -> Vector b-{-# INLINE map #-}-map = G.map---- | /O(n)/, Apply a function to every index/value pair yielding a new vector-imap :: (Int -> a -> b) -> Vector a -> Vector b-{-# INLINE imap #-}-imap = G.imap---- | /O(n)/, generate a vector from each element of the input vector, then join the results.-concatMap :: (a -> Vector b) -> Vector a -> Vector b-{-# INLINE concatMap #-}-concatMap = G.concatMap---- Zipping/unzipping--- --------------------- |/O(n)/, Zip two vectors with the given function.-zipWith :: (a -> b -> c) -> Vector a -> Vector b -> Vector c-{-# INLINE zipWith #-}-zipWith = G.zipWith---- |/O(n)/, Zip three vectors with the given function.-zipWith3 :: (a -> b -> c -> d) -> Vector a -> Vector b -> Vector c -> Vector d-{-# INLINE zipWith3 #-}-zipWith3 = G.zipWith3---- |/O(n)/, Zip four vectors with the given function.-zipWith4 :: (a -> b -> c -> d -> e)- -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e-{-# INLINE zipWith4 #-}-zipWith4 = G.zipWith4---- |/O(n)/, Zip five vectors with the given function.-zipWith5 :: (a -> b -> c -> d -> e -> f)- -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e- -> Vector f-{-# INLINE zipWith5 #-}-zipWith5 = G.zipWith5---- |/O(n)/, Zip six vectors with the given function.-zipWith6 :: (a -> b -> c -> d -> e -> f -> g)- -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e- -> Vector f -> Vector g-{-# INLINE zipWith6 #-}-zipWith6 = G.zipWith6---- |/O(n)/, Zip two vectors and their indices with the given function.-izipWith :: (Int -> a -> b -> c) -> Vector a -> Vector b -> Vector c-{-# INLINE izipWith #-}-izipWith = G.izipWith---- |/O(n)/, Zip three vectors and their indices with the given function.-izipWith3 :: (Int -> a -> b -> c -> d)- -> Vector a -> Vector b -> Vector c -> Vector d-{-# INLINE izipWith3 #-}-izipWith3 = G.izipWith3---- |/O(n)/, Zip four vectors and their indices with the given function.-izipWith4 :: (Int -> a -> b -> c -> d -> e)- -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e-{-# INLINE izipWith4 #-}-izipWith4 = G.izipWith4---- |/O(n)/, Zip five vectors and their indices with the given function.-izipWith5 :: (Int -> a -> b -> c -> d -> e -> f)- -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e- -> Vector f-{-# INLINE izipWith5 #-}-izipWith5 = G.izipWith5---- |/O(n)/, Zip six vectors and their indices with the given function.-izipWith6 :: (Int -> a -> b -> c -> d -> e -> f -> g)- -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e- -> Vector f -> Vector g-{-# INLINE izipWith6 #-}-izipWith6 = G.izipWith6---- | Elementwise pairing of array elements. -zip :: Vector a -> Vector b -> Vector (a, b)-{-# INLINE zip #-}-zip = G.zip---- | zip together three vectors into a vector of triples-zip3 :: Vector a -> Vector b -> Vector c -> Vector (a, b, c)-{-# INLINE zip3 #-}-zip3 = G.zip3--zip4 :: Vector a -> Vector b -> Vector c -> Vector d- -> Vector (a, b, c, d)-{-# INLINE zip4 #-}-zip4 = G.zip4--zip5 :: Vector a -> Vector b -> Vector c -> Vector d -> Vector e- -> Vector (a, b, c, d, e)-{-# INLINE zip5 #-}-zip5 = G.zip5--zip6 :: Vector a -> Vector b -> Vector c -> Vector d -> Vector e -> Vector f- -> Vector (a, b, c, d, e, f)-{-# INLINE zip6 #-}-zip6 = G.zip6---- | Elementwise unpairing of array elements.-unzip :: Vector (a, b) -> (Vector a, Vector b)-{-# INLINE unzip #-}-unzip = G.unzip--unzip3 :: Vector (a, b, c) -> (Vector a, Vector b, Vector c)-{-# INLINE unzip3 #-}-unzip3 = G.unzip3--unzip4 :: Vector (a, b, c, d) -> (Vector a, Vector b, Vector c, Vector d)-{-# INLINE unzip4 #-}-unzip4 = G.unzip4--unzip5 :: Vector (a, b, c, d, e)- -> (Vector a, Vector b, Vector c, Vector d, Vector e)-{-# INLINE unzip5 #-}-unzip5 = G.unzip5--unzip6 :: Vector (a, b, c, d, e, f)- -> (Vector a, Vector b, Vector c, Vector d, Vector e, Vector f)-{-# INLINE unzip6 #-}-unzip6 = G.unzip6---- Filtering--- ------------- |/O(n)/, Remove elements from the vector which do not satisfy the predicate-filter :: (a -> Bool) -> Vector a -> Vector a-{-# INLINE filter #-}-filter = G.filter---- |/O(n)/, Drop elements that do not satisfy the predicate (applied to values and--- their indices)-ifilter :: (Int -> a -> Bool) -> Vector a -> Vector a-{-# INLINE ifilter #-}-ifilter = G.ifilter---- |/O(n)/, Yield the longest prefix of elements satisfying the predicate.-takeWhile :: (a -> Bool) -> Vector a -> Vector a-{-# INLINE takeWhile #-}-takeWhile = G.takeWhile---- |/O(n)/, Drop the longest prefix of elements that satisfy the predicate.-dropWhile :: (a -> Bool) -> Vector a -> Vector a-{-# INLINE dropWhile #-}-dropWhile = G.dropWhile---- | Split the vector in two parts, the first one containing those elements--- that satisfy the predicate and the second one those that don't. The--- relative order of the elements is preserved at the cost of a (sometimes)--- reduced performance compared to 'unstablePartition'.-partition :: (a -> Bool) -> Vector a -> (Vector a, Vector a)-{-# INLINE partition #-}-partition = G.partition---- |/O(n)/, Split the vector in two parts, the first one containing those elements--- that satisfy the predicate and the second one those that don't. The order--- of the elements is not preserved.-unstablePartition :: (a -> Bool) -> Vector a -> (Vector a, Vector a)-{-# INLINE unstablePartition #-}-unstablePartition = G.unstablePartition---- |/O(n)/, Split the vector into the longest prefix of elements that satisfy the--- predicate and the rest.-span :: (a -> Bool) -> Vector a -> (Vector a, Vector a)-{-# INLINE span #-}-span = G.span---- | Split the vector into the longest prefix of elements that do not satisfy--- the predicate and the rest.-break :: (a -> Bool) -> Vector a -> (Vector a, Vector a)-{-# INLINE break #-}-break = G.break---- Searching--- -----------infix 4 `elem`--- | Check whether the vector contains an element-elem :: Eq a => a -> Vector a -> Bool-{-# INLINE elem #-}-elem = G.elem--infix 4 `notElem`--- | Inverse of `elem`-notElem :: Eq a => a -> Vector a -> Bool-{-# INLINE notElem #-}-notElem = G.notElem---- | Yield 'Just' the first element matching the predicate or 'Nothing' if no--- such element exists.-find :: (a -> Bool) -> Vector a -> Maybe a-{-# INLINE find #-}-find = G.find---- | Yield 'Just' the index of the first element matching the predicate or--- 'Nothing' if no such element exists.-findIndex :: (a -> Bool) -> Vector a -> Maybe Int-{-# INLINE findIndex #-}-findIndex = G.findIndex---- | Yield the indices of elements satisfying the predicate-findIndices :: (a -> Bool) -> Vector a -> Vector Int-{-# INLINE findIndices #-}-findIndices = G.findIndices---- | Yield 'Just' the index of the first occurence of the given element or--- 'Nothing' if the vector does not contain the element-elemIndex :: Eq a => a -> Vector a -> Maybe Int-{-# INLINE elemIndex #-}-elemIndex = G.elemIndex---- | Yield the indices of all occurences of the given element-elemIndices :: Eq a => a -> Vector a -> Vector Int-{-# INLINE elemIndices #-}-elemIndices = G.elemIndices---- Folding--- ----------- | Left fold-foldl :: (a -> b -> a) -> a -> Vector b -> a-{-# INLINE foldl #-}-foldl = G.foldl---- | Left fold on non-empty vectors-foldl1 :: (a -> a -> a) -> Vector a -> a-{-# INLINE foldl1 #-}-foldl1 = G.foldl1---- | Left fold with strict accumulator-foldl' :: (a -> b -> a) -> a -> Vector b -> a-{-# INLINE foldl' #-}-foldl' = G.foldl'---- | Left fold on non-empty vectors with strict accumulator-foldl1' :: (a -> a -> a) -> Vector a -> a-{-# INLINE foldl1' #-}-foldl1' = G.foldl1'---- | Right fold-foldr :: (a -> b -> b) -> b -> Vector a -> b-{-# INLINE foldr #-}-foldr = G.foldr---- | Right fold on non-empty vectors-foldr1 :: (a -> a -> a) -> Vector a -> a-{-# INLINE foldr1 #-}-foldr1 = G.foldr1---- | Right fold with a strict accumulator-foldr' :: (a -> b -> b) -> b -> Vector a -> b-{-# INLINE foldr' #-}-foldr' = G.foldr'---- | Right fold on non-empty vectors with strict accumulator-foldr1' :: (a -> a -> a) -> Vector a -> a-{-# INLINE foldr1' #-}-foldr1' = G.foldr1'---- | Left fold (function applied to each element and its index)-ifoldl :: (a -> Int -> b -> a) -> a -> Vector b -> a-{-# INLINE ifoldl #-}-ifoldl = G.ifoldl---- | Left fold with strict accumulator (function applied to each element and--- its index)-ifoldl' :: (a -> Int -> b -> a) -> a -> Vector b -> a-{-# INLINE ifoldl' #-}-ifoldl' = G.ifoldl'---- | Right fold (function applied to each element and its index)-ifoldr :: (Int -> a -> b -> b) -> b -> Vector a -> b-{-# INLINE ifoldr #-}-ifoldr = G.ifoldr---- | Right fold with strict accumulator (function applied to each element and--- its index)-ifoldr' :: (Int -> a -> b -> b) -> b -> Vector a -> b-{-# INLINE ifoldr' #-}-ifoldr' = G.ifoldr'---- Specialised folds--- --------------------- |/O(n)/. @'all' p u@ determines whether all elements in array @u@ satisfy --- predicate @p@.-all :: (a -> Bool) -> Vector a -> Bool-{-# INLINE all #-}-all = G.all---- |/O(n)/. @'any' p u@ determines whether any element in array @u@ satisfies--- predicate @p@.-any :: (a -> Bool) -> Vector a -> Bool-{-# INLINE any #-}-any = G.any---- |/O(n)/. 'and' yields the conjunction of a boolean array.-and :: Vector Bool -> Bool-{-# INLINE and #-}-and = G.and---- |/O(n)/. 'or' yields the disjunction of a boolean array.-or :: Vector Bool -> Bool-{-# INLINE or #-}-or = G.or---- |/O(n)/. 'sum' computes the sum (with @(+)@) of an array of elements.-sum :: Num a => Vector a -> a-{-# INLINE sum #-}-sum = G.sum---- |/O(n)/. 'sum' computes the product (with @(*)@) of an array of elements.-product :: Num a => Vector a -> a-{-# INLINE product #-}-product = G.product---- |/O(n)/. 'maximum' finds the maximum element in an array of orderable elements.-maximum :: Ord a => Vector a -> a-{-# INLINE maximum #-}-maximum = G.maximum---- |/O(n)/. 'maximumBy' finds the maximum element in an array under the given ordering.-maximumBy :: (a -> a -> Ordering) -> Vector a -> a-{-# INLINE maximumBy #-}-maximumBy = G.maximumBy---- |/O(n)/. 'minimum' finds the minimum element in an array of orderable elements.-minimum :: Ord a => Vector a -> a-{-# INLINE minimum #-}-minimum = G.minimum---- |/O(n)/. 'minimumBy' finds the minimum element in an array under the given ordering.-minimumBy :: (a -> a -> Ordering) -> Vector a -> a-{-# INLINE minimumBy #-}-minimumBy = G.minimumBy---- | TODO maxIndex-maxIndex :: Ord a => Vector a -> Int-{-# INLINE maxIndex #-}-maxIndex = G.maxIndex---- | TODO maxIndexBy-maxIndexBy :: (a -> a -> Ordering) -> Vector a -> Int-{-# INLINE maxIndexBy #-}-maxIndexBy = G.maxIndexBy---- | TODO minIndex-minIndex :: Ord a => Vector a -> Int-{-# INLINE minIndex #-}-minIndex = G.minIndex---- | TODO minIndexBy-minIndexBy :: (a -> a -> Ordering) -> Vector a -> Int-{-# INLINE minIndexBy #-}-minIndexBy = G.minIndexBy---- Unfolding--- ------------- | The 'unfoldr' function is a \`dual\' to 'foldr': while 'foldr'--- reduces a vector to a summary value, 'unfoldr' builds a list from--- a seed value. The function takes the element and returns 'Nothing'--- if it is done generating the vector or returns 'Just' @(a,b)@, in which--- case, @a@ is a prepended to the vector and @b@ is used as the next--- element in a recursive call.------ A simple use of unfoldr:------ > unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10--- > [10,9,8,7,6,5,4,3,2,1]----unfoldr :: (b -> Maybe (a, b)) -> b -> Vector a-{-# INLINE unfoldr #-}-unfoldr = G.unfoldr---- | Unfold at most @n@ elements-unfoldrN :: Int -> (b -> Maybe (a, b)) -> b -> Vector a-{-# INLINE unfoldrN #-}-unfoldrN = G.unfoldrN---- Scans--- --------- | Prefix scan-prescanl :: (a -> b -> a) -> a -> Vector b -> Vector a-{-# INLINE prescanl #-}-prescanl = G.prescanl---- | Prefix scan with strict accumulator-prescanl' :: (a -> b -> a) -> a -> Vector b -> Vector a-{-# INLINE prescanl' #-}-prescanl' = G.prescanl'---- | Suffix scan-postscanl :: (a -> b -> a) -> a -> Vector b -> Vector a-{-# INLINE postscanl #-}-postscanl = G.postscanl---- | Suffix scan with strict accumulator-postscanl' :: (a -> b -> a) -> a -> Vector b -> Vector a-{-# INLINE postscanl' #-}-postscanl' = G.postscanl'---- | Haskell-style scan function.-scanl :: (a -> b -> a) -> a -> Vector b -> Vector a-{-# INLINE scanl #-}-scanl = G.scanl---- | Haskell-style scan with strict accumulator-scanl' :: (a -> b -> a) -> a -> Vector b -> Vector a-{-# INLINE scanl' #-}-scanl' = G.scanl'---- | Scan over a non-empty 'Vector'-scanl1 :: (a -> a -> a) -> Vector a -> Vector a-{-# INLINE scanl1 #-}-scanl1 = G.scanl1---- | Scan over a non-empty 'Vector' with a strict accumulator-scanl1' :: (a -> a -> a) -> Vector a -> Vector a-{-# INLINE scanl1' #-}-scanl1' = G.scanl1'---- | Prefix right-to-left scan-prescanr :: (a -> b -> b) -> b -> Vector a -> Vector b-{-# INLINE prescanr #-}-prescanr = G.prescanr---- | Prefix right-to-left scan with strict accumulator-prescanr' :: (a -> b -> b) -> b -> Vector a -> Vector b-{-# INLINE prescanr' #-}-prescanr' = G.prescanr'---- | Suffix right-to-left scan-postscanr :: (a -> b -> b) -> b -> Vector a -> Vector b-{-# INLINE postscanr #-}-postscanr = G.postscanr---- | Suffix right-to-left scan with strict accumulator-postscanr' :: (a -> b -> b) -> b -> Vector a -> Vector b-{-# INLINE postscanr' #-}-postscanr' = G.postscanr'---- | Haskell-style right-to-left scan-scanr :: (a -> b -> b) -> b -> Vector a -> Vector b-{-# INLINE scanr #-}-scanr = G.scanr---- | Haskell-style right-to-left scan with strict accumulator-scanr' :: (a -> b -> b) -> b -> Vector a -> Vector b-{-# INLINE scanr' #-}-scanr' = G.scanr'---- | Right-to-left scan over a non-empty vector-scanr1 :: (a -> a -> a) -> Vector a -> Vector a-{-# INLINE scanr1 #-}-scanr1 = G.scanr1---- | Right-to-left scan over a non-empty vector with a strict accumulator-scanr1' :: (a -> a -> a) -> Vector a -> Vector a-{-# INLINE scanr1' #-}-scanr1' = G.scanr1'---- Enumeration--- --------------- | Yield a vector of the given length containing the values @x@, @x+1@ etc.--- This operation is usually more efficient than 'enumFromTo'.-enumFromN :: Num a => a -> Int -> Vector a-{-# INLINE enumFromN #-}-enumFromN = G.enumFromN---- | Yield a vector of the given length containing the values @x@, @x+y@,--- @x+y+y@ etc. This operations is usually more efficient than--- 'enumFromThenTo'.-enumFromStepN :: Num a => a -> a -> Int -> Vector a-{-# INLINE enumFromStepN #-}-enumFromStepN = G.enumFromStepN---- | Enumerate values from @x@ to @y@.------ /WARNING:/ This operation can be very inefficient. If at all possible, use--- 'enumFromN' instead.-enumFromTo :: Enum a => a -> a -> Vector a-{-# INLINE enumFromTo #-}-enumFromTo = G.enumFromTo---- | Enumerate values from @x@ to @y@ with a specific step @z@.------ /WARNING:/ This operation can be very inefficient. If at all possible, use--- 'enumFromStepN' instead.-enumFromThenTo :: Enum a => a -> a -> a -> Vector a-{-# INLINE enumFromThenTo #-}-enumFromThenTo = G.enumFromThenTo---- Conversion to/from lists--- ---------------------------- | Convert a vector to a list-toList :: Vector a -> [a]-{-# INLINE toList #-}-toList = G.toList---- | Convert a list to a vector-fromList :: [a] -> Vector a-{-# INLINE fromList #-}-fromList = G.fromList---- | Convert the first @n@ elements of a list to a vector------ > fromListN n xs = fromList (take n xs)-fromListN :: Int -> [a] -> Vector a-{-# INLINE fromListN #-}-fromListN = G.fromListN---- Monadic operations--- ---------------------- | Perform the monadic action the given number of times and store the--- results in a vector.-replicateM :: Monad m => Int -> m a -> m (Vector a)-{-# INLINE replicateM #-}-replicateM = G.replicateM---- | Apply the monadic action to all elements of the vector, yielding a vector--- of results-mapM :: Monad m => (a -> m b) -> Vector a -> m (Vector b)-{-# INLINE mapM #-}-mapM = G.mapM---- | Apply the monadic action to all elements of a vector and ignore the--- results-mapM_ :: Monad m => (a -> m b) -> Vector a -> m ()-{-# INLINE mapM_ #-}-mapM_ = G.mapM_---- | Apply the monadic action to all elements of the vector, yielding a vector--- of results-forM :: Monad m => Vector a -> (a -> m b) -> m (Vector b)-{-# INLINE forM #-}-forM = G.forM---- | Apply the monadic action to all elements of a vector and ignore the--- results-forM_ :: Monad m => Vector a -> (a -> m b) -> m ()-{-# INLINE forM_ #-}-forM_ = G.forM_---- | Zip the two vectors with the monadic action and yield a vector of results-zipWithM :: Monad m- => (a -> b -> m c) -> Vector a -> Vector b -> m (Vector c)-{-# INLINE zipWithM #-}-zipWithM = G.zipWithM---- | Zip the two vectors with the monadic action and ignore the results-zipWithM_ :: Monad m- => (a -> b -> m c) -> Vector a -> Vector b -> m ()-{-# INLINE zipWithM_ #-}-zipWithM_ = G.zipWithM_---- | Drop elements that do not satisfy the monadic predicate-filterM :: Monad m => (a -> m Bool) -> Vector a -> m (Vector a)-{-# INLINE filterM #-}-filterM = G.filterM---- | Monadic fold-foldM :: Monad m => (a -> b -> m a) -> a -> Vector b -> m a-{-# INLINE foldM #-}-foldM = G.foldM---- | Monadic fold over non-empty vectors-fold1M :: Monad m => (a -> a -> m a) -> Vector a -> m a-{-# INLINE fold1M #-}-fold1M = G.fold1M---- | Monadic fold with strict accumulator-foldM' :: Monad m => (a -> b -> m a) -> a -> Vector b -> m a-{-# INLINE foldM' #-}-foldM' = G.foldM'---- | Monad fold over non-empty vectors with strict accumulator-fold1M' :: Monad m => (a -> a -> m a) -> Vector a -> m a-{-# INLINE fold1M' #-}-fold1M' = G.fold1M'---- Destructive operations--- -------------------------- | Destructively initialise a vector.-create :: (forall s. ST s (MVector s a)) -> Vector a-{-# INLINE create #-}-create = G.create---- | Apply a destructive operation to a vector. The operation is applied to a--- copy of the vector unless it can be safely performed in place.-modify :: (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a-{-# INLINE modify #-}-modify = G.modify---- | Copy an immutable vector into a mutable one. The two vectors must have--- the same length. This is not checked.-unsafeCopy :: PrimMonad m => MVector (PrimState m) a -> Vector a -> m ()-{-# INLINE unsafeCopy #-}-unsafeCopy = G.unsafeCopy- --- | Copy an immutable vector into a mutable one. The two vectors must have the--- same length.+ -- * Boxed vectors+ Vector, MVector,++ -- * Accessors++ -- ** Length information+ length, null,++ -- ** Indexing+ (!), head, last,+ unsafeIndex, unsafeHead, unsafeLast,++ -- ** Monadic indexing+ indexM, headM, lastM,+ unsafeIndexM, unsafeHeadM, unsafeLastM,++ -- ** Extracting subvectors (slicing)+ slice, init, tail, take, drop,+ unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,++ -- * Construction++ -- ** Initialisation+ empty, singleton, replicate, generate,++ -- ** Monadic initialisation+ replicateM, create,++ -- ** Unfolding+ unfoldr, unfoldrN,++ -- ** Enumeration+ enumFromN, enumFromStepN, enumFromTo, enumFromThenTo,++ -- ** Concatenation+ cons, snoc, (++),++ -- ** Restricting memory usage+ force,++ -- * Modifying vectors++ -- ** Bulk updates+ (//), update, update_,+ unsafeUpd, unsafeUpdate, unsafeUpdate_,++ -- ** Accumulations+ accum, accumulate, accumulate_,+ unsafeAccum, unsafeAccumulate, unsafeAccumulate_,++ -- ** Permutations + reverse, backpermute, unsafeBackpermute,++ -- ** Safe destructive updates+ modify,++ -- * Elementwise operations++ -- ** Mapping+ map, imap, concatMap,++ -- ** Monadic mapping+ mapM, mapM_, forM, forM_,++ -- ** Zipping+ zipWith, zipWith3, zipWith4, zipWith5, zipWith6,+ izipWith, izipWith3, izipWith4, izipWith5, izipWith6,+ zip, zip3, zip4, zip5, zip6,++ -- ** Monadic zipping+ zipWithM, zipWithM_,++ -- ** Unzipping+ unzip, unzip3, unzip4, unzip5, unzip6,++ -- * Working with predicates++ -- ** Filtering+ filter, ifilter, filterM,+ takeWhile, dropWhile,++ -- ** Partitioning+ partition, unstablePartition, span, break,++ -- ** Searching+ elem, notElem, find, findIndex, findIndices, elemIndex, elemIndices,++ -- * Folding+ foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1',+ ifoldl, ifoldl', ifoldr, ifoldr',++ -- ** Specialised folds+ all, any, and, or,+ sum, product,+ maximum, maximumBy, minimum, minimumBy,+ minIndex, minIndexBy, maxIndex, maxIndexBy,++ -- ** Monadic folds+ foldM, foldM', fold1M, fold1M',++ -- * Prefix sums (scans)+ prescanl, prescanl',+ postscanl, postscanl',+ scanl, scanl', scanl1, scanl1',+ prescanr, prescanr',+ postscanr, postscanr',+ scanr, scanr', scanr1, scanr1',++ -- * Conversions++ -- ** Lists+ toList, fromList, fromListN,++ -- ** Mutable vectors+ copy, unsafeCopy+) where++import qualified Data.Vector.Generic as G+import Data.Vector.Mutable ( MVector(..) )+import Data.Primitive.Array+import qualified Data.Vector.Fusion.Stream as Stream++import Control.Monad ( liftM )+import Control.Monad.ST ( ST )+import Control.Monad.Primitive++import Prelude hiding ( length, null,+ replicate, (++),+ head, last,+ init, tail, take, drop, reverse,+ map, concatMap,+ zipWith, zipWith3, zip, zip3, unzip, unzip3,+ filter, takeWhile, dropWhile, span, break,+ elem, notElem,+ foldl, foldl1, foldr, foldr1,+ all, any, and, or, sum, product, minimum, maximum,+ scanl, scanl1, scanr, scanr1,+ enumFromTo, enumFromThenTo,+ mapM, mapM_ )++import qualified Prelude++import Data.Typeable ( Typeable )+import Data.Data ( Data(..) )++-- | Boxed vectors, supporting efficient slicing.+data Vector a = Vector {-# UNPACK #-} !Int+ {-# UNPACK #-} !Int+ {-# UNPACK #-} !(Array a)+ deriving ( Typeable )++instance Show a => Show (Vector a) where+ show = (Prelude.++ " :: Data.Vector.Vector") . ("fromList " Prelude.++) . show . toList++instance Data a => Data (Vector a) where+ gfoldl = G.gfoldl+ toConstr _ = error "toConstr"+ gunfold _ _ = error "gunfold"+ dataTypeOf _ = G.mkType "Data.Vector.Vector"+ dataCast1 = G.dataCast++type instance G.Mutable Vector = MVector++instance G.Vector Vector a where+ {-# INLINE unsafeFreeze #-}+ unsafeFreeze (MVector i n marr)+ = Vector i n `liftM` unsafeFreezeArray marr++ {-# INLINE basicLength #-}+ basicLength (Vector _ n _) = n++ {-# INLINE basicUnsafeSlice #-}+ basicUnsafeSlice j n (Vector i _ arr) = Vector (i+j) n arr++ {-# INLINE basicUnsafeIndexM #-}+ basicUnsafeIndexM (Vector i _ arr) j = indexArrayM arr (i+j)++-- See http://trac.haskell.org/vector/ticket/12+instance Eq a => Eq (Vector a) where+ {-# INLINE (==) #-}+ xs == ys = Stream.eq (G.stream xs) (G.stream ys)++ {-# INLINE (/=) #-}+ xs /= ys = not (Stream.eq (G.stream xs) (G.stream ys))++-- See http://trac.haskell.org/vector/ticket/12+instance Ord a => Ord (Vector a) where+ {-# INLINE compare #-}+ compare xs ys = Stream.cmp (G.stream xs) (G.stream ys)++ {-# INLINE (<) #-}+ xs < ys = Stream.cmp (G.stream xs) (G.stream ys) == LT++ {-# INLINE (<=) #-}+ xs <= ys = Stream.cmp (G.stream xs) (G.stream ys) /= GT++ {-# INLINE (>) #-}+ xs > ys = Stream.cmp (G.stream xs) (G.stream ys) == GT++ {-# INLINE (>=) #-}+ xs >= ys = Stream.cmp (G.stream xs) (G.stream ys) /= LT++-- Length information+-- ------------------++-- | /O(1)/ Yield the length of the vector.+length :: Vector a -> Int+{-# INLINE length #-}+length = G.length++-- | /O(1)/ Test whether a vector if empty+null :: Vector a -> Bool+{-# INLINE null #-}+null = G.null++-- Indexing+-- --------++-- | O(1) Indexing+(!) :: Vector a -> Int -> a+{-# INLINE (!) #-}+(!) = (G.!)++-- | /O(1)/ First element+head :: Vector a -> a+{-# INLINE head #-}+head = G.head++-- | /O(1)/ Last element+last :: Vector a -> a+{-# INLINE last #-}+last = G.last++-- | /O(1)/ Unsafe indexing without bounds checking+unsafeIndex :: Vector a -> Int -> a+{-# INLINE unsafeIndex #-}+unsafeIndex = G.unsafeIndex++-- | /O(1)/ First element without checking if the vector is empty+unsafeHead :: Vector a -> a+{-# INLINE unsafeHead #-}+unsafeHead = G.unsafeHead++-- | /O(1)/ Last element without checking if the vector is empty+unsafeLast :: Vector a -> a+{-# INLINE unsafeLast #-}+unsafeLast = G.unsafeLast++-- Monadic indexing+-- ----------------++-- | /O(1)/ Indexing in a monad.+--+-- The monad allows operations to be strict in the vector when necessary.+-- Suppose vector copying is implemented like this:+--+-- > copy mv v = ... write mv i (v ! i) ...+--+-- For lazy vectors, @v ! i@ would not be evaluated which means that @mv@+-- would unnecessarily retain a reference to @v@ in each element written.+--+-- With 'indexM', copying can be implemented like this instead:+--+-- > copy mv v = ... do+-- > x <- indexM v i+-- > write mv i x+--+-- Here, no references to @v@ are retained because indexing (but /not/ the+-- elements) is evaluated eagerly.+--+indexM :: Monad m => Vector a -> Int -> m a+{-# INLINE indexM #-}+indexM = G.indexM++-- | /O(1)/ First element of a vector in a monad. See 'indexM' for an+-- explanation of why this is useful.+headM :: Monad m => Vector a -> m a+{-# INLINE headM #-}+headM = G.headM++-- | /O(1)/ Last element of a vector in a monad. See 'indexM' for an+-- explanation of why this is useful.+lastM :: Monad m => Vector a -> m a+{-# INLINE lastM #-}+lastM = G.lastM++-- | /O(1)/ Indexing in a monad without bounds checks. See 'indexM' for an+-- explanation of why this is useful.+unsafeIndexM :: Monad m => Vector a -> Int -> m a+{-# INLINE unsafeIndexM #-}+unsafeIndexM = G.unsafeIndexM++-- | /O(1)/ First element in a monad without checking for empty vectors.+-- See 'indexM' for an explanation of why this is useful.+unsafeHeadM :: Monad m => Vector a -> m a+{-# INLINE unsafeHeadM #-}+unsafeHeadM = G.unsafeHeadM++-- | /O(1)/ Last element in a monad without checking for empty vectors.+-- See 'indexM' for an explanation of why this is useful.+unsafeLastM :: Monad m => Vector a -> m a+{-# INLINE unsafeLastM #-}+unsafeLastM = G.unsafeLastM++-- Extracting subvectors (slicing)+-- -------------------------------++-- | /O(1)/ Yield a slice of the vector without copying it. The vector must+-- contain at least @i+n@ elements.+slice :: Int -- ^ @i@ starting index+ -> Int -- ^ @n@ length+ -> Vector a+ -> Vector a+{-# INLINE slice #-}+slice = G.slice++-- | /O(1)/ Yield all but the last element without copying. The vector may not+-- be empty.+init :: Vector a -> Vector a+{-# INLINE init #-}+init = G.init++-- | /O(1)/ Yield all but the first element without copying. The vector may not+-- be empty.+tail :: Vector a -> Vector a+{-# INLINE tail #-}+tail = G.tail++-- | /O(1)/ Yield at the first @n@ elements without copying. The vector may+-- contain less than @n@ elements in which case it is returned unchanged.+take :: Int -> Vector a -> Vector a+{-# INLINE take #-}+take = G.take++-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may+-- contain less than @n@ elements in which case an empty vector is returned.+drop :: Int -> Vector a -> Vector a+{-# INLINE drop #-}+drop = G.drop++-- | /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+ -> Int -- ^ @n@ length+ -> Vector a+ -> Vector a+{-# INLINE unsafeSlice #-}+unsafeSlice = G.unsafeSlice++-- | /O(1)/ Yield all but the last element without copying. The vector may not+-- be empty but this is not checked.+unsafeInit :: Vector a -> Vector a+{-# INLINE unsafeInit #-}+unsafeInit = G.unsafeInit++-- | /O(1)/ Yield all but the first element without copying. The vector may not+-- be empty but this is not checked.+unsafeTail :: Vector a -> Vector a+{-# INLINE unsafeTail #-}+unsafeTail = G.unsafeTail++-- | /O(1)/ Yield the first @n@ elements without copying. The vector must+-- contain at least @n@ elements but this is not checked.+unsafeTake :: Int -> Vector a -> Vector a+{-# INLINE unsafeTake #-}+unsafeTake = G.unsafeTake++-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector+-- must contain at least @n@ elements but this is not checked.+unsafeDrop :: Int -> Vector a -> Vector a+{-# INLINE unsafeDrop #-}+unsafeDrop = G.unsafeDrop++-- Initialisation+-- --------------++-- | /O(1)/ Empty vector+empty :: Vector a+{-# INLINE empty #-}+empty = G.empty++-- | /O(1)/ Vector with exactly one element+singleton :: a -> Vector a+{-# INLINE singleton #-}+singleton = G.singleton++-- | /O(n)/ Vector of the given length with the same value in each position+replicate :: Int -> a -> Vector a+{-# INLINE replicate #-}+replicate = G.replicate++-- | /O(n)/ Construct a vector of the given length by applying the function to+-- each index+generate :: Int -> (Int -> a) -> Vector a+{-# INLINE generate #-}+generate = G.generate++-- Unfolding+-- ---------++-- | /O(n)/ Construct a vector by repeatedly applying the generator function+-- to a seed. The generator function yields 'Just' the next element and the+-- new seed or 'Nothing' if there are no more elements.+--+-- > unfoldr (\n -> if n == 0 then Nothing else Just (n,n-1)) 10+-- > = <10,9,8,7,6,5,4,3,2,1>+unfoldr :: (b -> Maybe (a, b)) -> b -> Vector a+{-# INLINE unfoldr #-}+unfoldr = G.unfoldr++-- | /O(n)/ Construct a vector with at most @n@ by repeatedly applying the+-- generator function to the a seed. The generator function yields 'Just' the+-- next element and the new seed or 'Nothing' if there are no more elements.+--+-- > unfoldrN 3 (\n -> Just (n,n-1)) 10 = <10,9,8>+unfoldrN :: Int -> (b -> Maybe (a, b)) -> b -> Vector a+{-# INLINE unfoldrN #-}+unfoldrN = G.unfoldrN++-- Enumeration+-- -----------++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+1@+-- etc. This operation is usually more efficient than 'enumFromTo'.+--+-- > enumFromN 5 3 = <5,6,7>+enumFromN :: Num a => a -> Int -> Vector a+{-# INLINE enumFromN #-}+enumFromN = G.enumFromN++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,+-- @x+y+y@ etc. This operations is usually more efficient than 'enumFromThenTo'.+--+-- > enumFromStepN 1 0.1 5 = <1,1.1,1.2,1.3,1.4>+enumFromStepN :: Num a => a -> a -> Int -> Vector a+{-# INLINE enumFromStepN #-}+enumFromStepN = G.enumFromStepN++-- | /O(n)/ Enumerate values from @x@ to @y@.+--+-- /WARNING:/ This operation can be very inefficient. If at all possible, use+-- 'enumFromN' instead.+enumFromTo :: Enum a => a -> a -> Vector a+{-# INLINE enumFromTo #-}+enumFromTo = G.enumFromTo++-- | /O(n)/ Enumerate values from @x@ to @y@ with a specific step @z@.+--+-- /WARNING:/ This operation can be very inefficient. If at all possible, use+-- 'enumFromStepN' instead.+enumFromThenTo :: Enum a => a -> a -> a -> Vector a+{-# INLINE enumFromThenTo #-}+enumFromThenTo = G.enumFromThenTo++-- Concatenation+-- -------------++-- | /O(n)/ Prepend an element+cons :: a -> Vector a -> Vector a+{-# INLINE cons #-}+cons = G.cons++-- | /O(n)/ Append an element+snoc :: Vector a -> a -> Vector a+{-# INLINE snoc #-}+snoc = G.snoc++infixr 5 +++-- | /O(m+n)/ Concatenate two vectors+(++) :: Vector a -> Vector a -> Vector a+{-# INLINE (++) #-}+(++) = (G.++)++-- Monadic initialisation+-- ----------------------++-- | /O(n)/ Execute the monadic action the given number of times and store the+-- results in a vector.+replicateM :: Monad m => Int -> m a -> m (Vector a)+{-# INLINE replicateM #-}+replicateM = G.replicateM++-- | Execute the monadic action and freeze the resulting vector.+--+-- @+-- create (do { v \<- new 2; write v 0 \'a\'; write v 1 \'b\' }) = \<'a','b'\>+-- @+create :: (forall s. ST s (MVector s a)) -> Vector a+{-# INLINE create #-}+create = G.create++++-- Restricting memory usage+-- ------------------------++-- | /O(n)/ Yield the argument but force it not to retain any extra memory,+-- possibly by copying it.+--+-- This is especially useful when dealing with slices. For example:+--+-- > force (slice 0 2 <huge vector>)+--+-- Here, the slice retains a reference to the huge vector. Forcing it creates+-- a copy of just the elements that belong to the slice and allows the huge+-- vector to be garbage collected.+force :: Vector a -> Vector a+{-# INLINE force #-}+force = G.force++-- Bulk updates+-- ------------++-- | /O(m+n)/ For each pair @(i,a)@ from the list, replace the vector+-- element at position @i@ by @a@.+--+-- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7>+--+(//) :: Vector a -- ^ initial vector (of length @m@)+ -> [(Int, a)] -- ^ list of index/value pairs (of length @n@) + -> Vector a+{-# INLINE (//) #-}+(//) = (G.//)++-- | /O(m+n)/ For each pair @(i,a)@ from the vector of index/value pairs,+-- replace the vector element at position @i@ by @a@.+--+-- > update <5,9,2,7> <(2,1),(0,3),(2,8)> = <3,9,8,7>+--+update :: Vector a -- ^ initial vector (of length @m@)+ -> Vector (Int, a) -- ^ vector of index/value pairs (of length @n@)+ -> Vector a+{-# INLINE update #-}+update = G.update++-- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the+-- corresponding value @a@ from the value vector, replace the element of the+-- initial vector at position @i@ by @a@.+--+-- > update_ <5,9,2,7> <2,0,2> <1,3,8> = <3,9,8,7>+--+-- The function 'update' provides the same functionality and is usually more+-- convenient.+--+-- @+-- update_ xs is ys = 'update' xs ('zip' is ys)+-- @+update_ :: Vector a -- ^ initial vector (of length @m@)+ -> Vector Int -- ^ index vector (of length @n1@)+ -> Vector a -- ^ value vector (of length @n2@)+ -> Vector a+{-# INLINE update_ #-}+update_ = G.update_++-- | Same as ('//') but without bounds checking.+unsafeUpd :: Vector a -> [(Int, a)] -> Vector a+{-# INLINE unsafeUpd #-}+unsafeUpd = G.unsafeUpd++-- | Same as 'update' but without bounds checking.+unsafeUpdate :: Vector a -> Vector (Int, a) -> Vector a+{-# INLINE unsafeUpdate #-}+unsafeUpdate = G.unsafeUpdate++-- | Same as 'update_' but without bounds checking.+unsafeUpdate_ :: Vector a -> Vector Int -> Vector a -> Vector a+{-# INLINE unsafeUpdate_ #-}+unsafeUpdate_ = G.unsafeUpdate_++-- Accumulations+-- -------------++-- | /O(m+n)/ For each pair @(i,b)@ from the list, replace the vector element+-- @a@ at position @i@ by @f a b@.+--+-- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4>+accum :: (a -> b -> a) -- ^ accumulating function @f@+ -> Vector a -- ^ initial vector (of length @m@)+ -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)+ -> Vector a+{-# INLINE accum #-}+accum = G.accum++-- | /O(m+n)/ For each pair @(i,b)@ from the vector of pairs, replace the vector+-- element @a@ at position @i@ by @f a b@.+--+-- > accumulate (+) <5,9,2> <(2,4),(1,6),(0,3),(1,7)> = <5+3, 9+6+7, 2+4>+accumulate :: (a -> b -> a) -- ^ accumulating function @f@+ -> Vector a -- ^ initial vector (of length @m@)+ -> Vector (Int,b) -- ^ vector of index/value pairs (of length @n@)+ -> Vector a+{-# INLINE accumulate #-}+accumulate = G.accumulate++-- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the+-- corresponding value @b@ from the the value vector,+-- replace the element of the initial vector at+-- position @i@ by @f a b@.+--+-- > accumulate_ (+) <5,9,2> <2,1,0,1> <4,6,3,7> = <5+3, 9+6+7, 2+4>+--+-- The function 'accumulate' provides the same functionality and is usually more+-- convenient.+--+-- @+-- accumulate_ f as is bs = 'accumulate' f as ('zip' is bs)+-- @+accumulate_ :: (a -> b -> a) -- ^ accumulating function @f@+ -> Vector a -- ^ initial vector (of length @m@)+ -> Vector Int -- ^ index vector (of length @n1@)+ -> Vector b -- ^ value vector (of length @n2@)+ -> Vector a+{-# INLINE accumulate_ #-}+accumulate_ = G.accumulate_++-- | Same as 'accum' but without bounds checking.+unsafeAccum :: (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a+{-# INLINE unsafeAccum #-}+unsafeAccum = G.unsafeAccum++-- | Same as 'accumulate' but without bounds checking.+unsafeAccumulate :: (a -> b -> a) -> Vector a -> Vector (Int,b) -> Vector a+{-# INLINE unsafeAccumulate #-}+unsafeAccumulate = G.unsafeAccumulate++-- | Same as 'accumulate_' but without bounds checking.+unsafeAccumulate_+ :: (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a+{-# INLINE unsafeAccumulate_ #-}+unsafeAccumulate_ = G.unsafeAccumulate_++-- Permutations+-- ------------++-- | /O(n)/ Reverse a vector+reverse :: Vector a -> Vector a+{-# INLINE reverse #-}+reverse = G.reverse++-- | /O(n)/ Yield the vector obtained by replacing each element @i@ of the+-- index vector by @xs'!'i@. This is equivalent to @'map' (xs'!') is@ but is+-- often much more efficient.+--+-- > backpermute <a,b,c,d> <0,3,2,3,1,0> = <a,d,c,d,b,a>+backpermute :: Vector a -> Vector Int -> Vector a+{-# INLINE backpermute #-}+backpermute = G.backpermute++-- | Same as 'backpermute' but without bounds checking.+unsafeBackpermute :: Vector a -> Vector Int -> Vector a+{-# INLINE unsafeBackpermute #-}+unsafeBackpermute = G.unsafeBackpermute++-- Safe destructive updates+-- ------------------------++-- | Apply a destructive operation to a vector. The operation will be+-- performed in place if it is safe to do so and will modify a copy of the+-- vector otherwise.+--+-- @+-- modify (\\v -> write v 0 \'x\') ('replicate' 3 \'a\') = \<\'x\',\'a\',\'a\'\>+-- @+modify :: (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a+{-# INLINE modify #-}+modify = G.modify++-- Mapping+-- -------++-- | /O(n)/ Map a function over a vector+map :: (a -> b) -> Vector a -> Vector b+{-# INLINE map #-}+map = G.map++-- | /O(n)/ Apply a function to every element of a vector and its index+imap :: (Int -> a -> b) -> Vector a -> Vector b+{-# INLINE imap #-}+imap = G.imap++-- | Map a function over a vector and concatenate the results.+concatMap :: (a -> Vector b) -> Vector a -> Vector b+{-# INLINE concatMap #-}+concatMap = G.concatMap++-- Monadic mapping+-- ---------------++-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a+-- vector of results+mapM :: Monad m => (a -> m b) -> Vector a -> m (Vector b)+{-# INLINE mapM #-}+mapM = G.mapM++-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the+-- results+mapM_ :: Monad m => (a -> m b) -> Vector a -> m ()+{-# INLINE mapM_ #-}+mapM_ = G.mapM_++-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a+-- vector of results. Equvalent to @flip 'mapM'@.+forM :: Monad m => Vector a -> (a -> m b) -> m (Vector b)+{-# INLINE forM #-}+forM = G.forM++-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the+-- results. Equivalent to @flip 'mapM_'@.+forM_ :: Monad m => Vector a -> (a -> m b) -> m ()+{-# INLINE forM_ #-}+forM_ = G.forM_++-- Zipping+-- -------++-- | /O(min(m,n))/ Zip two vectors with the given function.+zipWith :: (a -> b -> c) -> Vector a -> Vector b -> Vector c+{-# INLINE zipWith #-}+zipWith = G.zipWith++-- | Zip three vectors with the given function.+zipWith3 :: (a -> b -> c -> d) -> Vector a -> Vector b -> Vector c -> Vector d+{-# INLINE zipWith3 #-}+zipWith3 = G.zipWith3++zipWith4 :: (a -> b -> c -> d -> e)+ -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e+{-# INLINE zipWith4 #-}+zipWith4 = G.zipWith4++zipWith5 :: (a -> b -> c -> d -> e -> f)+ -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e+ -> Vector f+{-# INLINE zipWith5 #-}+zipWith5 = G.zipWith5++zipWith6 :: (a -> b -> c -> d -> e -> f -> g)+ -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e+ -> Vector f -> Vector g+{-# INLINE zipWith6 #-}+zipWith6 = G.zipWith6++-- | /O(min(m,n))/ Zip two vectors with a function that also takes the+-- elements' indices.+izipWith :: (Int -> a -> b -> c) -> Vector a -> Vector b -> Vector c+{-# INLINE izipWith #-}+izipWith = G.izipWith++-- | Zip three vectors and their indices with the given function.+izipWith3 :: (Int -> a -> b -> c -> d)+ -> Vector a -> Vector b -> Vector c -> Vector d+{-# INLINE izipWith3 #-}+izipWith3 = G.izipWith3++izipWith4 :: (Int -> a -> b -> c -> d -> e)+ -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e+{-# INLINE izipWith4 #-}+izipWith4 = G.izipWith4++izipWith5 :: (Int -> a -> b -> c -> d -> e -> f)+ -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e+ -> Vector f+{-# INLINE izipWith5 #-}+izipWith5 = G.izipWith5++izipWith6 :: (Int -> a -> b -> c -> d -> e -> f -> g)+ -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e+ -> Vector f -> Vector g+{-# INLINE izipWith6 #-}+izipWith6 = G.izipWith6++-- | Elementwise pairing of array elements. +zip :: Vector a -> Vector b -> Vector (a, b)+{-# INLINE zip #-}+zip = G.zip++-- | zip together three vectors into a vector of triples+zip3 :: Vector a -> Vector b -> Vector c -> Vector (a, b, c)+{-# INLINE zip3 #-}+zip3 = G.zip3++zip4 :: Vector a -> Vector b -> Vector c -> Vector d+ -> Vector (a, b, c, d)+{-# INLINE zip4 #-}+zip4 = G.zip4++zip5 :: Vector a -> Vector b -> Vector c -> Vector d -> Vector e+ -> Vector (a, b, c, d, e)+{-# INLINE zip5 #-}+zip5 = G.zip5++zip6 :: Vector a -> Vector b -> Vector c -> Vector d -> Vector e -> Vector f+ -> Vector (a, b, c, d, e, f)+{-# INLINE zip6 #-}+zip6 = G.zip6++-- Unzipping+-- ---------++-- | /O(min(m,n))/ Unzip a vector of pairs.+unzip :: Vector (a, b) -> (Vector a, Vector b)+{-# INLINE unzip #-}+unzip = G.unzip++unzip3 :: Vector (a, b, c) -> (Vector a, Vector b, Vector c)+{-# INLINE unzip3 #-}+unzip3 = G.unzip3++unzip4 :: Vector (a, b, c, d) -> (Vector a, Vector b, Vector c, Vector d)+{-# INLINE unzip4 #-}+unzip4 = G.unzip4++unzip5 :: Vector (a, b, c, d, e)+ -> (Vector a, Vector b, Vector c, Vector d, Vector e)+{-# INLINE unzip5 #-}+unzip5 = G.unzip5++unzip6 :: Vector (a, b, c, d, e, f)+ -> (Vector a, Vector b, Vector c, Vector d, Vector e, Vector f)+{-# INLINE unzip6 #-}+unzip6 = G.unzip6++-- Monadic zipping+-- ---------------++-- | /O(min(m,n))/ Zip the two vectors with the monadic action and yield a+-- vector of results+zipWithM :: Monad m => (a -> b -> m c) -> Vector a -> Vector b -> m (Vector c)+{-# INLINE zipWithM #-}+zipWithM = G.zipWithM++-- | /O(min(m,n))/ Zip the two vectors with the monadic action and ignore the+-- results+zipWithM_ :: Monad m => (a -> b -> m c) -> Vector a -> Vector b -> m ()+{-# INLINE zipWithM_ #-}+zipWithM_ = G.zipWithM_++-- Filtering+-- ---------++-- | /O(n)/ Drop elements that do not satisfy the predicate+filter :: (a -> Bool) -> Vector a -> Vector a+{-# INLINE filter #-}+filter = G.filter++-- | /O(n)/ Drop elements that do not satisfy the predicate which is applied to+-- values and their indices+ifilter :: (Int -> a -> Bool) -> Vector a -> Vector a+{-# INLINE ifilter #-}+ifilter = G.ifilter++-- | /O(n)/ Drop elements that do not satisfy the monadic predicate+filterM :: Monad m => (a -> m Bool) -> Vector a -> m (Vector a)+{-# INLINE filterM #-}+filterM = G.filterM++-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate+-- without copying.+takeWhile :: (a -> Bool) -> Vector a -> Vector a+{-# INLINE takeWhile #-}+takeWhile = G.takeWhile++-- | /O(n)/ Drop the longest prefix of elements that satisfy the predicate+-- without copying.+dropWhile :: (a -> Bool) -> Vector a -> Vector a+{-# INLINE dropWhile #-}+dropWhile = G.dropWhile++-- Parititioning+-- -------------++-- | /O(n)/ Split the vector in two parts, the first one containing those+-- elements that satisfy the predicate and the second one those that don't. The+-- relative order of the elements is preserved at the cost of a sometimes+-- reduced performance compared to 'unstablePartition'.+partition :: (a -> Bool) -> Vector a -> (Vector a, Vector a)+{-# INLINE partition #-}+partition = G.partition++-- | /O(n)/ Split the vector in two parts, the first one containing those+-- elements that satisfy the predicate and the second one those that don't.+-- The order of the elements is not preserved but the operation is often+-- faster than 'partition'.+unstablePartition :: (a -> Bool) -> Vector a -> (Vector a, Vector a)+{-# INLINE unstablePartition #-}+unstablePartition = G.unstablePartition++-- | /O(n)/ Split the vector into the longest prefix of elements that satisfy+-- the predicate and the rest without copying.+span :: (a -> Bool) -> Vector a -> (Vector a, Vector a)+{-# INLINE span #-}+span = G.span++-- | /O(n)/ Split the vector into the longest prefix of elements that do not+-- satisfy the predicate and the rest without copying.+break :: (a -> Bool) -> Vector a -> (Vector a, Vector a)+{-# INLINE break #-}+break = G.break++-- Searching+-- ---------++infix 4 `elem`+-- | /O(n)/ Check if the vector contains an element+elem :: Eq a => a -> Vector a -> Bool+{-# INLINE elem #-}+elem = G.elem++infix 4 `notElem`+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem')+notElem :: Eq a => a -> Vector a -> Bool+{-# INLINE notElem #-}+notElem = G.notElem++-- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing'+-- if no such element exists.+find :: (a -> Bool) -> Vector a -> Maybe a+{-# INLINE find #-}+find = G.find++-- | /O(n)/ Yield 'Just' the index of the first element matching the predicate+-- or 'Nothing' if no such element exists.+findIndex :: (a -> Bool) -> Vector a -> Maybe Int+{-# INLINE findIndex #-}+findIndex = G.findIndex++-- | /O(n)/ Yield the indices of elements satisfying the predicate in ascending+-- order.+findIndices :: (a -> Bool) -> Vector a -> Vector Int+{-# INLINE findIndices #-}+findIndices = G.findIndices++-- | /O(n)/ Yield 'Just' the index of the first occurence of the given element or+-- 'Nothing' if the vector does not contain the element. This is a specialised+-- version of 'findIndex'.+elemIndex :: Eq a => a -> Vector a -> Maybe Int+{-# INLINE elemIndex #-}+elemIndex = G.elemIndex++-- | /O(n)/ Yield the indices of all occurences of the given element in+-- ascending order. This is a specialised version of 'findIndices'.+elemIndices :: Eq a => a -> Vector a -> Vector Int+{-# INLINE elemIndices #-}+elemIndices = G.elemIndices++-- Folding+-- -------++-- | /O(n)/ Left fold+foldl :: (a -> b -> a) -> a -> Vector b -> a+{-# INLINE foldl #-}+foldl = G.foldl++-- | /O(n)/ Left fold on non-empty vectors+foldl1 :: (a -> a -> a) -> Vector a -> a+{-# INLINE foldl1 #-}+foldl1 = G.foldl1++-- | /O(n)/ Left fold with strict accumulator+foldl' :: (a -> b -> a) -> a -> Vector b -> a+{-# INLINE foldl' #-}+foldl' = G.foldl'++-- | /O(n)/ Left fold on non-empty vectors with strict accumulator+foldl1' :: (a -> a -> a) -> Vector a -> a+{-# INLINE foldl1' #-}+foldl1' = G.foldl1'++-- | /O(n)/ Right fold+foldr :: (a -> b -> b) -> b -> Vector a -> b+{-# INLINE foldr #-}+foldr = G.foldr++-- | /O(n)/ Right fold on non-empty vectors+foldr1 :: (a -> a -> a) -> Vector a -> a+{-# INLINE foldr1 #-}+foldr1 = G.foldr1++-- | /O(n)/ Right fold with a strict accumulator+foldr' :: (a -> b -> b) -> b -> Vector a -> b+{-# INLINE foldr' #-}+foldr' = G.foldr'++-- | /O(n)/ Right fold on non-empty vectors with strict accumulator+foldr1' :: (a -> a -> a) -> Vector a -> a+{-# INLINE foldr1' #-}+foldr1' = G.foldr1'++-- | /O(n)/ Left fold (function applied to each element and its index)+ifoldl :: (a -> Int -> b -> a) -> a -> Vector b -> a+{-# INLINE ifoldl #-}+ifoldl = G.ifoldl++-- | /O(n)/ Left fold with strict accumulator (function applied to each element+-- and its index)+ifoldl' :: (a -> Int -> b -> a) -> a -> Vector b -> a+{-# INLINE ifoldl' #-}+ifoldl' = G.ifoldl'++-- | /O(n)/ Right fold (function applied to each element and its index)+ifoldr :: (Int -> a -> b -> b) -> b -> Vector a -> b+{-# INLINE ifoldr #-}+ifoldr = G.ifoldr++-- | /O(n)/ Right fold with strict accumulator (function applied to each+-- element and its index)+ifoldr' :: (Int -> a -> b -> b) -> b -> Vector a -> b+{-# INLINE ifoldr' #-}+ifoldr' = G.ifoldr'++-- Specialised folds+-- -----------------++-- | /O(n)/ Check if all elements satisfy the predicate.+all :: (a -> Bool) -> Vector a -> Bool+{-# INLINE all #-}+all = G.all++-- | /O(n)/ Check if any element satisfies the predicate.+any :: (a -> Bool) -> Vector a -> Bool+{-# INLINE any #-}+any = G.any++-- | /O(n)/ Check if all elements are 'True'+and :: Vector Bool -> Bool+{-# INLINE and #-}+and = G.and++-- | /O(n)/ Check if any element is 'True'+or :: Vector Bool -> Bool+{-# INLINE or #-}+or = G.or++-- | /O(n)/ Compute the sum of the elements+sum :: Num a => Vector a -> a+{-# INLINE sum #-}+sum = G.sum++-- | /O(n)/ Compute the produce of the elements+product :: Num a => Vector a -> a+{-# INLINE product #-}+product = G.product++-- | /O(n)/ Yield the maximum element of the vector. The vector may not be+-- empty.+maximum :: Ord a => Vector a -> a+{-# INLINE maximum #-}+maximum = G.maximum++-- | /O(n)/ Yield the maximum element of the vector according to the given+-- comparison function. The vector may not be empty.+maximumBy :: (a -> a -> Ordering) -> Vector a -> a+{-# INLINE maximumBy #-}+maximumBy = G.maximumBy++-- | /O(n)/ Yield the minimum element of the vector. The vector may not be+-- empty.+minimum :: Ord a => Vector a -> a+{-# INLINE minimum #-}+minimum = G.minimum++-- | /O(n)/ Yield the minimum element of the vector according to the given+-- comparison function. The vector may not be empty.+minimumBy :: (a -> a -> Ordering) -> Vector a -> a+{-# INLINE minimumBy #-}+minimumBy = G.minimumBy++-- | /O(n)/ Yield the index of the maximum element of the vector. The vector+-- may not be empty.+maxIndex :: Ord a => Vector a -> Int+{-# INLINE maxIndex #-}+maxIndex = G.maxIndex++-- | /O(n)/ Yield the index of the maximum element of the vector according to+-- the given comparison function. The vector may not be empty.+maxIndexBy :: (a -> a -> Ordering) -> Vector a -> Int+{-# INLINE maxIndexBy #-}+maxIndexBy = G.maxIndexBy++-- | /O(n)/ Yield the index of the minimum element of the vector. The vector+-- may not be empty.+minIndex :: Ord a => Vector a -> Int+{-# INLINE minIndex #-}+minIndex = G.minIndex++-- | /O(n)/ Yield the index of the minimum element of the vector according to+-- the given comparison function. The vector may not be empty.+minIndexBy :: (a -> a -> Ordering) -> Vector a -> Int+{-# INLINE minIndexBy #-}+minIndexBy = G.minIndexBy++-- Monadic folds+-- -------------++-- | /O(n)/ Monadic fold+foldM :: Monad m => (a -> b -> m a) -> a -> Vector b -> m a+{-# INLINE foldM #-}+foldM = G.foldM++-- | /O(n)/ Monadic fold over non-empty vectors+fold1M :: Monad m => (a -> a -> m a) -> Vector a -> m a+{-# INLINE fold1M #-}+fold1M = G.fold1M++-- | /O(n)/ Monadic fold with strict accumulator+foldM' :: Monad m => (a -> b -> m a) -> a -> Vector b -> m a+{-# INLINE foldM' #-}+foldM' = G.foldM'++-- | /O(n)/ Monad fold over non-empty vectors with strict accumulator+fold1M' :: Monad m => (a -> a -> m a) -> Vector a -> m a+{-# INLINE fold1M' #-}+fold1M' = G.fold1M'++-- Prefix sums (scans)+-- -------------------++-- | /O(n)/ Prescan+--+-- @+-- prescanl f z = 'init' . 'scanl' f z+-- @+--+-- Example: @prescanl (+) 0 \<1,2,3,4\> = \<0,1,3,6\>@+--+prescanl :: (a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE prescanl #-}+prescanl = G.prescanl++-- | /O(n)/ Prescan with strict accumulator+prescanl' :: (a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE prescanl' #-}+prescanl' = G.prescanl'++-- | /O(n)/ Scan+--+-- @+-- postscanl f z = 'tail' . 'scanl' f z+-- @+--+-- Example: @postscanl (+) 0 \<1,2,3,4\> = \<1,3,6,10\>@+--+postscanl :: (a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE postscanl #-}+postscanl = G.postscanl++-- | /O(n)/ Scan with strict accumulator+postscanl' :: (a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE postscanl' #-}+postscanl' = G.postscanl'++-- | /O(n)/ Haskell-style scan+--+-- > scanl f z <x1,...,xn> = <y1,...,y(n+1)>+-- > where y1 = z+-- > yi = f y(i-1) x(i-1)+--+-- Example: @scanl (+) 0 \<1,2,3,4\> = \<0,1,3,6,10\>@+-- +scanl :: (a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE scanl #-}+scanl = G.scanl++-- | /O(n)/ Haskell-style scan with strict accumulator+scanl' :: (a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE scanl' #-}+scanl' = G.scanl'++-- | /O(n)/ Scan over a non-empty vector+--+-- > scanl f <x1,...,xn> = <y1,...,yn>+-- > where y1 = x1+-- > yi = f y(i-1) xi+--+scanl1 :: (a -> a -> a) -> Vector a -> Vector a+{-# INLINE scanl1 #-}+scanl1 = G.scanl1++-- | /O(n)/ Scan over a non-empty vector with a strict accumulator+scanl1' :: (a -> a -> a) -> Vector a -> Vector a+{-# INLINE scanl1' #-}+scanl1' = G.scanl1'++-- | /O(n)/ Right-to-left prescan+--+-- @+-- prescanr f z = 'reverse' . 'prescanl' (flip f) z . 'reverse'+-- @+--+prescanr :: (a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE prescanr #-}+prescanr = G.prescanr++-- | /O(n)/ Right-to-left prescan with strict accumulator+prescanr' :: (a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE prescanr' #-}+prescanr' = G.prescanr'++-- | /O(n)/ Right-to-left scan+postscanr :: (a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE postscanr #-}+postscanr = G.postscanr++-- | /O(n)/ Right-to-left scan with strict accumulator+postscanr' :: (a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE postscanr' #-}+postscanr' = G.postscanr'++-- | /O(n)/ Right-to-left Haskell-style scan+scanr :: (a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE scanr #-}+scanr = G.scanr++-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator+scanr' :: (a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE scanr' #-}+scanr' = G.scanr'++-- | /O(n)/ Right-to-left scan over a non-empty vector+scanr1 :: (a -> a -> a) -> Vector a -> Vector a+{-# INLINE scanr1 #-}+scanr1 = G.scanr1++-- | /O(n)/ Right-to-left scan over a non-empty vector with a strict+-- accumulator+scanr1' :: (a -> a -> a) -> Vector a -> Vector a+{-# INLINE scanr1' #-}+scanr1' = G.scanr1'++-- Conversions - Lists+-- ------------------------++-- | /O(n)/ Convert a vector to a list+toList :: Vector a -> [a]+{-# INLINE toList #-}+toList = G.toList++-- | /O(n)/ Convert a list to a vector+fromList :: [a] -> Vector a+{-# INLINE fromList #-}+fromList = G.fromList++-- | /O(n)/ Convert the first @n@ elements of a list to a vector+--+-- @+-- fromListN n xs = 'fromList' ('take' n xs)+-- @+fromListN :: Int -> [a] -> Vector a+{-# INLINE fromListN #-}+fromListN = G.fromListN++-- Conversions - Mutable vectors+-- -----------------------------++-- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must+-- have the same length.+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. copy :: PrimMonad m => MVector (PrimState m) a -> Vector a -> m () {-# INLINE copy #-} copy = G.copy
Data/Vector/Generic.hs view
@@ -9,1358 +9,1663 @@ -- Stability : experimental -- Portability : non-portable -- --- Generic interface to pure vectors-----module Data.Vector.Generic (- -- * Immutable vectors- Vector(..), Mutable,-- -- * Length information- length, null,-- -- * Construction- empty, singleton, cons, snoc, replicate, generate, (++), force,-- -- * Accessing individual elements- (!), head, last, indexM, headM, lastM,- unsafeIndex, unsafeHead, unsafeLast,- unsafeIndexM, unsafeHeadM, unsafeLastM,-- -- * Subvectors- slice, init, tail, take, drop,- unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,-- -- * Permutations- accum, accumulate, accumulate_,- (//), update, update_,- backpermute, reverse,- unsafeAccum, unsafeAccumulate, unsafeAccumulate_,- unsafeUpd, unsafeUpdate, unsafeUpdate_,- unsafeBackpermute,-- -- * Mapping- map, imap, concatMap,-- -- * Zipping and unzipping- zipWith, zipWith3, zipWith4, zipWith5, zipWith6,- izipWith, izipWith3, izipWith4, izipWith5, izipWith6,- zip, zip3, zip4, zip5, zip6,- unzip, unzip3, unzip4, unzip5, unzip6,-- -- * Comparisons- eq, cmp,-- -- * Filtering- filter, ifilter, takeWhile, dropWhile,- partition, unstablePartition, span, break,-- -- * Searching- elem, notElem, find, findIndex, findIndices, elemIndex, elemIndices,-- -- * Folding- foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1',- ifoldl, ifoldl', ifoldr, ifoldr',- - -- * Specialised folds- all, any, and, or,- sum, product,- maximum, maximumBy, minimum, minimumBy,- minIndex, minIndexBy, maxIndex, maxIndexBy,-- -- * Unfolding- unfoldr, unfoldrN,-- -- * Scans- prescanl, prescanl',- postscanl, postscanl',- scanl, scanl', scanl1, scanl1',- prescanr, prescanr',- postscanr, postscanr',- scanr, scanr', scanr1, scanr1',-- -- * Enumeration- enumFromN, enumFromStepN, enumFromTo, enumFromThenTo,-- -- * 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,-- -- * Conversion to/from Streams- stream, unstream, streamR, unstreamR,-- -- * Recycling support- new, clone,-- -- * Utilities for defining Data instances- gfoldl, dataCast, mkType-) where--import Data.Vector.Generic.Base--import Data.Vector.Generic.Mutable ( MVector )-import qualified Data.Vector.Generic.Mutable as M--import qualified Data.Vector.Generic.New as New-import Data.Vector.Generic.New ( New )--import qualified Data.Vector.Fusion.Stream as Stream-import Data.Vector.Fusion.Stream ( Stream, MStream, inplace )-import qualified Data.Vector.Fusion.Stream.Monadic as MStream-import Data.Vector.Fusion.Stream.Size-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,- init, tail, take, drop, reverse,- map, concatMap,- zipWith, zipWith3, zip, zip3, unzip, unzip3,- filter, takeWhile, dropWhile, span, break,- elem, notElem,- foldl, foldl1, foldr, foldr1,- all, any, and, or, sum, product, maximum, minimum,- scanl, scanl1, scanr, scanr1,- enumFromTo, enumFromThenTo,- mapM, mapM_ )--import Data.Typeable ( Typeable1, gcast1 )-import Data.Data ( Data, DataType, mkNorepType )--#include "vector.h"---- Fusion--- ---------- | Construct a pure vector from a monadic initialiser -new :: Vector v a => New v a -> v a-{-# INLINE_STREAM new #-}-new m = m `seq` runST (unsafeFreeze =<< New.run m)--clone :: Vector v a => v a -> New v a-{-# INLINE_STREAM clone #-}-clone v = v `seq` New.create (- do- mv <- M.new (length v)- unsafeCopy mv v- return mv)---- | Convert a vector to a 'Stream'-stream :: Vector v a => v a -> Stream a-{-# INLINE_STREAM stream #-}-stream v = v `seq` (Stream.unfoldr get 0 `Stream.sized` Exact n)- where- n = length v-- -- NOTE: the False case comes first in Core so making it the recursive one- -- makes the code easier to read- {-# INLINE get #-}- get i | i >= n = Nothing- | otherwise = case basicUnsafeIndexM v i of Box x -> Just (x, i+1)---- | Create a vector from a 'Stream'-unstream :: Vector v a => Stream a -> v a-{-# INLINE unstream #-}-unstream s = new (New.unstream s)--{-# RULES--"stream/unstream [Vector]" forall s.- stream (new (New.unstream s)) = s--"New.unstream/stream [Vector]" forall v.- New.unstream (stream v) = clone v--"clone/new [Vector]" forall p.- clone (new p) = p--"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--"uninplace [Vector]"- forall (f :: forall m. Monad m => MStream m a -> MStream m a) m.- stream (new (New.transform f m)) = inplace f (stream (new m))-- #-}---- | Convert a vector to a 'Stream'-streamR :: Vector v a => v a -> Stream a-{-# INLINE_STREAM streamR #-}-streamR v = v `seq` (Stream.unfoldr get n `Stream.sized` Exact n)- where- n = length v-- {-# INLINE get #-}- get 0 = Nothing- get i = let i' = i-1- in- case basicUnsafeIndexM v i' of Box x -> Just (x, i')---- | Create a vector from a 'Stream'-unstreamR :: Vector v a => Stream a -> v a-{-# INLINE unstreamR #-}-unstreamR s = new (New.unstreamR s)--{-# RULES--"streamR/unstreamR [Vector]" forall s.- streamR (new (New.unstreamR s)) = s--"New.unstreamR/streamR/new [Vector]" forall p.- New.unstreamR (streamR (new p)) = p--"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 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))-- #-}---- Length--- --------length :: Vector v a => v a -> Int-{-# INLINE_STREAM length #-}-length v = basicLength v--{-# RULES--"length/unstream [Vector]" forall s.- length (new (New.unstream s)) = Stream.length s-- #-}--null :: Vector v a => v a -> Bool-{-# INLINE_STREAM null #-}-null v = basicLength v == 0--{-# RULES--"null/unstream [Vector]" forall s.- null (new (New.unstream s)) = Stream.null s-- #-}---- Construction--- ---------------- | Empty vector-empty :: Vector v a => v a-{-# INLINE empty #-}-empty = unstream Stream.empty---- | Vector with exaclty one element-singleton :: forall v a. Vector v a => a -> v a-{-# INLINE singleton #-}-singleton x = elemseq (undefined :: v a) x- $ unstream (Stream.singleton x)---- | Vector of the given length with the given value in each position-replicate :: forall v a. Vector v a => Int -> a -> v a-{-# INLINE replicate #-}-replicate n x = elemseq (undefined :: v a) x- $ unstream- $ Stream.replicate n x---- | Generate a vector of the given length by applying the function to each--- index-generate :: Vector v a => Int -> (Int -> a) -> v a-{-# INLINE generate #-}-generate n f = unstream (Stream.generate n f)---- | Prepend an element-cons :: forall v a. Vector v a => a -> v a -> v a-{-# INLINE cons #-}-cons x v = elemseq (undefined :: v a) x- $ unstream- $ Stream.cons x- $ stream v---- | Append an element-snoc :: forall v a. Vector v a => v a -> a -> v a-{-# INLINE snoc #-}-snoc v x = elemseq (undefined :: v a) x- $ unstream- $ Stream.snoc (stream v) x--infixr 5 ++--- | Concatenate two vectors-(++) :: Vector v a => v a -> v a -> v a-{-# INLINE (++) #-}-v ++ w = unstream (stream v Stream.++ stream w)---- | Create a copy of a vector. Useful when dealing with slices.-force :: Vector v a => v a -> v a-{-# INLINE_STREAM force #-}-force v = new (clone v)---- Accessing individual elements--- --------------------------------- | Indexing-(!) :: Vector v a => v a -> Int -> a-{-# INLINE_STREAM (!) #-}-v ! i = BOUNDS_CHECK(checkIndex) "(!)" i (length v)- $ unId (basicUnsafeIndexM v i)---- | First element-head :: Vector v a => v a -> a-{-# INLINE_STREAM head #-}-head v = v ! 0---- | Last element-last :: Vector v a => v a -> a-{-# INLINE_STREAM last #-}-last v = v ! (length v - 1)---- | Unsafe indexing without bounds checking-unsafeIndex :: Vector v a => v a -> Int -> a-{-# INLINE_STREAM unsafeIndex #-}-unsafeIndex v i = UNSAFE_CHECK(checkIndex) "unsafeIndex" i (length v)- $ unId (basicUnsafeIndexM v i)---- | Yield the first element of a vector without checking if the vector is--- empty-unsafeHead :: Vector v a => v a -> a-{-# INLINE_STREAM unsafeHead #-}-unsafeHead v = unsafeIndex v 0---- | Yield the last element of a vector without checking if the vector is--- empty-unsafeLast :: Vector v a => v a -> a-{-# INLINE_STREAM unsafeLast #-}-unsafeLast v = unsafeIndex v (length v - 1)--{-# RULES--"(!)/unstream [Vector]" forall i s.- new (New.unstream s) ! i = s Stream.!! i--"head/unstream [Vector]" forall s.- head (new (New.unstream s)) = Stream.head s--"last/unstream [Vector]" forall s.- last (new (New.unstream s)) = Stream.last s--"unsafeIndex/unstream [Vector]" forall i s.- unsafeIndex (new (New.unstream s)) i = s Stream.!! i--"unsafeHead/unstream [Vector]" forall s.- unsafeHead (new (New.unstream s)) = Stream.head s--"unsafeLast/unstream [Vector]" forall s.- unsafeLast (new (New.unstream s)) = Stream.last s-- #-}---- | Monadic indexing which can be strict in the vector while remaining lazy in--- the element.-indexM :: (Vector v a, Monad m) => v a -> Int -> m a-{-# INLINE_STREAM indexM #-}-indexM v i = BOUNDS_CHECK(checkIndex) "indexM" i (length v)- $ basicUnsafeIndexM v i--headM :: (Vector v a, Monad m) => v a -> m a-{-# INLINE_STREAM headM #-}-headM v = indexM v 0--lastM :: (Vector v a, Monad m) => v a -> m a-{-# INLINE_STREAM lastM #-}-lastM v = indexM v (length v - 1)---- | Unsafe monadic indexing without bounds checks-unsafeIndexM :: (Vector v a, Monad m) => v a -> Int -> m a-{-# INLINE_STREAM unsafeIndexM #-}-unsafeIndexM v i = UNSAFE_CHECK(checkIndex) "unsafeIndexM" i (length v)- $ basicUnsafeIndexM v i--unsafeHeadM :: (Vector v a, Monad m) => v a -> m a-{-# INLINE_STREAM unsafeHeadM #-}-unsafeHeadM v = unsafeIndexM v 0--unsafeLastM :: (Vector v a, Monad m) => v a -> m a-{-# INLINE_STREAM unsafeLastM #-}-unsafeLastM v = unsafeIndexM v (length v - 1)---- FIXME: the rhs of these rules are lazy in the stream which is WRONG-{- RULES--"indexM/unstream [Vector]" forall v i s.- indexM (new' v (New.unstream s)) i = return (s Stream.!! i)--"headM/unstream [Vector]" forall v s.- headM (new' v (New.unstream s)) = return (Stream.head s)--"lastM/unstream [Vector]" forall v s.- lastM (new' v (New.unstream s)) = return (Stream.last s)-- -}---- Subarrays--- ------------- | Yield a part of the vector without copying it.-slice :: Vector v a => Int -- ^ starting index- -> Int -- ^ length- -> v a- -> v a-{-# INLINE_STREAM slice #-}-slice i n v = BOUNDS_CHECK(checkSlice) "slice" i n (length v)- $ basicUnsafeSlice i n v---- | Yield all but the last element without copying.-init :: Vector v a => v a -> v a-{-# INLINE_STREAM init #-}-init v = slice 0 (length v - 1) v---- | All but the first element (without copying).-tail :: Vector v a => v a -> v a-{-# INLINE_STREAM tail #-}-tail v = slice 1 (length v - 1) v---- | Yield the first @n@ elements without copying.-take :: Vector v a => Int -> v a -> v a-{-# INLINE_STREAM take #-}-take n v = unsafeSlice 0 (delay_inline min n' (length v)) v- where n' = max n 0---- | Yield all but the first @n@ elements without copying.-drop :: Vector v a => Int -> v a -> v a-{-# INLINE_STREAM drop #-}-drop n v = unsafeSlice (delay_inline min n' len)- (delay_inline max 0 (len - n')) v- where n' = max n 0- len = length v---- | Unsafely yield a part of the vector without copying it and without--- performing bounds checks.-unsafeSlice :: Vector v a => Int -- ^ starting index- -> Int -- ^ length- -> v a- -> v a-{-# INLINE_STREAM unsafeSlice #-}-unsafeSlice i n v = UNSAFE_CHECK(checkSlice) "unsafeSlice" i n (length v)- $ basicUnsafeSlice i n v--unsafeInit :: Vector v a => v a -> v a-{-# INLINE_STREAM unsafeInit #-}-unsafeInit v = unsafeSlice 0 (length v - 1) v--unsafeTail :: Vector v a => v a -> v a-{-# INLINE_STREAM unsafeTail #-}-unsafeTail v = unsafeSlice 1 (length v - 1) v--unsafeTake :: Vector v a => Int -> v a -> v a-{-# INLINE unsafeTake #-}-unsafeTake n v = unsafeSlice 0 n v--unsafeDrop :: Vector v a => Int -> v a -> v a-{-# INLINE unsafeDrop #-}-unsafeDrop n v = unsafeSlice n (length v - n) v--{-# RULES--"slice/new [Vector]" forall i n p.- slice i n (new p) = new (New.slice i n p)--"init/new [Vector]" forall p.- init (new p) = new (New.init p)--"tail/new [Vector]" forall p.- tail (new p) = new (New.tail p)--"take/new [Vector]" forall n p.- take n (new p) = new (New.take n p)--"drop/new [Vector]" forall n p.- drop n (new p) = new (New.drop n p)--"unsafeSlice/new [Vector]" forall i n p.- unsafeSlice i n (new p) = new (New.unsafeSlice i n p)--"unsafeInit/new [Vector]" forall p.- unsafeInit (new p) = new (New.unsafeInit p)--"unsafeTail/new [Vector]" forall p.- unsafeTail (new p) = new (New.unsafeTail p)-- #-}---- Permutations--- --------------unsafeAccum_stream- :: Vector v a => (a -> b -> a) -> v a -> Stream (Int,b) -> v a-{-# INLINE unsafeAccum_stream #-}-unsafeAccum_stream f = modifyWithStream (M.unsafeAccum f)--unsafeAccum :: Vector v a => (a -> b -> a) -> v a -> [(Int,b)] -> v a-{-# INLINE unsafeAccum #-}-unsafeAccum f v us = unsafeAccum_stream f v (Stream.fromList us)--unsafeAccumulate :: (Vector v a, Vector v (Int, b))- => (a -> b -> a) -> v a -> v (Int,b) -> v a-{-# INLINE unsafeAccumulate #-}-unsafeAccumulate f v us = unsafeAccum_stream f v (stream us)--unsafeAccumulate_ :: (Vector v a, Vector v Int, Vector v b)- => (a -> b -> a) -> v a -> v Int -> v b -> v a-{-# INLINE unsafeAccumulate_ #-}-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 #-}-accum_stream f = modifyWithStream (M.accum f)--accum :: Vector v a => (a -> b -> a) -> v a -> [(Int,b)] -> v a-{-# INLINE accum #-}-accum f v us = accum_stream f v (Stream.fromList us)--accumulate :: (Vector v a, Vector v (Int, b))- => (a -> b -> a) -> v a -> v (Int,b) -> v a-{-# INLINE accumulate #-}-accumulate f v us = accum_stream f v (stream us)--accumulate_ :: (Vector v a, Vector v Int, Vector v b)- => (a -> b -> a) -> v a -> v Int -> v b -> v a-{-# INLINE accumulate_ #-}-accumulate_ f v is xs = accum_stream f v (Stream.zipWith (,) (stream is)- (stream xs))- --unsafeUpdate_stream :: Vector v a => v a -> Stream (Int,a) -> v a-{-# INLINE unsafeUpdate_stream #-}-unsafeUpdate_stream = modifyWithStream M.unsafeUpdate--unsafeUpd :: Vector v a => v a -> [(Int, a)] -> v a-{-# INLINE unsafeUpd #-}-unsafeUpd v us = unsafeUpdate_stream v (Stream.fromList us)--unsafeUpdate :: (Vector v a, Vector v (Int, a)) => v a -> v (Int, a) -> v a-{-# INLINE unsafeUpdate #-}-unsafeUpdate v w = unsafeUpdate_stream v (stream w)--unsafeUpdate_ :: (Vector v a, Vector v Int) => v a -> v Int -> v a -> v a-{-# INLINE unsafeUpdate_ #-}-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 #-}-update_stream = modifyWithStream M.update--(//) :: Vector v a => v a -> [(Int, a)] -> v a-{-# INLINE (//) #-}-v // us = update_stream v (Stream.fromList us)--update :: (Vector v a, Vector v (Int, a)) => v a -> v (Int, a) -> v a-{-# INLINE update #-}-update v w = update_stream v (stream w)--update_ :: (Vector v a, Vector v Int) => v a -> v Int -> v a -> v a-{-# INLINE update_ #-}-update_ v is w = update_stream v (Stream.zipWith (,) (stream is) (stream w))---- This somewhat non-intuitive definition ensures that the resulting vector--- does not retain references to the original one even if it is lazy in its--- elements. This would not be the case if we simply used------ backpermute v is = map (v!) is-backpermute :: (Vector v a, Vector v Int) => v a -> v Int -> v a-{-# INLINE backpermute #-}-backpermute v is = seq v- $ unstream- $ Stream.unbox- $ Stream.map (indexM v)- $ stream is--unsafeBackpermute :: (Vector v a, Vector v Int) => v a -> v Int -> v a-{-# INLINE unsafeBackpermute #-}-unsafeBackpermute v is = seq v- $ unstream- $ Stream.unbox- $ Stream.map (unsafeIndexM v)- $ stream is---- FIXME: make this fuse better, add support for recycling-reverse :: (Vector v a) => v a -> v a-{-# INLINE reverse #-}-reverse = unstream . streamR---- Mapping--- ----------- | Map a function over a vector-map :: (Vector v a, Vector v b) => (a -> b) -> v a -> v b-{-# INLINE map #-}-map f = unstream . inplace (MStream.map f) . stream---- | Apply a function to every index/value pair-imap :: (Vector v a, Vector v b) => (Int -> a -> b) -> v a -> v b-{-# INLINE imap #-}-imap f = unstream . inplace (MStream.map (uncurry f) . MStream.indexed)- . stream--concatMap :: (Vector v a, Vector v b) => (a -> v b) -> v a -> v b-{-# INLINE concatMap #-}-concatMap f = unstream . Stream.concatMap (stream . f) . stream---- Zipping/unzipping--- --------------------- | Zip two vectors with the given function.-zipWith :: (Vector v a, Vector v b, Vector v c)- => (a -> b -> c) -> v a -> v b -> v c-{-# INLINE zipWith #-}-zipWith f xs ys = unstream (Stream.zipWith f (stream xs) (stream ys))---- | Zip three vectors with the given function.-zipWith3 :: (Vector v a, Vector v b, Vector v c, Vector v d)- => (a -> b -> c -> d) -> v a -> v b -> v c -> v d-{-# INLINE zipWith3 #-}-zipWith3 f as bs cs = unstream (Stream.zipWith3 f (stream as)- (stream bs)- (stream cs))--zipWith4 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e)- => (a -> b -> c -> d -> e) -> v a -> v b -> v c -> v d -> v e-{-# INLINE zipWith4 #-}-zipWith4 f as bs cs ds- = unstream (Stream.zipWith4 f (stream as)- (stream bs)- (stream cs)- (stream ds))--zipWith5 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,- Vector v f)- => (a -> b -> c -> d -> e -> f) -> v a -> v b -> v c -> v d -> v e- -> v f-{-# INLINE zipWith5 #-}-zipWith5 f as bs cs ds es- = unstream (Stream.zipWith5 f (stream as)- (stream bs)- (stream cs)- (stream ds)- (stream es))--zipWith6 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,- Vector v f, Vector v g)- => (a -> b -> c -> d -> e -> f -> g)- -> v a -> v b -> v c -> v d -> v e -> v f -> v g-{-# INLINE zipWith6 #-}-zipWith6 f as bs cs ds es fs- = unstream (Stream.zipWith6 f (stream as)- (stream bs)- (stream cs)- (stream ds)- (stream es)- (stream fs))---- | Zip two vectors and their indices with the given function.-izipWith :: (Vector v a, Vector v b, Vector v c)- => (Int -> a -> b -> c) -> v a -> v b -> v c-{-# INLINE izipWith #-}-izipWith f xs ys = unstream- (Stream.zipWith (uncurry f) (Stream.indexed (stream xs))- (stream ys))---- | Zip three vectors and their indices with the given function.-izipWith3 :: (Vector v a, Vector v b, Vector v c, Vector v d)- => (Int -> a -> b -> c -> d) -> v a -> v b -> v c -> v d-{-# INLINE izipWith3 #-}-izipWith3 f as bs cs- = unstream (Stream.zipWith3 (uncurry f) (Stream.indexed (stream as))- (stream bs)- (stream cs))--izipWith4 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e)- => (Int -> a -> b -> c -> d -> e) -> v a -> v b -> v c -> v d -> v e-{-# INLINE izipWith4 #-}-izipWith4 f as bs cs ds- = unstream (Stream.zipWith4 (uncurry f) (Stream.indexed (stream as))- (stream bs)- (stream cs)- (stream ds))--izipWith5 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,- Vector v f)- => (Int -> a -> b -> c -> d -> e -> f) -> v a -> v b -> v c -> v d- -> v e -> v f-{-# INLINE izipWith5 #-}-izipWith5 f as bs cs ds es- = unstream (Stream.zipWith5 (uncurry f) (Stream.indexed (stream as))- (stream bs)- (stream cs)- (stream ds)- (stream es))--izipWith6 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,- Vector v f, Vector v g)- => (Int -> a -> b -> c -> d -> e -> f -> g)- -> v a -> v b -> v c -> v d -> v e -> v f -> v g-{-# INLINE izipWith6 #-}-izipWith6 f as bs cs ds es fs- = unstream (Stream.zipWith6 (uncurry f) (Stream.indexed (stream as))- (stream bs)- (stream cs)- (stream ds)- (stream es)- (stream fs))--zip :: (Vector v a, Vector v b, Vector v (a,b)) => v a -> v b -> v (a, b)-{-# INLINE zip #-}-zip = zipWith (,)--zip3 :: (Vector v a, Vector v b, Vector v c, Vector v (a, b, c))- => v a -> v b -> v c -> v (a, b, c)-{-# INLINE zip3 #-}-zip3 = zipWith3 (,,)--zip4 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v (a, b, c, d))- => v a -> v b -> v c -> v d -> v (a, b, c, d)-{-# INLINE zip4 #-}-zip4 = zipWith4 (,,,)--zip5 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,- Vector v (a, b, c, d, e))- => v a -> v b -> v c -> v d -> v e -> v (a, b, c, d, e)-{-# INLINE zip5 #-}-zip5 = zipWith5 (,,,,)--zip6 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,- Vector v f, Vector v (a, b, c, d, e, f))- => v a -> v b -> v c -> v d -> v e -> v f -> v (a, b, c, d, e, f)-{-# INLINE zip6 #-}-zip6 = zipWith6 (,,,,,)--unzip :: (Vector v a, Vector v b, Vector v (a,b)) => v (a, b) -> (v a, v b)-{-# INLINE unzip #-}-unzip xs = (map fst xs, map snd xs)--unzip3 :: (Vector v a, Vector v b, Vector v c, Vector v (a, b, c))- => v (a, b, c) -> (v a, v b, v c)-{-# INLINE unzip3 #-}-unzip3 xs = (map (\(a, b, c) -> a) xs,- map (\(a, b, c) -> b) xs,- map (\(a, b, c) -> c) xs)--unzip4 :: (Vector v a, Vector v b, Vector v c, Vector v d,- Vector v (a, b, c, d))- => v (a, b, c, d) -> (v a, v b, v c, v d)-{-# INLINE unzip4 #-}-unzip4 xs = (map (\(a, b, c, d) -> a) xs,- map (\(a, b, c, d) -> b) xs,- map (\(a, b, c, d) -> c) xs,- map (\(a, b, c, d) -> d) xs)--unzip5 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,- Vector v (a, b, c, d, e))- => v (a, b, c, d, e) -> (v a, v b, v c, v d, v e)-{-# INLINE unzip5 #-}-unzip5 xs = (map (\(a, b, c, d, e) -> a) xs,- map (\(a, b, c, d, e) -> b) xs,- map (\(a, b, c, d, e) -> c) xs,- map (\(a, b, c, d, e) -> d) xs,- map (\(a, b, c, d, e) -> e) xs)--unzip6 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,- Vector v f, Vector v (a, b, c, d, e, f))- => v (a, b, c, d, e, f) -> (v a, v b, v c, v d, v e, v f)-{-# INLINE unzip6 #-}-unzip6 xs = (map (\(a, b, c, d, e, f) -> a) xs,- map (\(a, b, c, d, e, f) -> b) xs,- map (\(a, b, c, d, e, f) -> c) xs,- map (\(a, b, c, d, e, f) -> d) xs,- map (\(a, b, c, d, e, f) -> e) xs,- map (\(a, b, c, d, e, f) -> f) xs)---- Comparisons--- -------------eq :: (Vector v a, Eq a) => v a -> v a -> Bool-{-# INLINE eq #-}-xs `eq` ys = stream xs == stream ys--cmp :: (Vector v a, Ord a) => v a -> v a -> Ordering-{-# INLINE cmp #-}-cmp xs ys = compare (stream xs) (stream ys)---- Filtering--- ------------- | Drop elements that do not satisfy the predicate-filter :: Vector v a => (a -> Bool) -> v a -> v a-{-# INLINE filter #-}-filter f = unstream . inplace (MStream.filter f) . stream---- | Drop elements that do not satisfy the predicate (applied to values and--- their indices)-ifilter :: Vector v a => (Int -> a -> Bool) -> v a -> v a-{-# INLINE ifilter #-}-ifilter f = unstream- . inplace (MStream.map snd . MStream.filter (uncurry f)- . MStream.indexed)- . stream---- | Yield the longest prefix of elements satisfying the predicate.-takeWhile :: Vector v a => (a -> Bool) -> v a -> v a-{-# INLINE takeWhile #-}-takeWhile f = unstream . Stream.takeWhile f . stream---- | Drop the longest prefix of elements that satisfy the predicate.-dropWhile :: Vector v a => (a -> Bool) -> v a -> v a-{-# INLINE dropWhile #-}-dropWhile f = unstream . Stream.dropWhile f . stream---- | Split the vector in two parts, the first one containing those elements--- that satisfy the predicate and the second one those that don't. The--- relative order of the elements is preserved at the cost of a (sometimes)--- reduced performance compared to 'unstablePartition'.-partition :: Vector v a => (a -> Bool) -> v a -> (v a, v a)-{-# INLINE partition #-}-partition f = partition_stream f . stream---- FIXME: Make this inplace-fusible (look at how stable_partition is--- implemented in C++)--partition_stream :: Vector v a => (a -> Bool) -> Stream a -> (v a, v a)-{-# INLINE_STREAM partition_stream #-}-partition_stream f s = s `seq` runST (- do- (mv1,mv2) <- M.partitionStream f s- v1 <- unsafeFreeze mv1- v2 <- unsafeFreeze mv2- return (v1,v2))---- | Split the vector in two parts, the first one containing those elements--- that satisfy the predicate and the second one those that don't. The order--- of the elements is not preserved but the operation is often faster than--- 'partition'.-unstablePartition :: Vector v a => (a -> Bool) -> v a -> (v a, v a)-{-# INLINE unstablePartition #-}-unstablePartition f = unstablePartition_stream f . stream--unstablePartition_stream- :: Vector v a => (a -> Bool) -> Stream a -> (v a, v a)-{-# INLINE_STREAM unstablePartition_stream #-}-unstablePartition_stream f s = s `seq` runST (- do- (mv1,mv2) <- M.unstablePartitionStream f s- v1 <- unsafeFreeze mv1- v2 <- unsafeFreeze mv2- return (v1,v2))--unstablePartition_new :: Vector v a => (a -> Bool) -> New v a -> (v a, v a)-{-# INLINE_STREAM unstablePartition_new #-}-unstablePartition_new f (New.New p) = runST (- do- mv <- p- i <- M.unstablePartition f mv- v <- unsafeFreeze mv- return (unsafeTake i v, unsafeDrop i v))--{-# RULES--"unstablePartition" forall f p.- unstablePartition_stream f (stream (new p))- = unstablePartition_new f p-- #-}----- FIXME: make span and break fusible---- | Split the vector into the longest prefix of elements that satisfy the--- predicate and the rest.-span :: Vector v a => (a -> Bool) -> v a -> (v a, v a)-{-# INLINE span #-}-span f = break (not . f)---- | Split the vector into the longest prefix of elements that do not satisfy--- the predicate and the rest.-break :: Vector v a => (a -> Bool) -> v a -> (v a, v a)-{-# INLINE break #-}-break f xs = case findIndex f xs of- Just i -> (unsafeSlice 0 i xs, unsafeSlice i (length xs - i) xs)- Nothing -> (xs, empty)- ---- Searching--- -----------infix 4 `elem`--- | Check whether the vector contains an element-elem :: (Vector v a, Eq a) => a -> v a -> Bool-{-# INLINE elem #-}-elem x = Stream.elem x . stream--infix 4 `notElem`--- | Inverse of `elem`-notElem :: (Vector v a, Eq a) => a -> v a -> Bool-{-# INLINE notElem #-}-notElem x = Stream.notElem x . stream---- | Yield 'Just' the first element matching the predicate or 'Nothing' if no--- such element exists.-find :: Vector v a => (a -> Bool) -> v a -> Maybe a-{-# INLINE find #-}-find f = Stream.find f . stream---- | Yield 'Just' the index of the first element matching the predicate or--- 'Nothing' if no such element exists.-findIndex :: Vector v a => (a -> Bool) -> v a -> Maybe Int-{-# INLINE findIndex #-}-findIndex f = Stream.findIndex f . stream---- | Yield the indices of elements satisfying the predicate-findIndices :: (Vector v a, Vector v Int) => (a -> Bool) -> v a -> v Int-{-# INLINE findIndices #-}-findIndices f = unstream- . inplace (MStream.map fst . MStream.filter (f . snd)- . MStream.indexed)- . stream---- | Yield 'Just' the index of the first occurence of the given element or--- 'Nothing' if the vector does not contain the element-elemIndex :: (Vector v a, Eq a) => a -> v a -> Maybe Int-{-# INLINE elemIndex #-}-elemIndex x = findIndex (x==)---- | Yield the indices of all occurences of the given element-elemIndices :: (Vector v a, Vector v Int, Eq a) => a -> v a -> v Int-{-# INLINE elemIndices #-}-elemIndices x = findIndices (x==)---- Folding--- ----------- | Left fold-foldl :: Vector v b => (a -> b -> a) -> a -> v b -> a-{-# INLINE foldl #-}-foldl f z = Stream.foldl f z . stream---- | Left fold on non-empty vectors-foldl1 :: Vector v a => (a -> a -> a) -> v a -> a-{-# INLINE foldl1 #-}-foldl1 f = Stream.foldl1 f . stream---- | Left fold with strict accumulator-foldl' :: Vector v b => (a -> b -> a) -> a -> v b -> a-{-# INLINE foldl' #-}-foldl' f z = Stream.foldl' f z . stream---- | Left fold on non-empty vectors with strict accumulator-foldl1' :: Vector v a => (a -> a -> a) -> v a -> a-{-# INLINE foldl1' #-}-foldl1' f = Stream.foldl1' f . stream---- | Right fold-foldr :: Vector v a => (a -> b -> b) -> b -> v a -> b-{-# INLINE foldr #-}-foldr f z = Stream.foldr f z . stream---- | Right fold on non-empty vectors-foldr1 :: Vector v a => (a -> a -> a) -> v a -> a-{-# INLINE foldr1 #-}-foldr1 f = Stream.foldr1 f . stream---- | Right fold with a strict accumulator-foldr' :: Vector v a => (a -> b -> b) -> b -> v a -> b-{-# INLINE foldr' #-}-foldr' f z = Stream.foldl' (flip f) z . streamR---- | Right fold on non-empty vectors with strict accumulator-foldr1' :: Vector v a => (a -> a -> a) -> v a -> a-{-# INLINE foldr1' #-}-foldr1' f = Stream.foldl1' (flip f) . streamR---- | Left fold (function applied to each element and its index)-ifoldl :: Vector v b => (a -> Int -> b -> a) -> a -> v b -> a-{-# INLINE ifoldl #-}-ifoldl f z = Stream.foldl (uncurry . f) z . Stream.indexed . stream---- | Left fold with strict accumulator (function applied to each element and--- its index)-ifoldl' :: Vector v b => (a -> Int -> b -> a) -> a -> v b -> a-{-# INLINE ifoldl' #-}-ifoldl' f z = Stream.foldl' (uncurry . f) z . Stream.indexed . stream---- | Right fold (function applied to each element and its index)-ifoldr :: Vector v a => (Int -> a -> b -> b) -> b -> v a -> b-{-# INLINE ifoldr #-}-ifoldr f z = Stream.foldr (uncurry f) z . Stream.indexed . stream---- | Right fold with strict accumulator (function applied to each element and--- its index)-ifoldr' :: Vector v a => (Int -> a -> b -> b) -> b -> v a -> b-{-# INLINE ifoldr' #-}-ifoldr' f z xs = Stream.foldl' (flip (uncurry f)) z- $ Stream.indexedR (length xs) $ streamR xs---- Specialised folds--- -------------------all :: Vector v a => (a -> Bool) -> v a -> Bool-{-# INLINE all #-}-all f = Stream.and . Stream.map f . stream--any :: Vector v a => (a -> Bool) -> v a -> Bool-{-# INLINE any #-}-any f = Stream.or . Stream.map f . stream--and :: Vector v Bool => v Bool -> Bool-{-# INLINE and #-}-and = Stream.and . stream--or :: Vector v Bool => v Bool -> Bool-{-# INLINE or #-}-or = Stream.or . stream--sum :: (Vector v a, Num a) => v a -> a-{-# INLINE sum #-}-sum = Stream.foldl' (+) 0 . stream--product :: (Vector v a, Num a) => v a -> a-{-# INLINE product #-}-product = Stream.foldl' (*) 1 . stream--maximum :: (Vector v a, Ord a) => v a -> a-{-# INLINE maximum #-}-maximum = Stream.foldl1' max . stream--maximumBy :: Vector v a => (a -> a -> Ordering) -> v a -> a-{-# INLINE maximumBy #-}-maximumBy cmp = Stream.foldl1' maxBy . stream- where- {-# INLINE maxBy #-}- maxBy x y = case cmp x y of- LT -> y- _ -> x--minimum :: (Vector v a, Ord a) => v a -> a-{-# INLINE minimum #-}-minimum = Stream.foldl1' min . stream--minimumBy :: Vector v a => (a -> a -> Ordering) -> v a -> a-{-# INLINE minimumBy #-}-minimumBy cmp = Stream.foldl1' minBy . stream- where- {-# INLINE minBy #-}- minBy x y = case cmp x y of- GT -> y- _ -> x--maxIndex :: (Vector v a, Ord a) => v a -> Int-{-# INLINE maxIndex #-}-maxIndex = maxIndexBy compare--maxIndexBy :: Vector v a => (a -> a -> Ordering) -> v a -> Int-{-# INLINE maxIndexBy #-}-maxIndexBy cmp = fst . Stream.foldl1' imax . Stream.indexed . stream- where- imax (i,x) (j,y) = case cmp x y of- LT -> (j,y)- _ -> (i,x)--minIndex :: (Vector v a, Ord a) => v a -> Int-{-# INLINE minIndex #-}-minIndex = minIndexBy compare--minIndexBy :: Vector v a => (a -> a -> Ordering) -> v a -> Int-{-# INLINE minIndexBy #-}-minIndexBy cmp = fst . Stream.foldl1' imin . Stream.indexed . stream- where- imin (i,x) (j,y) = case cmp x y of- GT -> (j,y)- _ -> (i,x)----- Unfolding--- ------------- | Unfold-unfoldr :: Vector v a => (b -> Maybe (a, b)) -> b -> v a-{-# INLINE unfoldr #-}-unfoldr f = unstream . Stream.unfoldr f---- | Unfoldr at most @n@ elements.-unfoldrN :: Vector v a => Int -> (b -> Maybe (a, b)) -> b -> v a-{-# INLINE unfoldrN #-}-unfoldrN n f = unstream . Stream.unfoldrN n f---- Scans--- --------- | Prefix scan-prescanl :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a-{-# INLINE prescanl #-}-prescanl f z = unstream . inplace (MStream.prescanl f z) . stream---- | Prefix scan with strict accumulator-prescanl' :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a-{-# INLINE prescanl' #-}-prescanl' f z = unstream . inplace (MStream.prescanl' f z) . stream---- | Suffix scan-postscanl :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a-{-# INLINE postscanl #-}-postscanl f z = unstream . inplace (MStream.postscanl f z) . stream---- | Suffix scan with strict accumulator-postscanl' :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a-{-# INLINE postscanl' #-}-postscanl' f z = unstream . inplace (MStream.postscanl' f z) . stream---- | Haskell-style scan-scanl :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a-{-# INLINE scanl #-}-scanl f z = unstream . Stream.scanl f z . stream---- | Haskell-style scan with strict accumulator-scanl' :: (Vector v a, Vector 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 :: Vector 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' :: Vector v a => (a -> a -> a) -> v a -> v a-{-# INLINE scanl1' #-}-scanl1' f = unstream . inplace (MStream.scanl1' f) . stream----- | Prefix right-to-left scan-prescanr :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b-{-# INLINE prescanr #-}-prescanr f z = unstreamR . inplace (MStream.prescanl (flip f) z) . streamR---- | Prefix right-to-left scan with strict accumulator-prescanr' :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b-{-# INLINE prescanr' #-}-prescanr' f z = unstreamR . inplace (MStream.prescanl' (flip f) z) . streamR---- | Suffix right-to-left scan-postscanr :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b-{-# INLINE postscanr #-}-postscanr f z = unstreamR . inplace (MStream.postscanl (flip f) z) . streamR---- | Suffix right-to-left scan with strict accumulator-postscanr' :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b-{-# INLINE postscanr' #-}-postscanr' f z = unstreamR . inplace (MStream.postscanl' (flip f) z) . streamR---- | Haskell-style right-to-left scan-scanr :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b-{-# INLINE scanr #-}-scanr f z = unstreamR . Stream.scanl (flip f) z . streamR---- | Haskell-style right-to-left scan with strict accumulator-scanr' :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b-{-# INLINE scanr' #-}-scanr' f z = unstreamR . Stream.scanl' (flip f) z . streamR---- | Right-to-left scan over a non-empty vector-scanr1 :: Vector v a => (a -> a -> a) -> v a -> v a-{-# INLINE scanr1 #-}-scanr1 f = unstreamR . inplace (MStream.scanl1 (flip f)) . streamR---- | Right-to-left scan over a non-empty vector with a strict accumulator-scanr1' :: Vector v a => (a -> a -> a) -> v a -> v a-{-# INLINE scanr1' #-}-scanr1' f = unstreamR . inplace (MStream.scanl1' (flip f)) . streamR---- Enumeration--- --------------- | Yield a vector of the given length containing the values @x@, @x+1@ etc.--- This operation is usually more efficient than 'enumFromTo'.-enumFromN :: (Vector v a, Num a) => a -> Int -> v a-{-# INLINE enumFromN #-}-enumFromN x n = enumFromStepN x 1 n---- | Yield a vector of the given length containing the values @x@, @x+y@,--- @x+y+y@ etc. This operations is usually more efficient than--- 'enumFromThenTo'.-enumFromStepN :: forall v a. (Vector v a, Num a) => a -> a -> Int -> v a-{-# INLINE enumFromStepN #-}-enumFromStepN x y n = elemseq (undefined :: v a) x- $ elemseq (undefined :: v a) y- $ unstream- $ Stream.enumFromStepN x y n---- | Enumerate values from @x@ to @y@.------ /WARNING:/ This operation can be very inefficient. If at all possible, use--- 'enumFromN' instead.-enumFromTo :: (Vector v a, Enum a) => a -> a -> v a-{-# INLINE enumFromTo #-}-enumFromTo x y = unstream (Stream.enumFromTo x y)---- | Enumerate values from @x@ to @y@ with a specific step @z@.------ /WARNING:/ This operation can be very inefficient. If at all possible, use--- 'enumFromStepN' instead.-enumFromThenTo :: (Vector v a, Enum a) => a -> a -> a -> v a-{-# INLINE enumFromThenTo #-}-enumFromThenTo x y z = unstream (Stream.enumFromThenTo x y z)---- Conversion to/from lists--- ---------------------------- | Convert a vector to a list-toList :: Vector v a => v a -> [a]-{-# INLINE toList #-}-toList = Stream.toList . stream---- | Convert a list to a vector-fromList :: Vector v a => [a] -> v a-{-# INLINE fromList #-}-fromList = unstream . Stream.fromList---- | Convert the first @n@ elements of a list to a vector------ > fromListN n xs = fromList (take n xs)-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--- -------------------------- | Destructively initialise a vector.-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 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 #-}-modify p = new . New.modify p . clone---- We have to make sure that this is strict in the stream but we can't seq on--- it while fusion is happening. Hence this ugliness.-modifyWithStream :: Vector v a- => (forall s. Mutable v s a -> Stream b -> ST s ())- -> v a -> Stream b -> v a-{-# INLINE modifyWithStream #-}-modifyWithStream p v s = new (New.modifyWithStream p (clone v) s)---- | Copy an immutable vector into a mutable one. The two vectors must have--- the same length. This is not checked.-unsafeCopy- :: (PrimMonad m, Vector v a) => Mutable v (PrimState m) a -> v a -> m ()-{-# INLINE unsafeCopy #-}-unsafeCopy dst src = UNSAFE_CHECK(check) "unsafeCopy" "length mismatch"- (M.length dst == length src)- $ (dst `seq` src `seq` basicUnsafeCopy dst src)- --- | Copy an immutable vector into a mutable one. The two vectors must have the--- same length.-copy- :: (PrimMonad m, Vector v a) => Mutable v (PrimState m) a -> v a -> m ()-{-# INLINE copy #-}-copy dst src = BOUNDS_CHECK(check) "copy" "length mismatch"- (M.length dst == length src)- $ unsafeCopy dst src---- Utilities for defining Data instances--- -------------------------------------+-- Generic interface to pure vectors.+--++module Data.Vector.Generic (+ -- * Immutable vectors+ Vector(..), Mutable,++ -- * Accessors++ -- ** Length information+ length, null,++ -- ** Indexing+ (!), head, last,+ unsafeIndex, unsafeHead, unsafeLast,++ -- ** Monadic indexing+ indexM, headM, lastM,+ unsafeIndexM, unsafeHeadM, unsafeLastM,++ -- ** Extracting subvectors (slicing)+ slice, init, tail, take, drop,+ unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,++ -- * Construction++ -- ** Initialisation+ empty, singleton, replicate, generate,++ -- ** Monadic initialisation+ replicateM, create,++ -- ** Unfolding+ unfoldr, unfoldrN,++ -- ** Enumeration+ enumFromN, enumFromStepN, enumFromTo, enumFromThenTo,++ -- ** Concatenation+ cons, snoc, (++),++ -- ** Restricting memory usage+ force,++ -- * Modifying vectors++ -- ** Bulk updates+ (//), update, update_,+ unsafeUpd, unsafeUpdate, unsafeUpdate_,++ -- ** Accumulations+ accum, accumulate, accumulate_,+ unsafeAccum, unsafeAccumulate, unsafeAccumulate_,++ -- ** Permutations + reverse, backpermute, unsafeBackpermute,++ -- ** Safe destructive updates+ modify,++ -- * Elementwise operations++ -- ** Mapping+ map, imap, concatMap,++ -- ** Monadic mapping+ mapM, mapM_, forM, forM_,++ -- ** Zipping+ zipWith, zipWith3, zipWith4, zipWith5, zipWith6,+ izipWith, izipWith3, izipWith4, izipWith5, izipWith6,+ zip, zip3, zip4, zip5, zip6,++ -- ** Monadic zipping+ zipWithM, zipWithM_,++ -- ** Unzipping+ unzip, unzip3, unzip4, unzip5, unzip6,++ -- * Working with predicates++ -- ** Filtering+ filter, ifilter, filterM,+ takeWhile, dropWhile,++ -- ** Partitioning+ partition, unstablePartition, span, break,++ -- ** Searching+ elem, notElem, find, findIndex, findIndices, elemIndex, elemIndices,++ -- * Folding+ foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1',+ ifoldl, ifoldl', ifoldr, ifoldr',++ -- ** Specialised folds+ all, any, and, or,+ sum, product,+ maximum, maximumBy, minimum, minimumBy,+ minIndex, minIndexBy, maxIndex, maxIndexBy,++ -- ** Monadic folds+ foldM, foldM', fold1M, fold1M',++ -- * Prefix sums (scans)+ prescanl, prescanl',+ postscanl, postscanl',+ scanl, scanl', scanl1, scanl1',+ prescanr, prescanr',+ postscanr, postscanr',+ scanr, scanr', scanr1, scanr1',++ -- * Conversions++ -- ** Lists+ toList, fromList, fromListN,++ -- ** Mutable vectors+ copy, unsafeCopy,++ -- * Fusion support++ -- ** Conversion to/from Streams+ stream, unstream, streamR, unstreamR,++ -- ** Recycling support+ new, clone,++ -- * Utilities++ -- ** Comparisons+ eq, cmp,++ -- ** @Data@ and @Typeable@+ gfoldl, dataCast, mkType+) where++import Data.Vector.Generic.Base++import Data.Vector.Generic.Mutable ( MVector )+import qualified Data.Vector.Generic.Mutable as M++import qualified Data.Vector.Generic.New as New+import Data.Vector.Generic.New ( New )++import qualified Data.Vector.Fusion.Stream as Stream+import Data.Vector.Fusion.Stream ( Stream, MStream, inplace )+import qualified Data.Vector.Fusion.Stream.Monadic as MStream+import Data.Vector.Fusion.Stream.Size+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,+ init, tail, take, drop, reverse,+ map, concatMap,+ zipWith, zipWith3, zip, zip3, unzip, unzip3,+ filter, takeWhile, dropWhile, span, break,+ elem, notElem,+ foldl, foldl1, foldr, foldr1,+ all, any, and, or, sum, product, maximum, minimum,+ scanl, scanl1, scanr, scanr1,+ enumFromTo, enumFromThenTo,+ mapM, mapM_ )++import Data.Typeable ( Typeable1, gcast1 )+import Data.Data ( Data, DataType, mkNorepType )++#include "vector.h"++-- Length information+-- ------------------++-- | /O(1)/ Yield the length of the vector.+length :: Vector v a => v a -> Int+{-# INLINE_STREAM length #-}+length v = basicLength v++{-# RULES++"length/unstream [Vector]" forall s.+ length (new (New.unstream s)) = Stream.length s++ #-}++-- | /O(1)/ Test whether a vector if empty+null :: Vector v a => v a -> Bool+{-# INLINE_STREAM null #-}+null v = basicLength v == 0++{-# RULES++"null/unstream [Vector]" forall s.+ null (new (New.unstream s)) = Stream.null s++ #-}++-- Indexing+-- --------++-- | O(1) Indexing+(!) :: Vector v a => v a -> Int -> a+{-# INLINE_STREAM (!) #-}+v ! i = BOUNDS_CHECK(checkIndex) "(!)" i (length v)+ $ unId (basicUnsafeIndexM v i)++-- | /O(1)/ First element+head :: Vector v a => v a -> a+{-# INLINE_STREAM head #-}+head v = v ! 0++-- | /O(1)/ Last element+last :: Vector v a => v a -> a+{-# INLINE_STREAM last #-}+last v = v ! (length v - 1)++-- | /O(1)/ Unsafe indexing without bounds checking+unsafeIndex :: Vector v a => v a -> Int -> a+{-# INLINE_STREAM unsafeIndex #-}+unsafeIndex v i = UNSAFE_CHECK(checkIndex) "unsafeIndex" i (length v)+ $ unId (basicUnsafeIndexM v i)++-- | /O(1)/ First element without checking if the vector is empty+unsafeHead :: Vector v a => v a -> a+{-# INLINE_STREAM unsafeHead #-}+unsafeHead v = unsafeIndex v 0++-- | /O(1)/ Last element without checking if the vector is empty+unsafeLast :: Vector v a => v a -> a+{-# INLINE_STREAM unsafeLast #-}+unsafeLast v = unsafeIndex v (length v - 1)++{-# RULES++"(!)/unstream [Vector]" forall i s.+ new (New.unstream s) ! i = s Stream.!! i++"head/unstream [Vector]" forall s.+ head (new (New.unstream s)) = Stream.head s++"last/unstream [Vector]" forall s.+ last (new (New.unstream s)) = Stream.last s++"unsafeIndex/unstream [Vector]" forall i s.+ unsafeIndex (new (New.unstream s)) i = s Stream.!! i++"unsafeHead/unstream [Vector]" forall s.+ unsafeHead (new (New.unstream s)) = Stream.head s++"unsafeLast/unstream [Vector]" forall s.+ unsafeLast (new (New.unstream s)) = Stream.last s++ #-}++-- Monadic indexing+-- ----------------++-- | /O(1)/ Indexing in a monad.+--+-- The monad allows operations to be strict in the vector when necessary.+-- Suppose vector copying is implemented like this:+--+-- > copy mv v = ... write mv i (v ! i) ...+--+-- For lazy vectors, @v ! i@ would not be evaluated which means that @mv@+-- would unnecessarily retain a reference to @v@ in each element written.+--+-- With 'indexM', copying can be implemented like this instead:+--+-- > copy mv v = ... do+-- > x <- indexM v i+-- > write mv i x+--+-- Here, no references to @v@ are retained because indexing (but /not/ the+-- elements) is evaluated eagerly.+--+indexM :: (Vector v a, Monad m) => v a -> Int -> m a+{-# INLINE_STREAM indexM #-}+indexM v i = BOUNDS_CHECK(checkIndex) "indexM" i (length v)+ $ basicUnsafeIndexM v i++-- | /O(1)/ First element of a vector in a monad. See 'indexM' for an+-- explanation of why this is useful.+headM :: (Vector v a, Monad m) => v a -> m a+{-# INLINE_STREAM headM #-}+headM v = indexM v 0++-- | /O(1)/ Last element of a vector in a monad. See 'indexM' for an+-- explanation of why this is useful.+lastM :: (Vector v a, Monad m) => v a -> m a+{-# INLINE_STREAM lastM #-}+lastM v = indexM v (length v - 1)++-- | /O(1)/ Indexing in a monad without bounds checks. See 'indexM' for an+-- explanation of why this is useful.+unsafeIndexM :: (Vector v a, Monad m) => v a -> Int -> m a+{-# INLINE_STREAM unsafeIndexM #-}+unsafeIndexM v i = UNSAFE_CHECK(checkIndex) "unsafeIndexM" i (length v)+ $ basicUnsafeIndexM v i++-- | /O(1)/ First element in a monad without checking for empty vectors.+-- See 'indexM' for an explanation of why this is useful.+unsafeHeadM :: (Vector v a, Monad m) => v a -> m a+{-# INLINE_STREAM unsafeHeadM #-}+unsafeHeadM v = unsafeIndexM v 0++-- | /O(1)/ Last element in a monad without checking for empty vectors.+-- See 'indexM' for an explanation of why this is useful.+unsafeLastM :: (Vector v a, Monad m) => v a -> m a+{-# INLINE_STREAM unsafeLastM #-}+unsafeLastM v = unsafeIndexM v (length v - 1)++-- FIXME: the rhs of these rules are lazy in the stream which is WRONG+{- RULES++"indexM/unstream [Vector]" forall v i s.+ indexM (new' v (New.unstream s)) i = return (s Stream.!! i)++"headM/unstream [Vector]" forall v s.+ headM (new' v (New.unstream s)) = return (Stream.head s)++"lastM/unstream [Vector]" forall v s.+ lastM (new' v (New.unstream s)) = return (Stream.last s)++ -}++-- Extracting subvectors (slicing)+-- -------------------------------++-- | /O(1)/ Yield a slice of the vector without copying it. The vector must+-- contain at least @i+n@ elements.+slice :: Vector v a => Int -- ^ @i@ starting index+ -> Int -- ^ @n@ length+ -> v a+ -> v a+{-# INLINE_STREAM slice #-}+slice i n v = BOUNDS_CHECK(checkSlice) "slice" i n (length v)+ $ basicUnsafeSlice i n v++-- | /O(1)/ Yield all but the last element without copying. The vector may not+-- be empty.+init :: Vector v a => v a -> v a+{-# INLINE_STREAM init #-}+init v = slice 0 (length v - 1) v++-- | /O(1)/ Yield all but the first element without copying. The vector may not+-- be empty.+tail :: Vector v a => v a -> v a+{-# INLINE_STREAM tail #-}+tail v = slice 1 (length v - 1) v++-- | /O(1)/ Yield at the first @n@ elements without copying. The vector may+-- contain less than @n@ elements in which case it is returned unchanged.+take :: Vector v a => Int -> v a -> v a+{-# INLINE_STREAM take #-}+take n v = unsafeSlice 0 (delay_inline min n' (length v)) v+ where n' = max n 0++-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may+-- contain less than @n@ elements in which case an empty vector is returned.+drop :: Vector v a => Int -> v a -> v a+{-# INLINE_STREAM drop #-}+drop n v = unsafeSlice (delay_inline min n' len)+ (delay_inline max 0 (len - n')) v+ where 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+ -> Int -- ^ @n@ length+ -> v a+ -> v a+{-# INLINE_STREAM unsafeSlice #-}+unsafeSlice i n v = UNSAFE_CHECK(checkSlice) "unsafeSlice" i n (length v)+ $ basicUnsafeSlice i n v++-- | /O(1)/ Yield all but the last element without copying. The vector may not+-- be empty but this is not checked.+unsafeInit :: Vector v a => v a -> v a+{-# INLINE_STREAM unsafeInit #-}+unsafeInit v = unsafeSlice 0 (length v - 1) v++-- | /O(1)/ Yield all but the first element without copying. The vector may not+-- be empty but this is not checked.+unsafeTail :: Vector v a => v a -> v a+{-# INLINE_STREAM unsafeTail #-}+unsafeTail v = unsafeSlice 1 (length v - 1) v++-- | /O(1)/ Yield the first @n@ elements without copying. The vector must+-- contain at least @n@ elements but this is not checked.+unsafeTake :: Vector v a => Int -> v a -> v a+{-# INLINE unsafeTake #-}+unsafeTake n v = unsafeSlice 0 n v++-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector+-- must contain at least @n@ elements but this is not checked.+unsafeDrop :: Vector v a => Int -> v a -> v a+{-# INLINE unsafeDrop #-}+unsafeDrop n v = unsafeSlice n (length v - n) v++{-# RULES++"slice/new [Vector]" forall i n p.+ slice i n (new p) = new (New.slice i n p)++"init/new [Vector]" forall p.+ init (new p) = new (New.init p)++"tail/new [Vector]" forall p.+ tail (new p) = new (New.tail p)++"take/new [Vector]" forall n p.+ take n (new p) = new (New.take n p)++"drop/new [Vector]" forall n p.+ drop n (new p) = new (New.drop n p)++"unsafeSlice/new [Vector]" forall i n p.+ unsafeSlice i n (new p) = new (New.unsafeSlice i n p)++"unsafeInit/new [Vector]" forall p.+ unsafeInit (new p) = new (New.unsafeInit p)++"unsafeTail/new [Vector]" forall p.+ unsafeTail (new p) = new (New.unsafeTail p)++ #-}++-- Initialisation+-- --------------++-- | /O(1)/ Empty vector+empty :: Vector v a => v a+{-# INLINE empty #-}+empty = unstream Stream.empty++-- | /O(1)/ Vector with exactly one element+singleton :: forall v a. Vector v a => a -> v a+{-# INLINE singleton #-}+singleton x = elemseq (undefined :: v a) x+ $ unstream (Stream.singleton x)++-- | /O(n)/ Vector of the given length with the same value in each position+replicate :: forall v a. Vector v a => Int -> a -> v a+{-# INLINE replicate #-}+replicate n x = elemseq (undefined :: v a) x+ $ unstream+ $ Stream.replicate n x++-- | /O(n)/ Construct a vector of the given length by applying the function to+-- each index+generate :: Vector v a => Int -> (Int -> a) -> v a+{-# INLINE generate #-}+generate n f = unstream (Stream.generate n f)++-- Unfolding+-- ---------++-- | /O(n)/ Construct a vector by repeatedly applying the generator function+-- to a seed. The generator function yields 'Just' the next element and the+-- new seed or 'Nothing' if there are no more elements.+--+-- > unfoldr (\n -> if n == 0 then Nothing else Just (n,n-1)) 10+-- > = <10,9,8,7,6,5,4,3,2,1>+unfoldr :: Vector v a => (b -> Maybe (a, b)) -> b -> v a+{-# INLINE unfoldr #-}+unfoldr f = unstream . Stream.unfoldr f++-- | /O(n)/ Construct a vector with at most @n@ by repeatedly applying the+-- generator function to the a seed. The generator function yields 'Just' the+-- next element and the new seed or 'Nothing' if there are no more elements.+--+-- > unfoldrN 3 (\n -> Just (n,n-1)) 10 = <10,9,8>+unfoldrN :: Vector v a => Int -> (b -> Maybe (a, b)) -> b -> v a+{-# INLINE unfoldrN #-}+unfoldrN n f = unstream . Stream.unfoldrN n f++-- Enumeration+-- -----------++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+1@+-- etc. This operation is usually more efficient than 'enumFromTo'.+--+-- > enumFromN 5 3 = <5,6,7>+enumFromN :: (Vector v a, Num a) => a -> Int -> v a+{-# INLINE enumFromN #-}+enumFromN x n = enumFromStepN x 1 n++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,+-- @x+y+y@ etc. This operations is usually more efficient than 'enumFromThenTo'.+--+-- > enumFromStepN 1 0.1 5 = <1,1.1,1.2,1.3,1.4>+enumFromStepN :: forall v a. (Vector v a, Num a) => a -> a -> Int -> v a+{-# INLINE enumFromStepN #-}+enumFromStepN x y n = elemseq (undefined :: v a) x+ $ elemseq (undefined :: v a) y+ $ unstream+ $ Stream.enumFromStepN x y n++-- | /O(n)/ Enumerate values from @x@ to @y@.+--+-- /WARNING:/ This operation can be very inefficient. If at all possible, use+-- 'enumFromN' instead.+enumFromTo :: (Vector v a, Enum a) => a -> a -> v a+{-# INLINE enumFromTo #-}+enumFromTo x y = unstream (Stream.enumFromTo x y)++-- | /O(n)/ Enumerate values from @x@ to @y@ with a specific step @z@.+--+-- /WARNING:/ This operation can be very inefficient. If at all possible, use+-- 'enumFromStepN' instead.+enumFromThenTo :: (Vector v a, Enum a) => a -> a -> a -> v a+{-# INLINE enumFromThenTo #-}+enumFromThenTo x y z = unstream (Stream.enumFromThenTo x y z)++-- Concatenation+-- -------------++-- | /O(n)/ Prepend an element+cons :: forall v a. Vector v a => a -> v a -> v a+{-# INLINE cons #-}+cons x v = elemseq (undefined :: v a) x+ $ unstream+ $ Stream.cons x+ $ stream v++-- | /O(n)/ Append an element+snoc :: forall v a. Vector v a => v a -> a -> v a+{-# INLINE snoc #-}+snoc v x = elemseq (undefined :: v a) x+ $ unstream+ $ Stream.snoc (stream v) x++infixr 5 +++-- | /O(m+n)/ Concatenate two vectors+(++) :: Vector v a => v a -> v a -> v a+{-# INLINE (++) #-}+v ++ w = unstream (stream v Stream.++ stream w)++-- Monadic initialisation+-- ----------------------++-- | /O(n)/ Execute 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)+-- FIXME: specialise for ST and IO?+{-# INLINE replicateM #-}+replicateM n m = fromListN n `Monad.liftM` Monad.replicateM n m++-- | Execute the monadic action and freeze the resulting vector.+--+-- @+-- create (do { v \<- 'M.new' 2; 'M.write' v 0 \'a\'; 'M.write' v 1 \'b\' }) = \<'a','b'\>+-- @+create :: Vector v a => (forall s. ST s (Mutable v s a)) -> v a+{-# INLINE create #-}+create p = new (New.create p)++-- Restricting memory usage+-- ------------------------++-- | /O(n)/ Yield the argument but force it not to retain any extra memory,+-- possibly by copying it.+--+-- This is especially useful when dealing with slices. For example:+--+-- > force (slice 0 2 <huge vector>)+--+-- Here, the slice retains a reference to the huge vector. Forcing it creates+-- a copy of just the elements that belong to the slice and allows the huge+-- vector to be garbage collected.+force :: Vector v a => v a -> v a+-- FIXME: we probably ought to inline this later as the rules still might fire+-- otherwise+{-# INLINE_STREAM force #-}+force v = new (clone v)++-- Bulk updates+-- ------------++-- | /O(m+n)/ For each pair @(i,a)@ from the list, replace the vector+-- element at position @i@ by @a@.+--+-- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7>+--+(//) :: Vector v a => v a -- ^ initial vector (of length @m@)+ -> [(Int, a)] -- ^ list of index/value pairs (of length @n@)+ -> v a+{-# INLINE (//) #-}+v // us = update_stream v (Stream.fromList us)++-- | /O(m+n)/ For each pair @(i,a)@ from the vector of index/value pairs,+-- replace the vector element at position @i@ by @a@.+--+-- > update <5,9,2,7> <(2,1),(0,3),(2,8)> = <3,9,8,7>+--+update :: (Vector v a, Vector v (Int, a))+ => v a -- ^ initial vector (of length @m@)+ -> v (Int, a) -- ^ vector of index/value pairs (of length @n@)+ -> v a+{-# INLINE update #-}+update v w = update_stream v (stream w)++-- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the+-- corresponding value @a@ from the value vector, replace the element of the+-- initial vector at position @i@ by @a@.+--+-- > update_ <5,9,2,7> <2,0,2> <1,3,8> = <3,9,8,7>+--+-- This function is useful for instances of 'Vector' that cannot store pairs.+-- Otherwise, 'update' is probably more convenient.+--+-- @+-- update_ xs is ys = 'update' xs ('zip' is ys)+-- @+update_ :: (Vector v a, Vector v Int)+ => v a -- ^ initial vector (of length @m@)+ -> v Int -- ^ index vector (of length @n1@)+ -> v a -- ^ value vector (of length @n2@)+ -> v a+{-# INLINE update_ #-}+update_ v is w = update_stream v (Stream.zipWith (,) (stream is) (stream w))++update_stream :: Vector v a => v a -> Stream (Int,a) -> v a+{-# INLINE update_stream #-}+update_stream = modifyWithStream M.update++-- | Same as ('//') but without bounds checking.+unsafeUpd :: Vector v a => v a -> [(Int, a)] -> v a+{-# INLINE unsafeUpd #-}+unsafeUpd v us = unsafeUpdate_stream v (Stream.fromList us)++-- | Same as 'update' but without bounds checking.+unsafeUpdate :: (Vector v a, Vector v (Int, a)) => v a -> v (Int, a) -> v a+{-# INLINE unsafeUpdate #-}+unsafeUpdate v w = unsafeUpdate_stream v (stream w)++-- | Same as 'update_' but without bounds checking.+unsafeUpdate_ :: (Vector v a, Vector v Int) => v a -> v Int -> v a -> v a+{-# INLINE unsafeUpdate_ #-}+unsafeUpdate_ v is w+ = unsafeUpdate_stream v (Stream.zipWith (,) (stream is) (stream w))++unsafeUpdate_stream :: Vector v a => v a -> Stream (Int,a) -> v a+{-# INLINE unsafeUpdate_stream #-}+unsafeUpdate_stream = modifyWithStream M.unsafeUpdate++-- Accumulations+-- -------------++-- | /O(m+n)/ For each pair @(i,b)@ from the list, replace the vector element+-- @a@ at position @i@ by @f a b@.+--+-- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4>+accum :: Vector v a+ => (a -> b -> a) -- ^ accumulating function @f@+ -> v a -- ^ initial vector (of length @m@)+ -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)+ -> v a+{-# INLINE accum #-}+accum f v us = accum_stream f v (Stream.fromList us)++-- | /O(m+n)/ For each pair @(i,b)@ from the vector of pairs, replace the vector+-- element @a@ at position @i@ by @f a b@.+--+-- > accumulate (+) <5,9,2> <(2,4),(1,6),(0,3),(1,7)> = <5+3, 9+6+7, 2+4>+accumulate :: (Vector v a, Vector v (Int, b))+ => (a -> b -> a) -- ^ accumulating function @f@+ -> v a -- ^ initial vector (of length @m@)+ -> v (Int,b) -- ^ vector of index/value pairs (of length @n@)+ -> v a+{-# INLINE accumulate #-}+accumulate f v us = accum_stream f v (stream us)++-- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the+-- corresponding value @b@ from the the value vector,+-- replace the element of the initial vector at+-- position @i@ by @f a b@.+--+-- > accumulate_ (+) <5,9,2> <2,1,0,1> <4,6,3,7> = <5+3, 9+6+7, 2+4>+--+-- This function is useful for instances of 'Vector' that cannot store pairs.+-- Otherwise, 'accumulate' is probably more convenient:+--+-- @+-- accumulate_ f as is bs = 'accumulate' f as ('zip' is bs)+-- @+accumulate_ :: (Vector v a, Vector v Int, Vector v b)+ => (a -> b -> a) -- ^ accumulating function @f@+ -> v a -- ^ initial vector (of length @m@)+ -> v Int -- ^ index vector (of length @n1@)+ -> v b -- ^ value vector (of length @n2@)+ -> v a+{-# INLINE accumulate_ #-}+accumulate_ f v is xs = accum_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 #-}+accum_stream f = modifyWithStream (M.accum f)++-- | Same as 'accum' but without bounds checking.+unsafeAccum :: Vector v a => (a -> b -> a) -> v a -> [(Int,b)] -> v a+{-# INLINE unsafeAccum #-}+unsafeAccum f v us = unsafeAccum_stream f v (Stream.fromList us)++-- | Same as 'accumulate' but without bounds checking.+unsafeAccumulate :: (Vector v a, Vector v (Int, b))+ => (a -> b -> a) -> v a -> v (Int,b) -> v a+{-# INLINE unsafeAccumulate #-}+unsafeAccumulate f v us = unsafeAccum_stream f v (stream us)++-- | Same as 'accumulate_' but without bounds checking.+unsafeAccumulate_ :: (Vector v a, Vector v Int, Vector v b)+ => (a -> b -> a) -> v a -> v Int -> v b -> v a+{-# INLINE unsafeAccumulate_ #-}+unsafeAccumulate_ f v is xs+ = unsafeAccum_stream f v (Stream.zipWith (,) (stream is) (stream xs))++unsafeAccum_stream+ :: Vector v a => (a -> b -> a) -> v a -> Stream (Int,b) -> v a+{-# INLINE unsafeAccum_stream #-}+unsafeAccum_stream f = modifyWithStream (M.unsafeAccum f)++-- Permutations+-- ------------++-- | /O(n)/ Reverse a vector+reverse :: (Vector v a) => v a -> v a+{-# INLINE reverse #-}+-- FIXME: make this fuse better, add support for recycling+reverse = unstream . streamR++-- | /O(n)/ Yield the vector obtained by replacing each element @i@ of the+-- index vector by @xs'!'i@. This is equivalent to @'map' (xs'!') is@ but is+-- often much more efficient.+--+-- > backpermute <a,b,c,d> <0,3,2,3,1,0> = <a,d,c,d,b,a>+backpermute :: (Vector v a, Vector v Int)+ => v a -- ^ @xs@ value vector+ -> v Int -- ^ @is@ index vector (of length @n@)+ -> v a+{-# INLINE backpermute #-}+-- This somewhat non-intuitive definition ensures that the resulting vector+-- does not retain references to the original one even if it is lazy in its+-- elements. This would not be the case if we simply used map (v!)+backpermute v is = seq v+ $ unstream+ $ Stream.unbox+ $ Stream.map (indexM v)+ $ stream is++-- | Same as 'backpermute' but without bounds checking.+unsafeBackpermute :: (Vector v a, Vector v Int) => v a -> v Int -> v a+{-# INLINE unsafeBackpermute #-}+unsafeBackpermute v is = seq v+ $ unstream+ $ Stream.unbox+ $ Stream.map (unsafeIndexM v)+ $ stream is++-- Safe destructive updates+-- ------------------------++-- | Apply a destructive operation to a vector. The operation will be+-- performed in place if it is safe to do so and will modify a copy of the+-- vector otherwise.+--+-- @+-- modify (\\v -> 'M.write' v 0 \'x\') ('replicate' 3 \'a\') = \<\'x\',\'a\',\'a\'\>+-- @+modify :: Vector v a => (forall s. Mutable v s a -> ST s ()) -> v a -> v a+{-# INLINE modify #-}+modify p = new . New.modify p . clone++-- We have to make sure that this is strict in the stream but we can't seq on+-- it while fusion is happening. Hence this ugliness.+modifyWithStream :: Vector v a+ => (forall s. Mutable v s a -> Stream b -> ST s ())+ -> v a -> Stream b -> v a+{-# INLINE modifyWithStream #-}+modifyWithStream p v s = new (New.modifyWithStream p (clone v) s)++-- Mapping+-- -------++-- | /O(n)/ Map a function over a vector+map :: (Vector v a, Vector v b) => (a -> b) -> v a -> v b+{-# INLINE map #-}+map f = unstream . inplace (MStream.map f) . stream++-- | /O(n)/ Apply a function to every element of a vector and its index+imap :: (Vector v a, Vector v b) => (Int -> a -> b) -> v a -> v b+{-# INLINE imap #-}+imap f = unstream . inplace (MStream.map (uncurry f) . MStream.indexed)+ . stream++-- | Map a function over a vector and concatenate the results.+concatMap :: (Vector v a, Vector v b) => (a -> v b) -> v a -> v b+{-# INLINE concatMap #-}+concatMap f = unstream . Stream.concatMap (stream . f) . stream++-- Monadic mapping+-- ---------------++-- | /O(n)/ 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)+-- FIXME: specialise for ST and IO?+{-# INLINE mapM #-}+mapM f = unstreamM . Stream.mapM f . stream++-- | /O(n)/ 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++-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a+-- vector of results. Equvalent to @flip 'mapM'@.+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++-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the+-- results. Equivalent to @flip 'mapM_'@.+forM_ :: (Monad m, Vector v a) => v a -> (a -> m b) -> m ()+{-# INLINE forM_ #-}+forM_ as f = mapM_ f as++-- Zipping+-- -------++-- | /O(min(m,n))/ Zip two vectors with the given function.+zipWith :: (Vector v a, Vector v b, Vector v c)+ => (a -> b -> c) -> v a -> v b -> v c+{-# INLINE zipWith #-}+zipWith f xs ys = unstream (Stream.zipWith f (stream xs) (stream ys))++-- | Zip three vectors with the given function.+zipWith3 :: (Vector v a, Vector v b, Vector v c, Vector v d)+ => (a -> b -> c -> d) -> v a -> v b -> v c -> v d+{-# INLINE zipWith3 #-}+zipWith3 f as bs cs = unstream (Stream.zipWith3 f (stream as)+ (stream bs)+ (stream cs))++zipWith4 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e)+ => (a -> b -> c -> d -> e) -> v a -> v b -> v c -> v d -> v e+{-# INLINE zipWith4 #-}+zipWith4 f as bs cs ds+ = unstream (Stream.zipWith4 f (stream as)+ (stream bs)+ (stream cs)+ (stream ds))++zipWith5 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,+ Vector v f)+ => (a -> b -> c -> d -> e -> f) -> v a -> v b -> v c -> v d -> v e+ -> v f+{-# INLINE zipWith5 #-}+zipWith5 f as bs cs ds es+ = unstream (Stream.zipWith5 f (stream as)+ (stream bs)+ (stream cs)+ (stream ds)+ (stream es))++zipWith6 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,+ Vector v f, Vector v g)+ => (a -> b -> c -> d -> e -> f -> g)+ -> v a -> v b -> v c -> v d -> v e -> v f -> v g+{-# INLINE zipWith6 #-}+zipWith6 f as bs cs ds es fs+ = unstream (Stream.zipWith6 f (stream as)+ (stream bs)+ (stream cs)+ (stream ds)+ (stream es)+ (stream fs))++-- | /O(min(m,n))/ Zip two vectors with a function that also takes the+-- elements' indices.+izipWith :: (Vector v a, Vector v b, Vector v c)+ => (Int -> a -> b -> c) -> v a -> v b -> v c+{-# INLINE izipWith #-}+izipWith f xs ys = unstream+ (Stream.zipWith (uncurry f) (Stream.indexed (stream xs))+ (stream ys))++izipWith3 :: (Vector v a, Vector v b, Vector v c, Vector v d)+ => (Int -> a -> b -> c -> d) -> v a -> v b -> v c -> v d+{-# INLINE izipWith3 #-}+izipWith3 f as bs cs+ = unstream (Stream.zipWith3 (uncurry f) (Stream.indexed (stream as))+ (stream bs)+ (stream cs))++izipWith4 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e)+ => (Int -> a -> b -> c -> d -> e) -> v a -> v b -> v c -> v d -> v e+{-# INLINE izipWith4 #-}+izipWith4 f as bs cs ds+ = unstream (Stream.zipWith4 (uncurry f) (Stream.indexed (stream as))+ (stream bs)+ (stream cs)+ (stream ds))++izipWith5 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,+ Vector v f)+ => (Int -> a -> b -> c -> d -> e -> f) -> v a -> v b -> v c -> v d+ -> v e -> v f+{-# INLINE izipWith5 #-}+izipWith5 f as bs cs ds es+ = unstream (Stream.zipWith5 (uncurry f) (Stream.indexed (stream as))+ (stream bs)+ (stream cs)+ (stream ds)+ (stream es))++izipWith6 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,+ Vector v f, Vector v g)+ => (Int -> a -> b -> c -> d -> e -> f -> g)+ -> v a -> v b -> v c -> v d -> v e -> v f -> v g+{-# INLINE izipWith6 #-}+izipWith6 f as bs cs ds es fs+ = unstream (Stream.zipWith6 (uncurry f) (Stream.indexed (stream as))+ (stream bs)+ (stream cs)+ (stream ds)+ (stream es)+ (stream fs))++-- | /O(min(m,n))/ Zip two vectors+zip :: (Vector v a, Vector v b, Vector v (a,b)) => v a -> v b -> v (a, b)+{-# INLINE zip #-}+zip = zipWith (,)++zip3 :: (Vector v a, Vector v b, Vector v c, Vector v (a, b, c))+ => v a -> v b -> v c -> v (a, b, c)+{-# INLINE zip3 #-}+zip3 = zipWith3 (,,)++zip4 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v (a, b, c, d))+ => v a -> v b -> v c -> v d -> v (a, b, c, d)+{-# INLINE zip4 #-}+zip4 = zipWith4 (,,,)++zip5 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,+ Vector v (a, b, c, d, e))+ => v a -> v b -> v c -> v d -> v e -> v (a, b, c, d, e)+{-# INLINE zip5 #-}+zip5 = zipWith5 (,,,,)++zip6 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,+ Vector v f, Vector v (a, b, c, d, e, f))+ => v a -> v b -> v c -> v d -> v e -> v f -> v (a, b, c, d, e, f)+{-# INLINE zip6 #-}+zip6 = zipWith6 (,,,,,)++-- Monadic zipping+-- ---------------++-- | /O(min(m,n))/ 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)+-- FIXME: specialise for ST and IO?+{-# INLINE zipWithM #-}+zipWithM f as bs = unstreamM $ Stream.zipWithM f (stream as) (stream bs)++-- | /O(min(m,n))/ 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)++-- Unzipping+-- ---------++-- | /O(min(m,n))/ Unzip a vector of pairs.+unzip :: (Vector v a, Vector v b, Vector v (a,b)) => v (a, b) -> (v a, v b)+{-# INLINE unzip #-}+unzip xs = (map fst xs, map snd xs)++unzip3 :: (Vector v a, Vector v b, Vector v c, Vector v (a, b, c))+ => v (a, b, c) -> (v a, v b, v c)+{-# INLINE unzip3 #-}+unzip3 xs = (map (\(a, b, c) -> a) xs,+ map (\(a, b, c) -> b) xs,+ map (\(a, b, c) -> c) xs)++unzip4 :: (Vector v a, Vector v b, Vector v c, Vector v d,+ Vector v (a, b, c, d))+ => v (a, b, c, d) -> (v a, v b, v c, v d)+{-# INLINE unzip4 #-}+unzip4 xs = (map (\(a, b, c, d) -> a) xs,+ map (\(a, b, c, d) -> b) xs,+ map (\(a, b, c, d) -> c) xs,+ map (\(a, b, c, d) -> d) xs)++unzip5 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,+ Vector v (a, b, c, d, e))+ => v (a, b, c, d, e) -> (v a, v b, v c, v d, v e)+{-# INLINE unzip5 #-}+unzip5 xs = (map (\(a, b, c, d, e) -> a) xs,+ map (\(a, b, c, d, e) -> b) xs,+ map (\(a, b, c, d, e) -> c) xs,+ map (\(a, b, c, d, e) -> d) xs,+ map (\(a, b, c, d, e) -> e) xs)++unzip6 :: (Vector v a, Vector v b, Vector v c, Vector v d, Vector v e,+ Vector v f, Vector v (a, b, c, d, e, f))+ => v (a, b, c, d, e, f) -> (v a, v b, v c, v d, v e, v f)+{-# INLINE unzip6 #-}+unzip6 xs = (map (\(a, b, c, d, e, f) -> a) xs,+ map (\(a, b, c, d, e, f) -> b) xs,+ map (\(a, b, c, d, e, f) -> c) xs,+ map (\(a, b, c, d, e, f) -> d) xs,+ map (\(a, b, c, d, e, f) -> e) xs,+ map (\(a, b, c, d, e, f) -> f) xs)++-- Filtering+-- ---------++-- | /O(n)/ Drop elements that do not satisfy the predicate+filter :: Vector v a => (a -> Bool) -> v a -> v a+{-# INLINE filter #-}+filter f = unstream . inplace (MStream.filter f) . stream++-- | /O(n)/ Drop elements that do not satisfy the predicate which is applied to+-- values and their indices+ifilter :: Vector v a => (Int -> a -> Bool) -> v a -> v a+{-# INLINE ifilter #-}+ifilter f = unstream+ . inplace (MStream.map snd . MStream.filter (uncurry f)+ . MStream.indexed)+ . stream++-- | /O(n)/ 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++-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate+-- without copying.+takeWhile :: Vector v a => (a -> Bool) -> v a -> v a+{-# INLINE takeWhile #-}+takeWhile f = unstream . Stream.takeWhile f . stream++-- | /O(n)/ Drop the longest prefix of elements that satisfy the predicate+-- without copying.+dropWhile :: Vector v a => (a -> Bool) -> v a -> v a+{-# INLINE dropWhile #-}+dropWhile f = unstream . Stream.dropWhile f . stream++-- Parititioning+-- -------------++-- | /O(n)/ Split the vector in two parts, the first one containing those+-- elements that satisfy the predicate and the second one those that don't. The+-- relative order of the elements is preserved at the cost of a sometimes+-- reduced performance compared to 'unstablePartition'.+partition :: Vector v a => (a -> Bool) -> v a -> (v a, v a)+{-# INLINE partition #-}+partition f = partition_stream f . stream++-- FIXME: Make this inplace-fusible (look at how stable_partition is+-- implemented in C++)++partition_stream :: Vector v a => (a -> Bool) -> Stream a -> (v a, v a)+{-# INLINE_STREAM partition_stream #-}+partition_stream f s = s `seq` runST (+ do+ (mv1,mv2) <- M.partitionStream f s+ v1 <- unsafeFreeze mv1+ v2 <- unsafeFreeze mv2+ return (v1,v2))++-- | /O(n)/ Split the vector in two parts, the first one containing those+-- elements that satisfy the predicate and the second one those that don't.+-- The order of the elements is not preserved but the operation is often+-- faster than 'partition'.+unstablePartition :: Vector v a => (a -> Bool) -> v a -> (v a, v a)+{-# INLINE unstablePartition #-}+unstablePartition f = unstablePartition_stream f . stream++unstablePartition_stream+ :: Vector v a => (a -> Bool) -> Stream a -> (v a, v a)+{-# INLINE_STREAM unstablePartition_stream #-}+unstablePartition_stream f s = s `seq` runST (+ do+ (mv1,mv2) <- M.unstablePartitionStream f s+ v1 <- unsafeFreeze mv1+ v2 <- unsafeFreeze mv2+ return (v1,v2))++unstablePartition_new :: Vector v a => (a -> Bool) -> New v a -> (v a, v a)+{-# INLINE_STREAM unstablePartition_new #-}+unstablePartition_new f (New.New p) = runST (+ do+ mv <- p+ i <- M.unstablePartition f mv+ v <- unsafeFreeze mv+ return (unsafeTake i v, unsafeDrop i v))++{-# RULES++"unstablePartition" forall f p.+ unstablePartition_stream f (stream (new p))+ = unstablePartition_new f p++ #-}+++-- FIXME: make span and break fusible++-- | /O(n)/ Split the vector into the longest prefix of elements that satisfy+-- the predicate and the rest without copying.+span :: Vector v a => (a -> Bool) -> v a -> (v a, v a)+{-# INLINE span #-}+span f = break (not . f)++-- | /O(n)/ Split the vector into the longest prefix of elements that do not+-- satisfy the predicate and the rest without copying.+break :: Vector v a => (a -> Bool) -> v a -> (v a, v a)+{-# INLINE break #-}+break f xs = case findIndex f xs of+ Just i -> (unsafeSlice 0 i xs, unsafeSlice i (length xs - i) xs)+ Nothing -> (xs, empty)+ ++-- Searching+-- ---------++infix 4 `elem`+-- | /O(n)/ Check if the vector contains an element+elem :: (Vector v a, Eq a) => a -> v a -> Bool+{-# INLINE elem #-}+elem x = Stream.elem x . stream++infix 4 `notElem`+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem')+notElem :: (Vector v a, Eq a) => a -> v a -> Bool+{-# INLINE notElem #-}+notElem x = Stream.notElem x . stream++-- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing'+-- if no such element exists.+find :: Vector v a => (a -> Bool) -> v a -> Maybe a+{-# INLINE find #-}+find f = Stream.find f . stream++-- | /O(n)/ Yield 'Just' the index of the first element matching the predicate+-- or 'Nothing' if no such element exists.+findIndex :: Vector v a => (a -> Bool) -> v a -> Maybe Int+{-# INLINE findIndex #-}+findIndex f = Stream.findIndex f . stream++-- | /O(n)/ Yield the indices of elements satisfying the predicate in ascending+-- order.+findIndices :: (Vector v a, Vector v Int) => (a -> Bool) -> v a -> v Int+{-# INLINE findIndices #-}+findIndices f = unstream+ . inplace (MStream.map fst . MStream.filter (f . snd)+ . MStream.indexed)+ . stream++-- | /O(n)/ Yield 'Just' the index of the first occurence of the given element or+-- 'Nothing' if the vector does not contain the element. This is a specialised+-- version of 'findIndex'.+elemIndex :: (Vector v a, Eq a) => a -> v a -> Maybe Int+{-# INLINE elemIndex #-}+elemIndex x = findIndex (x==)++-- | /O(n)/ Yield the indices of all occurences of the given element in+-- ascending order. This is a specialised version of 'findIndices'.+elemIndices :: (Vector v a, Vector v Int, Eq a) => a -> v a -> v Int+{-# INLINE elemIndices #-}+elemIndices x = findIndices (x==)++-- Folding+-- -------++-- | /O(n)/ Left fold+foldl :: Vector v b => (a -> b -> a) -> a -> v b -> a+{-# INLINE foldl #-}+foldl f z = Stream.foldl f z . stream++-- | /O(n)/ Left fold on non-empty vectors+foldl1 :: Vector v a => (a -> a -> a) -> v a -> a+{-# INLINE foldl1 #-}+foldl1 f = Stream.foldl1 f . stream++-- | /O(n)/ Left fold with strict accumulator+foldl' :: Vector v b => (a -> b -> a) -> a -> v b -> a+{-# INLINE foldl' #-}+foldl' f z = Stream.foldl' f z . stream++-- | /O(n)/ Left fold on non-empty vectors with strict accumulator+foldl1' :: Vector v a => (a -> a -> a) -> v a -> a+{-# INLINE foldl1' #-}+foldl1' f = Stream.foldl1' f . stream++-- | /O(n)/ Right fold+foldr :: Vector v a => (a -> b -> b) -> b -> v a -> b+{-# INLINE foldr #-}+foldr f z = Stream.foldr f z . stream++-- | /O(n)/ Right fold on non-empty vectors+foldr1 :: Vector v a => (a -> a -> a) -> v a -> a+{-# INLINE foldr1 #-}+foldr1 f = Stream.foldr1 f . stream++-- | /O(n)/ Right fold with a strict accumulator+foldr' :: Vector v a => (a -> b -> b) -> b -> v a -> b+{-# INLINE foldr' #-}+foldr' f z = Stream.foldl' (flip f) z . streamR++-- | /O(n)/ Right fold on non-empty vectors with strict accumulator+foldr1' :: Vector v a => (a -> a -> a) -> v a -> a+{-# INLINE foldr1' #-}+foldr1' f = Stream.foldl1' (flip f) . streamR++-- | /O(n)/ Left fold (function applied to each element and its index)+ifoldl :: Vector v b => (a -> Int -> b -> a) -> a -> v b -> a+{-# INLINE ifoldl #-}+ifoldl f z = Stream.foldl (uncurry . f) z . Stream.indexed . stream++-- | /O(n)/ Left fold with strict accumulator (function applied to each element+-- and its index)+ifoldl' :: Vector v b => (a -> Int -> b -> a) -> a -> v b -> a+{-# INLINE ifoldl' #-}+ifoldl' f z = Stream.foldl' (uncurry . f) z . Stream.indexed . stream++-- | /O(n)/ Right fold (function applied to each element and its index)+ifoldr :: Vector v a => (Int -> a -> b -> b) -> b -> v a -> b+{-# INLINE ifoldr #-}+ifoldr f z = Stream.foldr (uncurry f) z . Stream.indexed . stream++-- | /O(n)/ Right fold with strict accumulator (function applied to each+-- element and its index)+ifoldr' :: Vector v a => (Int -> a -> b -> b) -> b -> v a -> b+{-# INLINE ifoldr' #-}+ifoldr' f z xs = Stream.foldl' (flip (uncurry f)) z+ $ Stream.indexedR (length xs) $ streamR xs++-- Specialised folds+-- -----------------++-- | /O(n)/ Check if all elements satisfy the predicate.+all :: Vector v a => (a -> Bool) -> v a -> Bool+{-# INLINE all #-}+all f = Stream.and . Stream.map f . stream++-- | /O(n)/ Check if any element satisfies the predicate.+any :: Vector v a => (a -> Bool) -> v a -> Bool+{-# INLINE any #-}+any f = Stream.or . Stream.map f . stream++-- | /O(n)/ Check if all elements are 'True'+and :: Vector v Bool => v Bool -> Bool+{-# INLINE and #-}+and = Stream.and . stream++-- | /O(n)/ Check if any element is 'True'+or :: Vector v Bool => v Bool -> Bool+{-# INLINE or #-}+or = Stream.or . stream++-- | /O(n)/ Compute the sum of the elements+sum :: (Vector v a, Num a) => v a -> a+{-# INLINE sum #-}+sum = Stream.foldl' (+) 0 . stream++-- | /O(n)/ Compute the produce of the elements+product :: (Vector v a, Num a) => v a -> a+{-# INLINE product #-}+product = Stream.foldl' (*) 1 . stream++-- | /O(n)/ Yield the maximum element of the vector. The vector may not be+-- empty.+maximum :: (Vector v a, Ord a) => v a -> a+{-# INLINE maximum #-}+maximum = Stream.foldl1' max . stream++-- | /O(n)/ Yield the maximum element of the vector according to the given+-- comparison function. The vector may not be empty.+maximumBy :: Vector v a => (a -> a -> Ordering) -> v a -> a+{-# INLINE maximumBy #-}+maximumBy cmp = Stream.foldl1' maxBy . stream+ where+ {-# INLINE maxBy #-}+ maxBy x y = case cmp x y of+ LT -> y+ _ -> x++-- | /O(n)/ Yield the minimum element of the vector. The vector may not be+-- empty.+minimum :: (Vector v a, Ord a) => v a -> a+{-# INLINE minimum #-}+minimum = Stream.foldl1' min . stream++-- | /O(n)/ Yield the minimum element of the vector according to the given+-- comparison function. The vector may not be empty.+minimumBy :: Vector v a => (a -> a -> Ordering) -> v a -> a+{-# INLINE minimumBy #-}+minimumBy cmp = Stream.foldl1' minBy . stream+ where+ {-# INLINE minBy #-}+ minBy x y = case cmp x y of+ GT -> y+ _ -> x++-- | /O(n)/ Yield the index of the maximum element of the vector. The vector+-- may not be empty.+maxIndex :: (Vector v a, Ord a) => v a -> Int+{-# INLINE maxIndex #-}+maxIndex = maxIndexBy compare++-- | /O(n)/ Yield the index of the maximum element of the vector according to+-- the given comparison function. The vector may not be empty.+maxIndexBy :: Vector v a => (a -> a -> Ordering) -> v a -> Int+{-# INLINE maxIndexBy #-}+maxIndexBy cmp = fst . Stream.foldl1' imax . Stream.indexed . stream+ where+ imax (i,x) (j,y) = i `seq` j `seq`+ case cmp x y of+ LT -> (j,y)+ _ -> (i,x)++-- | /O(n)/ Yield the index of the minimum element of the vector. The vector+-- may not be empty.+minIndex :: (Vector v a, Ord a) => v a -> Int+{-# INLINE minIndex #-}+minIndex = minIndexBy compare++-- | /O(n)/ Yield the index of the minimum element of the vector according to+-- the given comparison function. The vector may not be empty.+minIndexBy :: Vector v a => (a -> a -> Ordering) -> v a -> Int+{-# INLINE minIndexBy #-}+minIndexBy cmp = fst . Stream.foldl1' imin . Stream.indexed . stream+ where+ imin (i,x) (j,y) = i `seq` j `seq`+ case cmp x y of+ GT -> (j,y)+ _ -> (i,x)++-- Monadic folds+-- -------------++-- | /O(n)/ 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++-- | /O(n)/ 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++-- | /O(n)/ 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++-- | /O(n)/ 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++-- Prefix sums (scans)+-- -------------------++-- | /O(n)/ Prescan+--+-- @+-- prescanl f z = 'init' . 'scanl' f z+-- @+--+-- Example: @prescanl (+) 0 \<1,2,3,4\> = \<0,1,3,6\>@+--+prescanl :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a+{-# INLINE prescanl #-}+prescanl f z = unstream . inplace (MStream.prescanl f z) . stream++-- | /O(n)/ Prescan with strict accumulator+prescanl' :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a+{-# INLINE prescanl' #-}+prescanl' f z = unstream . inplace (MStream.prescanl' f z) . stream++-- | /O(n)/ Scan+--+-- @+-- postscanl f z = 'tail' . 'scanl' f z+-- @+--+-- Example: @postscanl (+) 0 \<1,2,3,4\> = \<1,3,6,10\>@+--+postscanl :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a+{-# INLINE postscanl #-}+postscanl f z = unstream . inplace (MStream.postscanl f z) . stream++-- | /O(n)/ Scan with strict accumulator+postscanl' :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a+{-# INLINE postscanl' #-}+postscanl' f z = unstream . inplace (MStream.postscanl' f z) . stream++-- | /O(n)/ Haskell-style scan+--+-- > scanl f z <x1,...,xn> = <y1,...,y(n+1)>+-- > where y1 = z+-- > yi = f y(i-1) x(i-1)+--+-- Example: @scanl (+) 0 \<1,2,3,4\> = \<0,1,3,6,10\>@+-- +scanl :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a+{-# INLINE scanl #-}+scanl f z = unstream . Stream.scanl f z . stream++-- | /O(n)/ Haskell-style scan with strict accumulator+scanl' :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a+{-# INLINE scanl' #-}+scanl' f z = unstream . Stream.scanl' f z . stream++-- | /O(n)/ Scan over a non-empty vector+--+-- > scanl f <x1,...,xn> = <y1,...,yn>+-- > where y1 = x1+-- > yi = f y(i-1) xi+--+scanl1 :: Vector v a => (a -> a -> a) -> v a -> v a+{-# INLINE scanl1 #-}+scanl1 f = unstream . inplace (MStream.scanl1 f) . stream++-- | /O(n)/ Scan over a non-empty vector with a strict accumulator+scanl1' :: Vector v a => (a -> a -> a) -> v a -> v a+{-# INLINE scanl1' #-}+scanl1' f = unstream . inplace (MStream.scanl1' f) . stream++-- | /O(n)/ Right-to-left prescan+--+-- @+-- prescanr f z = 'reverse' . 'prescanl' (flip f) z . 'reverse'+-- @+--+prescanr :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b+{-# INLINE prescanr #-}+prescanr f z = unstreamR . inplace (MStream.prescanl (flip f) z) . streamR++-- | /O(n)/ Right-to-left prescan with strict accumulator+prescanr' :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b+{-# INLINE prescanr' #-}+prescanr' f z = unstreamR . inplace (MStream.prescanl' (flip f) z) . streamR++-- | /O(n)/ Right-to-left scan+postscanr :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b+{-# INLINE postscanr #-}+postscanr f z = unstreamR . inplace (MStream.postscanl (flip f) z) . streamR++-- | /O(n)/ Right-to-left scan with strict accumulator+postscanr' :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b+{-# INLINE postscanr' #-}+postscanr' f z = unstreamR . inplace (MStream.postscanl' (flip f) z) . streamR++-- | /O(n)/ Right-to-left Haskell-style scan+scanr :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b+{-# INLINE scanr #-}+scanr f z = unstreamR . Stream.scanl (flip f) z . streamR++-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator+scanr' :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b+{-# INLINE scanr' #-}+scanr' f z = unstreamR . Stream.scanl' (flip f) z . streamR++-- | /O(n)/ Right-to-left scan over a non-empty vector+scanr1 :: Vector v a => (a -> a -> a) -> v a -> v a+{-# INLINE scanr1 #-}+scanr1 f = unstreamR . inplace (MStream.scanl1 (flip f)) . streamR++-- | /O(n)/ Right-to-left scan over a non-empty vector with a strict+-- accumulator+scanr1' :: Vector v a => (a -> a -> a) -> v a -> v a+{-# INLINE scanr1' #-}+scanr1' f = unstreamR . inplace (MStream.scanl1' (flip f)) . streamR++-- Conversions - Lists+-- ------------------------++-- | /O(n)/ Convert a vector to a list+toList :: Vector v a => v a -> [a]+{-# INLINE toList #-}+toList = Stream.toList . stream++-- | /O(n)/ Convert a list to a vector+fromList :: Vector v a => [a] -> v a+{-# INLINE fromList #-}+fromList = unstream . Stream.fromList++-- | /O(n)/ Convert the first @n@ elements of a list to a vector+--+-- @+-- fromListN n xs = 'fromList' ('take' n xs)+-- @+fromListN :: Vector v a => Int -> [a] -> v a+{-# INLINE fromListN #-}+fromListN n = unstream . Stream.fromListN n++-- Conversions - Mutable vectors+-- -----------------------------++-- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must+-- have the same length.+copy+ :: (PrimMonad m, Vector v a) => Mutable v (PrimState m) a -> v a -> m ()+{-# INLINE copy #-}+copy dst src = BOUNDS_CHECK(check) "copy" "length mismatch"+ (M.length dst == length src)+ $ unsafeCopy dst src++-- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must+-- have the same length. This is not checked.+unsafeCopy+ :: (PrimMonad m, Vector v a) => Mutable v (PrimState m) a -> v a -> m ()+{-# INLINE unsafeCopy #-}+unsafeCopy dst src = UNSAFE_CHECK(check) "unsafeCopy" "length mismatch"+ (M.length dst == length src)+ $ (dst `seq` src `seq` basicUnsafeCopy dst src)++-- Conversions to/from Streams+-- ---------------------------++-- | /O(1)/ Convert a vector to a 'Stream'+stream :: Vector v a => v a -> Stream a+{-# INLINE_STREAM stream #-}+stream v = v `seq` (Stream.unfoldr get 0 `Stream.sized` Exact n)+ where+ n = length v++ -- NOTE: the False case comes first in Core so making it the recursive one+ -- makes the code easier to read+ {-# INLINE get #-}+ get i | i >= n = Nothing+ | otherwise = case basicUnsafeIndexM v i of Box x -> Just (x, i+1)++-- | /O(n)/ Construct a vector from a 'Stream'+unstream :: Vector v a => Stream a -> v a+{-# INLINE unstream #-}+unstream s = new (New.unstream s)++{-# RULES++"stream/unstream [Vector]" forall s.+ stream (new (New.unstream s)) = s++"New.unstream/stream [Vector]" forall v.+ New.unstream (stream v) = clone v++"clone/new [Vector]" forall p.+ clone (new p) = p++"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++"uninplace [Vector]"+ forall (f :: forall m. Monad m => MStream m a -> MStream m a) m.+ stream (new (New.transform f m)) = inplace f (stream (new m))++ #-}++-- | /O(1)/ Convert a vector to a 'Stream', proceeding from right to left+streamR :: Vector v a => v a -> Stream a+{-# INLINE_STREAM streamR #-}+streamR v = v `seq` (Stream.unfoldr get n `Stream.sized` Exact n)+ where+ n = length v++ {-# INLINE get #-}+ get 0 = Nothing+ get i = let i' = i-1+ in+ case basicUnsafeIndexM v i' of Box x -> Just (x, i')++-- | /O(n)/ Construct a vector from a 'Stream', proceeding from right to left+unstreamR :: Vector v a => Stream a -> v a+{-# INLINE unstreamR #-}+unstreamR s = new (New.unstreamR s)++{-# RULES++"streamR/unstreamR [Vector]" forall s.+ streamR (new (New.unstreamR s)) = s++"New.unstreamR/streamR/new [Vector]" forall p.+ New.unstreamR (streamR (new p)) = p++"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 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))++ #-}++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++-- Recycling support+-- -----------------++-- | Construct a vector from a monadic initialiser.+new :: Vector v a => New v a -> v a+{-# INLINE_STREAM new #-}+new m = m `seq` runST (unsafeFreeze =<< New.run m)++-- | Convert a vector to an initialiser which, when run, produces a copy of+-- the vector.+clone :: Vector v a => v a -> New v a+{-# INLINE_STREAM clone #-}+clone v = v `seq` New.create (+ do+ mv <- M.new (length v)+ unsafeCopy mv v+ return mv)++-- Comparisons+-- -----------++-- | /O(n)/ Check if two vectors are equal. All 'Vector' instances are also+-- instances of 'Eq' and it is usually more appropriate to use those. This+-- function is primarily intended for implementing 'Eq' instances for new+-- vector types.+eq :: (Vector v a, Eq a) => v a -> v a -> Bool+{-# INLINE eq #-}+xs `eq` ys = stream xs == stream ys++-- | /O(n)/ Compare two vectors lexicographically. All 'Vector' instances are+-- also instances of 'Ord' and it is usually more appropriate to use those. This+-- function is primarily intended for implementing 'Ord' instances for new+-- vector types.+cmp :: (Vector v a, Ord a) => v a -> v a -> Ordering+{-# INLINE cmp #-}+cmp xs ys = compare (stream xs) (stream ys)++-- Data and Typeable+-- ----------------- -- | Generic definion of 'Data.Data.gfoldl' that views a 'Vector' as a -- list.
Data/Vector/Generic/Base.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE Rank2Types, MultiParamTypeClasses, FlexibleContexts, TypeFamilies, ScopedTypeVariables #-}+{-# OPTIONS_HADDOCK hide #-} -- | -- Module : Data.Vector.Generic.Base@@ -27,23 +28,49 @@ -- type family Mutable (v :: * -> *) :: * -> * -> * --- | Class of immutable vectors.+-- | Class of immutable vectors. Every immutable vector is associated with its+-- mutable version through the 'Mutable' type family. Methods of this class+-- should not be used directly. Instead, "Data.Vector.Generic" and other+-- Data.Vector modules provide safe and fusible wrappers. --+-- Minimum complete implementation:+--+-- * 'unsafeFreeze'+--+-- * 'basicLength'+--+-- * 'basicUnsafeSlice'+--+-- * 'basicUnsafeIndexM'+-- class MVector (Mutable v) a => Vector v a where- -- | Unsafely convert a mutable vector to its immutable version+ -- | /Assume complexity: O(1)/+ --+ -- Unsafely convert a mutable vector to its immutable version -- without copying. The mutable vector may not be used after -- this operation. unsafeFreeze :: PrimMonad m => Mutable v (PrimState m) a -> m (v a) - -- | Length of the vector (not fusible!)+ -- | /Assumed complexity: O(1)/+ --+ -- Yield the length of the vector. basicLength :: v a -> Int - -- | Yield a part of the vector without copying it. No range checks!- basicUnsafeSlice :: Int -> Int -> v a -> v a+ -- | /Assumed complexity: O(1)/+ --+ -- Yield a slice of the vector without copying it. No range checks are+ -- performed.+ basicUnsafeSlice :: Int -- ^ starting index+ -> Int -- ^ length+ -> v a -> v a - -- | Yield the element at the given position in a monad. The monad allows us- -- to be strict in the vector if we want. Suppose we had+ -- | /Assumed complexity: O(1)/ --+ -- Yield the element at the given position in a monad. No range checks are+ -- performed.+ --+ -- The monad allows us to be strict in the vector if we want. Suppose we had+ -- -- > unsafeIndex :: v a -> Int -> a -- -- instead. Now, if we wanted to copy a vector, we'd do something like@@ -64,7 +91,16 @@ -- basicUnsafeIndexM :: Monad m => v a -> Int -> m a - -- | Copy an immutable vector into a mutable one.+ -- | /Assumed complexity: O(n)/+ --+ -- Copy an immutable vector into a mutable one. The two vectors must have+ -- the same length but this is not checked.+ --+ -- Instances of 'Vector' should redefine this method if they wish to support+ -- an efficient block copy operation.+ --+ -- Default definition: copying basic on 'basicUnsafeIndexM' and+ -- 'basicUnsafeWrite'. basicUnsafeCopy :: PrimMonad m => Mutable v (PrimState m) a -> v a -> m () {-# INLINE basicUnsafeCopy #-}@@ -78,6 +114,16 @@ do_copy (i+1) | otherwise = return () + -- | Evaluate @a@ as far as storing it in a vector would and yield @b@.+ -- The @v a@ argument only fixes the type and is not touched. The method is+ -- only used for optimisation purposes. Thus, it is safe for instances of+ -- 'Vector' to evaluate @a@ less than it would be when stored in a vector+ -- although this might result in suboptimal code.+ --+ -- > elemseq v x y = (singleton x `asTypeOf` v) `seq` y+ --+ -- Default defintion: @a@ is not evaluated at all+ -- elemseq :: v a -> a -> b -> b {-# INLINE elemseq #-}
Data/Vector/Primitive.hs view
@@ -9,61 +9,110 @@ -- Stability : experimental -- Portability : non-portable -- --- Unboxed vectors of primitive types.+-- Unboxed vectors of primitive types. The use of this module is not+-- recommended except in very special cases. Adaptive unboxed vectors defined+-- in "Data.Vector.Unboxed" are significantly more flexible at no performance+-- cost. -- module Data.Vector.Primitive (+ -- * Primitive vectors Vector, MVector(..), Prim, - -- * Length information- length, null,+ -- * Accessors - -- * Construction- empty, singleton, cons, snoc, replicate, generate, (++), force,+ -- ** Length information+ length, null, - -- * Accessing individual elements- (!), head, last, indexM, headM, lastM,+ -- ** Indexing+ (!), head, last, unsafeIndex, unsafeHead, unsafeLast,++ -- ** Monadic indexing+ indexM, headM, lastM, unsafeIndexM, unsafeHeadM, unsafeLastM, - -- * Subvectors+ -- ** Extracting subvectors (slicing) slice, init, tail, take, drop, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, - -- * Permutations- accum, accumulate_, (//), update_, backpermute, reverse,- unsafeAccum, unsafeAccumulate_,+ -- * Construction++ -- ** Initialisation+ empty, singleton, replicate, generate,++ -- ** Monadic initialisation+ replicateM, create,++ -- ** Unfolding+ unfoldr, unfoldrN,++ -- ** Enumeration+ enumFromN, enumFromStepN, enumFromTo, enumFromThenTo,++ -- ** Concatenation+ cons, snoc, (++),++ -- ** Restricting memory usage+ force,++ -- * Modifying vectors++ -- ** Bulk updates+ (//), update_, unsafeUpd, unsafeUpdate_,- unsafeBackpermute, - -- * Mapping+ -- ** Accumulations+ accum, accumulate_,+ unsafeAccum, unsafeAccumulate_,++ -- ** Permutations + reverse, backpermute, unsafeBackpermute,++ -- ** Safe destructive updates+ modify,++ -- * Elementwise operations++ -- ** Mapping map, imap, concatMap, - -- * Zipping and unzipping+ -- ** Monadic mapping+ mapM, mapM_, forM, forM_,++ -- ** Zipping zipWith, zipWith3, zipWith4, zipWith5, zipWith6, izipWith, izipWith3, izipWith4, izipWith5, izipWith6, - -- * Filtering- filter, ifilter, takeWhile, dropWhile,+ -- ** Monadic zipping+ zipWithM, zipWithM_,++ -- * Working with predicates++ -- ** Filtering+ filter, ifilter, filterM,+ takeWhile, dropWhile,++ -- ** Partitioning partition, unstablePartition, span, break, - -- * Searching+ -- ** Searching elem, notElem, find, findIndex, findIndices, elemIndex, elemIndices, -- * Folding foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1', ifoldl, ifoldl', ifoldr, ifoldr', - -- * Specialised folds+ -- ** Specialised folds all, any, sum, product, maximum, maximumBy, minimum, minimumBy, minIndex, minIndexBy, maxIndex, maxIndexBy, - -- * Unfolding- unfoldr, unfoldrN,+ -- ** Monadic folds+ foldM, foldM', fold1M, fold1M', - -- * Scans+ -- * Prefix sums (scans) prescanl, prescanl', postscanl, postscanl', scanl, scanl', scanl1, scanl1',@@ -71,18 +120,13 @@ postscanr, postscanr', scanr, scanr', scanr1, scanr1', - -- * Enumeration- enumFromN, enumFromStepN, enumFromTo, enumFromThenTo,+ -- * Conversions - -- * Conversion to/from lists+ -- ** Lists toList, fromList, fromListN, - -- * Monadic operations- replicateM, mapM, mapM_, forM, forM_, zipWithM, zipWithM_, filterM,- foldM, foldM', fold1M, fold1M',-- -- * Destructive operations- create, modify, copy, unsafeCopy+ -- ** Mutable vectors+ copy, unsafeCopy ) where import qualified Data.Vector.Generic as G@@ -184,248 +228,475 @@ -- Length -- ------ +-- | /O(1)/ Yield the length of the vector. length :: Prim a => Vector a -> Int {-# INLINE length #-} length = G.length +-- | /O(1)/ Test whether a vector if empty null :: Prim a => Vector a -> Bool {-# INLINE null #-} null = G.null --- Construction--- ---------------- | Empty vector-empty :: Prim a => Vector a-{-# INLINE empty #-}-empty = G.empty---- | Vector with exaclty one element-singleton :: Prim a => a -> Vector a-{-# INLINE singleton #-}-singleton = G.singleton---- | Vector of the given length with the given value in each position-replicate :: Prim a => Int -> a -> Vector a-{-# INLINE replicate #-}-replicate = G.replicate---- | Generate a vector of the given length by applying the function to each--- index-generate :: Prim a => Int -> (Int -> a) -> Vector a-{-# INLINE generate #-}-generate = G.generate---- | Prepend an element-cons :: Prim a => a -> Vector a -> Vector a-{-# INLINE cons #-}-cons = G.cons---- | Append an element-snoc :: Prim a => Vector a -> a -> Vector a-{-# INLINE snoc #-}-snoc = G.snoc--infixr 5 ++--- | Concatenate two vectors-(++) :: Prim a => Vector a -> Vector a -> Vector a-{-# INLINE (++) #-}-(++) = (G.++)---- | Create a copy of a vector. Useful when dealing with slices.-force :: Prim a => Vector a -> Vector a-{-# INLINE force #-}-force = G.force---- Accessing individual elements--- -----------------------------+-- Indexing+-- -------- --- | Indexing+-- | O(1) Indexing (!) :: Prim a => Vector a -> Int -> a {-# INLINE (!) #-} (!) = (G.!) --- | First element+-- | /O(1)/ First element head :: Prim a => Vector a -> a {-# INLINE head #-} head = G.head --- | Last element+-- | /O(1)/ Last element last :: Prim a => Vector a -> a {-# INLINE last #-} last = G.last --- | Unsafe indexing without bounds checking+-- | /O(1)/ Unsafe indexing without bounds checking unsafeIndex :: Prim a => Vector a -> Int -> a {-# INLINE unsafeIndex #-} unsafeIndex = G.unsafeIndex --- | Yield the first element of a vector without checking if the vector is--- empty+-- | /O(1)/ First element without checking if the vector is empty unsafeHead :: Prim a => Vector a -> a {-# INLINE unsafeHead #-} unsafeHead = G.unsafeHead --- | Yield the last element of a vector without checking if the vector is--- empty+-- | /O(1)/ Last element without checking if the vector is empty unsafeLast :: Prim a => Vector a -> a {-# INLINE unsafeLast #-} unsafeLast = G.unsafeLast --- | Monadic indexing which can be strict in the vector while remaining lazy in--- the element+-- Monadic indexing+-- ----------------++-- | /O(1)/ Indexing in a monad.+--+-- The monad allows operations to be strict in the vector when necessary.+-- Suppose vector copying is implemented like this:+--+-- > copy mv v = ... write mv i (v ! i) ...+--+-- For lazy vectors, @v ! i@ would not be evaluated which means that @mv@+-- would unnecessarily retain a reference to @v@ in each element written.+--+-- With 'indexM', copying can be implemented like this instead:+--+-- > copy mv v = ... do+-- > x <- indexM v i+-- > write mv i x+--+-- Here, no references to @v@ are retained because indexing (but /not/ the+-- elements) is evaluated eagerly.+-- indexM :: (Prim a, Monad m) => Vector a -> Int -> m a {-# INLINE indexM #-} indexM = G.indexM +-- | /O(1)/ First element of a vector in a monad. See 'indexM' for an+-- explanation of why this is useful. headM :: (Prim a, Monad m) => Vector a -> m a {-# INLINE headM #-} headM = G.headM +-- | /O(1)/ Last element of a vector in a monad. See 'indexM' for an+-- explanation of why this is useful. lastM :: (Prim a, Monad m) => Vector a -> m a {-# INLINE lastM #-} lastM = G.lastM --- | Unsafe monadic indexing without bounds checks+-- | /O(1)/ Indexing in a monad without bounds checks. See 'indexM' for an+-- explanation of why this is useful. unsafeIndexM :: (Prim a, Monad m) => Vector a -> Int -> m a {-# INLINE unsafeIndexM #-} unsafeIndexM = G.unsafeIndexM +-- | /O(1)/ First element in a monad without checking for empty vectors.+-- See 'indexM' for an explanation of why this is useful. unsafeHeadM :: (Prim a, Monad m) => Vector a -> m a {-# INLINE unsafeHeadM #-} unsafeHeadM = G.unsafeHeadM +-- | /O(1)/ Last element in a monad without checking for empty vectors.+-- See 'indexM' for an explanation of why this is useful. unsafeLastM :: (Prim a, Monad m) => Vector a -> m a {-# INLINE unsafeLastM #-} unsafeLastM = G.unsafeLastM --- Subarrays--- ---------+-- Extracting subvectors (slicing)+-- ------------------------------- --- | Yield a part of the vector without copying it. Safer version of--- 'basicUnsafeSlice'.-slice :: Prim a => Int -- ^ starting index- -> Int -- ^ length- -> Vector a- -> Vector a+-- | /O(1)/ Yield a slice of the vector without copying it. The vector must+-- contain at least @i+n@ elements.+slice :: Prim a+ => Int -- ^ @i@ starting index+ -> Int -- ^ @n@ length+ -> Vector a+ -> Vector a {-# INLINE slice #-} slice = G.slice --- | Yield all but the last element without copying.+-- | /O(1)/ Yield all but the last element without copying. The vector may not+-- be empty. init :: Prim a => Vector a -> Vector a {-# INLINE init #-} init = G.init --- | All but the first element (without copying).+-- | /O(1)/ Yield all but the first element without copying. The vector may not+-- be empty. tail :: Prim a => Vector a -> Vector a {-# INLINE tail #-} tail = G.tail --- | Yield the first @n@ elements without copying.+-- | /O(1)/ Yield at the first @n@ elements without copying. The vector may+-- contain less than @n@ elements in which case it is returned unchanged. take :: Prim a => Int -> Vector a -> Vector a {-# INLINE take #-} take = G.take --- | Yield all but the first @n@ elements without copying.+-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may+-- contain less than @n@ elements in which case an empty vector is returned. drop :: Prim a => Int -> Vector a -> Vector a {-# INLINE drop #-} drop = G.drop --- | Unsafely yield a part of the vector without copying it and without--- performing bounds checks.-unsafeSlice :: Prim a => Int -- ^ starting index- -> Int -- ^ length- -> Vector a- -> Vector a+-- | /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+ -> Int -- ^ @n@ length+ -> Vector a+ -> Vector a {-# INLINE unsafeSlice #-} unsafeSlice = G.unsafeSlice +-- | /O(1)/ Yield all but the last element without copying. The vector may not+-- be empty but this is not checked. unsafeInit :: Prim a => Vector a -> Vector a {-# INLINE unsafeInit #-} unsafeInit = G.unsafeInit +-- | /O(1)/ Yield all but the first element without copying. The vector may not+-- be empty but this is not checked. unsafeTail :: Prim a => Vector a -> Vector a {-# INLINE unsafeTail #-} unsafeTail = G.unsafeTail +-- | /O(1)/ Yield the first @n@ elements without copying. The vector must+-- contain at least @n@ elements but this is not checked. unsafeTake :: Prim a => Int -> Vector a -> Vector a {-# INLINE unsafeTake #-} unsafeTake = G.unsafeTake +-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector+-- must contain at least @n@ elements but this is not checked. unsafeDrop :: Prim a => Int -> Vector a -> Vector a {-# INLINE unsafeDrop #-} unsafeDrop = G.unsafeDrop --- Permutations--- ------------+-- Initialisation+-- -------------- -unsafeAccum :: Prim a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a-{-# INLINE unsafeAccum #-}-unsafeAccum = G.unsafeAccum+-- | /O(1)/ Empty vector+empty :: Prim a => Vector a+{-# INLINE empty #-}+empty = G.empty -unsafeAccumulate_ :: (Prim a, Prim b) =>- (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a-{-# INLINE unsafeAccumulate_ #-}-unsafeAccumulate_ = G.unsafeAccumulate_+-- | /O(1)/ Vector with exactly one element+singleton :: Prim a => a -> Vector a+{-# INLINE singleton #-}+singleton = G.singleton -accum :: Prim a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a-{-# INLINE accum #-}-accum = G.accum+-- | /O(n)/ Vector of the given length with the same value in each position+replicate :: Prim a => Int -> a -> Vector a+{-# INLINE replicate #-}+replicate = G.replicate -accumulate_ :: (Prim a, Prim b) =>- (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a-{-# INLINE accumulate_ #-}-accumulate_ = G.accumulate_+-- | /O(n)/ Construct a vector of the given length by applying the function to+-- each index+generate :: Prim a => Int -> (Int -> a) -> Vector a+{-# INLINE generate #-}+generate = G.generate +-- Unfolding+-- ---------++-- | /O(n)/ Construct a vector by repeatedly applying the generator function+-- to a seed. The generator function yields 'Just' the next element and the+-- new seed or 'Nothing' if there are no more elements.+--+-- > unfoldr (\n -> if n == 0 then Nothing else Just (n,n-1)) 10+-- > = <10,9,8,7,6,5,4,3,2,1>+unfoldr :: Prim a => (b -> Maybe (a, b)) -> b -> Vector a+{-# INLINE unfoldr #-}+unfoldr = G.unfoldr++-- | /O(n)/ Construct a vector with at most @n@ by repeatedly applying the+-- generator function to the a seed. The generator function yields 'Just' the+-- next element and the new seed or 'Nothing' if there are no more elements.+--+-- > unfoldrN 3 (\n -> Just (n,n-1)) 10 = <10,9,8>+unfoldrN :: Prim a => Int -> (b -> Maybe (a, b)) -> b -> Vector a+{-# INLINE unfoldrN #-}+unfoldrN = G.unfoldrN++-- Enumeration+-- -----------++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+1@+-- etc. This operation is usually more efficient than 'enumFromTo'.+--+-- > enumFromN 5 3 = <5,6,7>+enumFromN :: (Prim a, Num a) => a -> Int -> Vector a+{-# INLINE enumFromN #-}+enumFromN = G.enumFromN++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,+-- @x+y+y@ etc. This operations is usually more efficient than 'enumFromThenTo'.+--+-- > enumFromStepN 1 0.1 5 = <1,1.1,1.2,1.3,1.4>+enumFromStepN :: (Prim a, Num a) => a -> a -> Int -> Vector a+{-# INLINE enumFromStepN #-}+enumFromStepN = G.enumFromStepN++-- | /O(n)/ Enumerate values from @x@ to @y@.+--+-- /WARNING:/ This operation can be very inefficient. If at all possible, use+-- 'enumFromN' instead.+enumFromTo :: (Prim a, Enum a) => a -> a -> Vector a+{-# INLINE enumFromTo #-}+enumFromTo = G.enumFromTo++-- | /O(n)/ Enumerate values from @x@ to @y@ with a specific step @z@.+--+-- /WARNING:/ This operation can be very inefficient. If at all possible, use+-- 'enumFromStepN' instead.+enumFromThenTo :: (Prim a, Enum a) => a -> a -> a -> Vector a+{-# INLINE enumFromThenTo #-}+enumFromThenTo = G.enumFromThenTo++-- Concatenation+-- -------------++-- | /O(n)/ Prepend an element+cons :: Prim a => a -> Vector a -> Vector a+{-# INLINE cons #-}+cons = G.cons++-- | /O(n)/ Append an element+snoc :: Prim a => Vector a -> a -> Vector a+{-# INLINE snoc #-}+snoc = G.snoc++infixr 5 +++-- | /O(m+n)/ Concatenate two vectors+(++) :: Prim a => Vector a -> Vector a -> Vector a+{-# INLINE (++) #-}+(++) = (G.++)++-- Monadic initialisation+-- ----------------------++-- | /O(n)/ Execute the monadic action the given number of times and store the+-- results in a vector.+replicateM :: (Monad m, Prim a) => Int -> m a -> m (Vector a)+{-# INLINE replicateM #-}+replicateM = G.replicateM++-- | Execute the monadic action and freeze the resulting vector.+--+-- @+-- create (do { v \<- new 2; write v 0 \'a\'; write v 1 \'b\' }) = \<'a','b'\>+-- @+create :: Prim a => (forall s. ST s (MVector s a)) -> Vector a+{-# INLINE create #-}+create = G.create++-- Restricting memory usage+-- ------------------------++-- | /O(n)/ Yield the argument but force it not to retain any extra memory,+-- possibly by copying it.+--+-- This is especially useful when dealing with slices. For example:+--+-- > force (slice 0 2 <huge vector>)+--+-- Here, the slice retains a reference to the huge vector. Forcing it creates+-- a copy of just the elements that belong to the slice and allows the huge+-- vector to be garbage collected.+force :: Prim a => Vector a -> Vector a+{-# INLINE force #-}+force = G.force++-- Bulk updates+-- ------------++-- | /O(m+n)/ For each pair @(i,a)@ from the list, replace the vector+-- element at position @i@ by @a@.+--+-- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7>+--+(//) :: Prim a => Vector a -- ^ initial vector (of length @m@)+ -> [(Int, a)] -- ^ list of index/value pairs (of length @n@) + -> Vector a+{-# INLINE (//) #-}+(//) = (G.//)++-- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the+-- corresponding value @a@ from the value vector, replace the element of the+-- initial vector at position @i@ by @a@.+--+-- > update_ <5,9,2,7> <2,0,2> <1,3,8> = <3,9,8,7>+--+update_ :: Prim a+ => Vector a -- ^ initial vector (of length @m@)+ -> Vector Int -- ^ index vector (of length @n1@)+ -> Vector a -- ^ value vector (of length @n2@)+ -> Vector a+{-# INLINE update_ #-}+update_ = G.update_++-- | Same as ('//') but without bounds checking. unsafeUpd :: Prim a => Vector a -> [(Int, a)] -> Vector a {-# INLINE unsafeUpd #-} unsafeUpd = G.unsafeUpd +-- | Same as 'update_' but without bounds checking. unsafeUpdate_ :: Prim a => Vector a -> Vector Int -> Vector a -> Vector a {-# INLINE unsafeUpdate_ #-} unsafeUpdate_ = G.unsafeUpdate_ -(//) :: Prim a => Vector a -> [(Int, a)] -> Vector a-{-# INLINE (//) #-}-(//) = (G.//)+-- Accumulations+-- ------------- -update_ :: Prim a => Vector a -> Vector Int -> Vector a -> Vector a-{-# INLINE update_ #-}-update_ = G.update_+-- | /O(m+n)/ For each pair @(i,b)@ from the list, replace the vector element+-- @a@ at position @i@ by @f a b@.+--+-- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4>+accum :: Prim a+ => (a -> b -> a) -- ^ accumulating function @f@+ -> Vector a -- ^ initial vector (of length @m@)+ -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)+ -> Vector a+{-# INLINE accum #-}+accum = G.accum +-- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the+-- corresponding value @b@ from the the value vector,+-- replace the element of the initial vector at+-- position @i@ by @f a b@.+--+-- > accumulate_ (+) <5,9,2> <2,1,0,1> <4,6,3,7> = <5+3, 9+6+7, 2+4>+--+accumulate_ :: (Prim a, Prim b)+ => (a -> b -> a) -- ^ accumulating function @f@+ -> Vector a -- ^ initial vector (of length @m@)+ -> Vector Int -- ^ index vector (of length @n1@)+ -> Vector b -- ^ value vector (of length @n2@)+ -> Vector a+{-# INLINE accumulate_ #-}+accumulate_ = G.accumulate_++-- | Same as 'accum' but without bounds checking.+unsafeAccum :: Prim a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a+{-# INLINE unsafeAccum #-}+unsafeAccum = G.unsafeAccum++-- | Same as 'accumulate_' but without bounds checking.+unsafeAccumulate_ :: (Prim a, Prim b) =>+ (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a+{-# INLINE unsafeAccumulate_ #-}+unsafeAccumulate_ = G.unsafeAccumulate_++-- Permutations+-- ------------++-- | /O(n)/ Reverse a vector+reverse :: Prim a => Vector a -> Vector a+{-# INLINE reverse #-}+reverse = G.reverse++-- | /O(n)/ Yield the vector obtained by replacing each element @i@ of the+-- index vector by @xs'!'i@. This is equivalent to @'map' (xs'!') is@ but is+-- often much more efficient.+--+-- > backpermute <a,b,c,d> <0,3,2,3,1,0> = <a,d,c,d,b,a> backpermute :: Prim a => Vector a -> Vector Int -> Vector a {-# INLINE backpermute #-} backpermute = G.backpermute +-- | Same as 'backpermute' but without bounds checking. unsafeBackpermute :: Prim a => Vector a -> Vector Int -> Vector a {-# INLINE unsafeBackpermute #-} unsafeBackpermute = G.unsafeBackpermute -reverse :: Prim a => Vector a -> Vector a-{-# INLINE reverse #-}-reverse = G.reverse+-- Safe destructive updates+-- ------------------------ +-- | Apply a destructive operation to a vector. The operation will be+-- performed in place if it is safe to do so and will modify a copy of the+-- vector otherwise.+--+-- @+-- modify (\\v -> write v 0 \'x\') ('replicate' 3 \'a\') = \<\'x\',\'a\',\'a\'\>+-- @+modify :: Prim a => (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a+{-# INLINE modify #-}+modify = G.modify+ -- Mapping -- ------- --- | Map a function over a vector+-- | /O(n)/ Map a function over a vector map :: (Prim a, Prim b) => (a -> b) -> Vector a -> Vector b {-# INLINE map #-} map = G.map --- | Apply a function to every index/value pair+-- | /O(n)/ Apply a function to every element of a vector and its index imap :: (Prim a, Prim b) => (Int -> a -> b) -> Vector a -> Vector b {-# INLINE imap #-} imap = G.imap +-- | Map a function over a vector and concatenate the results. concatMap :: (Prim a, Prim b) => (a -> Vector b) -> Vector a -> Vector b {-# INLINE concatMap #-} concatMap = G.concatMap --- Zipping/unzipping--- -----------------+-- Monadic mapping+-- --------------- --- | Zip two vectors with the given function.+-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a+-- vector of results+mapM :: (Monad m, Prim a, Prim b) => (a -> m b) -> Vector a -> m (Vector b)+{-# INLINE mapM #-}+mapM = G.mapM++-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the+-- results+mapM_ :: (Monad m, Prim a) => (a -> m b) -> Vector a -> m ()+{-# INLINE mapM_ #-}+mapM_ = G.mapM_++-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a+-- vector of results. Equvalent to @flip 'mapM'@.+forM :: (Monad m, Prim a, Prim b) => Vector a -> (a -> m b) -> m (Vector b)+{-# INLINE forM #-}+forM = G.forM++-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the+-- results. Equivalent to @flip 'mapM_'@.+forM_ :: (Monad m, Prim a) => Vector a -> (a -> m b) -> m ()+{-# INLINE forM_ #-}+forM_ = G.forM_++-- Zipping+-- -------++-- | /O(min(m,n))/ Zip two vectors with the given function. zipWith :: (Prim a, Prim b, Prim c) => (a -> b -> c) -> Vector a -> Vector b -> Vector c {-# INLINE zipWith #-}@@ -443,21 +714,24 @@ {-# INLINE zipWith4 #-} zipWith4 = G.zipWith4 -zipWith5 :: (Prim a, Prim b, Prim c, Prim d, Prim e, Prim f)+zipWith5 :: (Prim a, Prim b, Prim c, Prim d, Prim e,+ Prim f) => (a -> b -> c -> d -> e -> f) -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e -> Vector f {-# INLINE zipWith5 #-} zipWith5 = G.zipWith5 -zipWith6 :: (Prim a, Prim b, Prim c, Prim d, Prim e, Prim f, Prim g)+zipWith6 :: (Prim a, Prim b, Prim c, Prim d, Prim e,+ Prim f, Prim g) => (a -> b -> c -> d -> e -> f -> g) -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e -> Vector f -> Vector g {-# INLINE zipWith6 #-} zipWith6 = G.zipWith6 --- | Zip two vectors and their indices with the given function.+-- | /O(min(m,n))/ Zip two vectors with a function that also takes the+-- elements' indices. izipWith :: (Prim a, Prim b, Prim c) => (Int -> a -> b -> c) -> Vector a -> Vector b -> Vector c {-# INLINE izipWith #-}@@ -476,67 +750,97 @@ {-# INLINE izipWith4 #-} izipWith4 = G.izipWith4 -izipWith5 :: (Prim a, Prim b, Prim c, Prim d, Prim e, Prim f)+izipWith5 :: (Prim a, Prim b, Prim c, Prim d, Prim e,+ Prim f) => (Int -> a -> b -> c -> d -> e -> f) -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e -> Vector f {-# INLINE izipWith5 #-} izipWith5 = G.izipWith5 -izipWith6 :: (Prim a, Prim b, Prim c, Prim d, Prim e, Prim f, Prim g)+izipWith6 :: (Prim a, Prim b, Prim c, Prim d, Prim e,+ Prim f, Prim g) => (Int -> a -> b -> c -> d -> e -> f -> g) -> Vector a -> Vector b -> Vector c -> Vector d -> Vector e -> Vector f -> Vector g {-# INLINE izipWith6 #-} izipWith6 = G.izipWith6 +-- Monadic zipping+-- ---------------++-- | /O(min(m,n))/ Zip the two vectors with the monadic action and yield a+-- vector of results+zipWithM :: (Monad m, Prim a, Prim b, Prim c)+ => (a -> b -> m c) -> Vector a -> Vector b -> m (Vector c)+{-# INLINE zipWithM #-}+zipWithM = G.zipWithM++-- | /O(min(m,n))/ Zip the two vectors with the monadic action and ignore the+-- results+zipWithM_ :: (Monad m, Prim a, Prim b)+ => (a -> b -> m c) -> Vector a -> Vector b -> m ()+{-# INLINE zipWithM_ #-}+zipWithM_ = G.zipWithM_+ -- Filtering -- --------- --- | Drop elements which do not satisfy the predicate+-- | /O(n)/ Drop elements that do not satisfy the predicate filter :: Prim a => (a -> Bool) -> Vector a -> Vector a {-# INLINE filter #-} filter = G.filter --- | Drop elements that do not satisfy the predicate (applied to values and--- their indices)+-- | /O(n)/ Drop elements that do not satisfy the predicate which is applied to+-- values and their indices ifilter :: Prim a => (Int -> a -> Bool) -> Vector a -> Vector a {-# INLINE ifilter #-} ifilter = G.ifilter --- | Yield the longest prefix of elements satisfying the predicate.+-- | /O(n)/ Drop elements that do not satisfy the monadic predicate+filterM :: (Monad m, Prim a) => (a -> m Bool) -> Vector a -> m (Vector a)+{-# INLINE filterM #-}+filterM = G.filterM++-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate+-- without copying. takeWhile :: Prim a => (a -> Bool) -> Vector a -> Vector a {-# INLINE takeWhile #-} takeWhile = G.takeWhile --- | Drop the longest prefix of elements that satisfy the predicate.+-- | /O(n)/ Drop the longest prefix of elements that satisfy the predicate+-- without copying. dropWhile :: Prim a => (a -> Bool) -> Vector a -> Vector a {-# INLINE dropWhile #-} dropWhile = G.dropWhile --- | Split the vector in two parts, the first one containing those elements--- that satisfy the predicate and the second one those that don't. The--- relative order of the elements is preserved at the cost of a (sometimes)+-- Parititioning+-- -------------++-- | /O(n)/ Split the vector in two parts, the first one containing those+-- elements that satisfy the predicate and the second one those that don't. The+-- relative order of the elements is preserved at the cost of a sometimes -- reduced performance compared to 'unstablePartition'. partition :: Prim a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE partition #-} partition = G.partition --- | Split the vector in two parts, the first one containing those elements--- that satisfy the predicate and the second one those that don't. The order--- of the elements is not preserved.+-- | /O(n)/ Split the vector in two parts, the first one containing those+-- elements that satisfy the predicate and the second one those that don't.+-- The order of the elements is not preserved but the operation is often+-- faster than 'partition'. unstablePartition :: Prim a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE unstablePartition #-} unstablePartition = G.unstablePartition --- | Split the vector into the longest prefix of elements that satisfy the--- predicate and the rest.+-- | /O(n)/ Split the vector into the longest prefix of elements that satisfy+-- the predicate and the rest without copying. span :: Prim a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE span #-} span = G.span --- | Split the vector into the longest prefix of elements that do not satisfy--- the predicate and the rest.+-- | /O(n)/ Split the vector into the longest prefix of elements that do not+-- satisfy the predicate and the rest without copying. break :: Prim a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE break #-} break = G.break@@ -545,41 +849,44 @@ -- --------- infix 4 `elem`--- | Check whether the vector contains an element+-- | /O(n)/ Check if the vector contains an element elem :: (Prim a, Eq a) => a -> Vector a -> Bool {-# INLINE elem #-} elem = G.elem infix 4 `notElem`--- | Inverse of `elem`+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem') notElem :: (Prim a, Eq a) => a -> Vector a -> Bool {-# INLINE notElem #-} notElem = G.notElem --- | Yield 'Just' the first element matching the predicate or 'Nothing' if no--- such element exists.+-- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing'+-- if no such element exists. find :: Prim a => (a -> Bool) -> Vector a -> Maybe a {-# INLINE find #-} find = G.find --- | Yield 'Just' the index of the first element matching the predicate or--- 'Nothing' if no such element exists.+-- | /O(n)/ Yield 'Just' the index of the first element matching the predicate+-- or 'Nothing' if no such element exists. findIndex :: Prim a => (a -> Bool) -> Vector a -> Maybe Int {-# INLINE findIndex #-} findIndex = G.findIndex --- | Yield the indices of elements satisfying the predicate+-- | /O(n)/ Yield the indices of elements satisfying the predicate in ascending+-- order. findIndices :: Prim a => (a -> Bool) -> Vector a -> Vector Int {-# INLINE findIndices #-} findIndices = G.findIndices --- | Yield 'Just' the index of the first occurence of the given element or--- 'Nothing' if the vector does not contain the element+-- | /O(n)/ Yield 'Just' the index of the first occurence of the given element or+-- 'Nothing' if the vector does not contain the element. This is a specialised+-- version of 'findIndex'. elemIndex :: (Prim a, Eq a) => a -> Vector a -> Maybe Int {-# INLINE elemIndex #-} elemIndex = G.elemIndex --- | Yield the indices of all occurences of the given element+-- | /O(n)/ Yield the indices of all occurences of the given element in+-- ascending order. This is a specialised version of 'findIndices'. elemIndices :: (Prim a, Eq a) => a -> Vector a -> Vector Int {-# INLINE elemIndices #-} elemIndices = G.elemIndices@@ -587,64 +894,64 @@ -- Folding -- ------- --- | Left fold+-- | /O(n)/ Left fold foldl :: Prim b => (a -> b -> a) -> a -> Vector b -> a {-# INLINE foldl #-} foldl = G.foldl --- | Lefgt fold on non-empty vectors+-- | /O(n)/ Left fold on non-empty vectors foldl1 :: Prim a => (a -> a -> a) -> Vector a -> a {-# INLINE foldl1 #-} foldl1 = G.foldl1 --- | Left fold with strict accumulator+-- | /O(n)/ Left fold with strict accumulator foldl' :: Prim b => (a -> b -> a) -> a -> Vector b -> a {-# INLINE foldl' #-} foldl' = G.foldl' --- | Left fold on non-empty vectors with strict accumulator+-- | /O(n)/ Left fold on non-empty vectors with strict accumulator foldl1' :: Prim a => (a -> a -> a) -> Vector a -> a {-# INLINE foldl1' #-} foldl1' = G.foldl1' --- | Right fold+-- | /O(n)/ Right fold foldr :: Prim a => (a -> b -> b) -> b -> Vector a -> b {-# INLINE foldr #-} foldr = G.foldr --- | Right fold on non-empty vectors+-- | /O(n)/ Right fold on non-empty vectors foldr1 :: Prim a => (a -> a -> a) -> Vector a -> a {-# INLINE foldr1 #-} foldr1 = G.foldr1 --- | Right fold with a strict accumulator+-- | /O(n)/ Right fold with a strict accumulator foldr' :: Prim a => (a -> b -> b) -> b -> Vector a -> b {-# INLINE foldr' #-} foldr' = G.foldr' --- | Right fold on non-empty vectors with strict accumulator+-- | /O(n)/ Right fold on non-empty vectors with strict accumulator foldr1' :: Prim a => (a -> a -> a) -> Vector a -> a {-# INLINE foldr1' #-} foldr1' = G.foldr1' --- | Left fold (function applied to each element and its index)+-- | /O(n)/ Left fold (function applied to each element and its index) ifoldl :: Prim b => (a -> Int -> b -> a) -> a -> Vector b -> a {-# INLINE ifoldl #-} ifoldl = G.ifoldl --- | Left fold with strict accumulator (function applied to each element and--- its index)+-- | /O(n)/ Left fold with strict accumulator (function applied to each element+-- and its index) ifoldl' :: Prim b => (a -> Int -> b -> a) -> a -> Vector b -> a {-# INLINE ifoldl' #-} ifoldl' = G.ifoldl' --- | Right fold (function applied to each element and its index)+-- | /O(n)/ Right fold (function applied to each element and its index) ifoldr :: Prim a => (Int -> a -> b -> b) -> b -> Vector a -> b {-# INLINE ifoldr #-} ifoldr = G.ifoldr --- | Right fold with strict accumulator (function applied to each element and--- its index)+-- | /O(n)/ Right fold with strict accumulator (function applied to each+-- element and its index) ifoldr' :: Prim a => (Int -> a -> b -> b) -> b -> Vector a -> b {-# INLINE ifoldr' #-} ifoldr' = G.ifoldr'@@ -652,308 +959,248 @@ -- Specialised folds -- ----------------- +-- | /O(n)/ Check if all elements satisfy the predicate. all :: Prim a => (a -> Bool) -> Vector a -> Bool {-# INLINE all #-} all = G.all +-- | /O(n)/ Check if any element satisfies the predicate. any :: Prim a => (a -> Bool) -> Vector a -> Bool {-# INLINE any #-} any = G.any +-- | /O(n)/ Compute the sum of the elements sum :: (Prim a, Num a) => Vector a -> a {-# INLINE sum #-} sum = G.sum +-- | /O(n)/ Compute the produce of the elements product :: (Prim a, Num a) => Vector a -> a {-# INLINE product #-} product = G.product +-- | /O(n)/ Yield the maximum element of the vector. The vector may not be+-- empty. maximum :: (Prim a, Ord a) => Vector a -> a {-# INLINE maximum #-} maximum = G.maximum +-- | /O(n)/ Yield the maximum element of the vector according to the given+-- comparison function. The vector may not be empty. maximumBy :: Prim a => (a -> a -> Ordering) -> Vector a -> a {-# INLINE maximumBy #-} maximumBy = G.maximumBy +-- | /O(n)/ Yield the minimum element of the vector. The vector may not be+-- empty. minimum :: (Prim a, Ord a) => Vector a -> a {-# INLINE minimum #-} minimum = G.minimum +-- | /O(n)/ Yield the minimum element of the vector according to the given+-- comparison function. The vector may not be empty. minimumBy :: Prim a => (a -> a -> Ordering) -> Vector a -> a {-# INLINE minimumBy #-} minimumBy = G.minimumBy +-- | /O(n)/ Yield the index of the maximum element of the vector. The vector+-- may not be empty. maxIndex :: (Prim a, Ord a) => Vector a -> Int {-# INLINE maxIndex #-} maxIndex = G.maxIndex +-- | /O(n)/ Yield the index of the maximum element of the vector according to+-- the given comparison function. The vector may not be empty. maxIndexBy :: Prim a => (a -> a -> Ordering) -> Vector a -> Int {-# INLINE maxIndexBy #-} maxIndexBy = G.maxIndexBy +-- | /O(n)/ Yield the index of the minimum element of the vector. The vector+-- may not be empty. minIndex :: (Prim a, Ord a) => Vector a -> Int {-# INLINE minIndex #-} minIndex = G.minIndex +-- | /O(n)/ Yield the index of the minimum element of the vector according to+-- the given comparison function. The vector may not be empty. minIndexBy :: Prim a => (a -> a -> Ordering) -> Vector a -> Int {-# INLINE minIndexBy #-} minIndexBy = G.minIndexBy --- Unfolding--- ---------+-- Monadic folds+-- ------------- --- | The 'unfoldr' function is a \`dual\' to 'foldr': while 'foldr'--- reduces a vector to a summary value, 'unfoldr' builds a list from--- a seed value. The function takes the element and returns 'Nothing'--- if it is done generating the vector or returns 'Just' @(a,b)@, in which--- case, @a@ is a prepended to the vector and @b@ is used as the next--- element in a recursive call.------ A simple use of unfoldr:------ > unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10--- > [10,9,8,7,6,5,4,3,2,1]----unfoldr :: Prim a => (b -> Maybe (a, b)) -> b -> Vector a-{-# INLINE unfoldr #-}-unfoldr = G.unfoldr+-- | /O(n)/ Monadic fold+foldM :: (Monad m, Prim b) => (a -> b -> m a) -> a -> Vector b -> m a+{-# INLINE foldM #-}+foldM = G.foldM --- | Unfold at most @n@ elements-unfoldrN :: Prim a => Int -> (b -> Maybe (a, b)) -> b -> Vector a-{-# INLINE unfoldrN #-}-unfoldrN = G.unfoldrN+-- | /O(n)/ Monadic fold over non-empty vectors+fold1M :: (Monad m, Prim a) => (a -> a -> m a) -> Vector a -> m a+{-# INLINE fold1M #-}+fold1M = G.fold1M --- Scans--- -----+-- | /O(n)/ Monadic fold with strict accumulator+foldM' :: (Monad m, Prim b) => (a -> b -> m a) -> a -> Vector b -> m a+{-# INLINE foldM' #-}+foldM' = G.foldM' --- | Prefix scan+-- | /O(n)/ Monad fold over non-empty vectors with strict accumulator+fold1M' :: (Monad m, Prim a) => (a -> a -> m a) -> Vector a -> m a+{-# INLINE fold1M' #-}+fold1M' = G.fold1M'++-- Prefix sums (scans)+-- -------------------++-- | /O(n)/ Prescan+--+-- @+-- prescanl f z = 'init' . 'scanl' f z+-- @+--+-- Example: @prescanl (+) 0 \<1,2,3,4\> = \<0,1,3,6\>@+-- prescanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE prescanl #-} prescanl = G.prescanl --- | Prefix scan with strict accumulator+-- | /O(n)/ Prescan with strict accumulator prescanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE prescanl' #-} prescanl' = G.prescanl' --- | Suffix scan+-- | /O(n)/ Scan+--+-- @+-- postscanl f z = 'tail' . 'scanl' f z+-- @+--+-- Example: @postscanl (+) 0 \<1,2,3,4\> = \<1,3,6,10\>@+-- postscanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE postscanl #-} postscanl = G.postscanl --- | Suffix scan with strict accumulator+-- | /O(n)/ Scan with strict accumulator postscanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE postscanl' #-} postscanl' = G.postscanl' --- | Haskell-style scan+-- | /O(n)/ Haskell-style scan+--+-- > scanl f z <x1,...,xn> = <y1,...,y(n+1)>+-- > where y1 = z+-- > yi = f y(i-1) x(i-1)+--+-- Example: @scanl (+) 0 \<1,2,3,4\> = \<0,1,3,6,10\>@+-- scanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE scanl #-} scanl = G.scanl --- | Haskell-style scan with strict accumulator+-- | /O(n)/ Haskell-style scan with strict accumulator scanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE scanl' #-} scanl' = G.scanl' --- | Scan over a non-empty 'Vector'+-- | /O(n)/ Scan over a non-empty vector+--+-- > scanl f <x1,...,xn> = <y1,...,yn>+-- > where y1 = x1+-- > yi = f y(i-1) xi+-- scanl1 :: Prim a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanl1 #-} scanl1 = G.scanl1 --- | Scan over a non-empty 'Vector' with a strict accumulator+-- | /O(n)/ Scan over a non-empty vector with a strict accumulator scanl1' :: Prim a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanl1' #-} scanl1' = G.scanl1' ---- | Prefix right-to-left scan+-- | /O(n)/ Right-to-left prescan+--+-- @+-- prescanr f z = 'reverse' . 'prescanl' (flip f) z . 'reverse'+-- @+-- prescanr :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE prescanr #-} prescanr = G.prescanr --- | Prefix right-to-left scan with strict accumulator+-- | /O(n)/ Right-to-left prescan with strict accumulator prescanr' :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE prescanr' #-} prescanr' = G.prescanr' --- | Suffix right-to-left scan+-- | /O(n)/ Right-to-left scan postscanr :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE postscanr #-} postscanr = G.postscanr --- | Suffix right-to-left scan with strict accumulator+-- | /O(n)/ Right-to-left scan with strict accumulator postscanr' :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE postscanr' #-} postscanr' = G.postscanr' --- | Haskell-style right-to-left scan+-- | /O(n)/ Right-to-left Haskell-style scan scanr :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE scanr #-} scanr = G.scanr --- | Haskell-style right-to-left scan with strict accumulator+-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator scanr' :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE scanr' #-} scanr' = G.scanr' --- | Right-to-left scan over a non-empty vector+-- | /O(n)/ Right-to-left scan over a non-empty vector scanr1 :: Prim a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanr1 #-} scanr1 = G.scanr1 --- | Right-to-left scan over a non-empty vector with a strict accumulator+-- | /O(n)/ Right-to-left scan over a non-empty vector with a strict+-- accumulator scanr1' :: Prim a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanr1' #-} scanr1' = G.scanr1' --- Enumeration--- --------------- | Yield a vector of the given length containing the values @x@, @x+1@ etc.--- This operation is usually more efficient than 'enumFromTo'.-enumFromN :: (Prim a, Num a) => a -> Int -> Vector a-{-# INLINE enumFromN #-}-enumFromN = G.enumFromN---- | Yield a vector of the given length containing the values @x@, @x+y@,--- @x+y+y@ etc. This operations is usually more efficient than--- 'enumFromThenTo'.-enumFromStepN :: (Prim a, Num a) => a -> a -> Int -> Vector a-{-# INLINE enumFromStepN #-}-enumFromStepN = G.enumFromStepN---- | Enumerate values from @x@ to @y@.------ /WARNING:/ This operation can be very inefficient. If at all possible, use--- 'enumFromN' instead.-enumFromTo :: (Prim a, Enum a) => a -> a -> Vector a-{-# INLINE enumFromTo #-}-enumFromTo = G.enumFromTo---- | Enumerate values from @x@ to @y@ with a specific step @z@.------ /WARNING:/ This operation can be very inefficient. If at all possible, use--- 'enumFromStepN' instead.-enumFromThenTo :: (Prim a, Enum a) => a -> a -> a -> Vector a-{-# INLINE enumFromThenTo #-}-enumFromThenTo = G.enumFromThenTo---- Conversion to/from lists+-- Conversions - Lists -- ------------------------ --- | Convert a vector to a list+-- | /O(n)/ Convert a vector to a list toList :: Prim a => Vector a -> [a] {-# INLINE toList #-} toList = G.toList --- | Convert a list to a vector+-- | /O(n)/ Convert a list to a vector fromList :: Prim a => [a] -> Vector a {-# INLINE fromList #-} fromList = G.fromList --- | Convert the first @n@ elements of a list to a vector+-- | /O(n)/ Convert the first @n@ elements of a list to a vector ----- > fromListN n xs = fromList (take n xs)+-- @+-- fromListN n xs = 'fromList' ('take' n xs)+-- @ fromListN :: Prim a => Int -> [a] -> Vector a {-# INLINE fromListN #-} fromListN = G.fromListN --- Monadic operations--- ---------------------- | Perform the monadic action the given number of times and store the--- results in a vector.-replicateM :: (Monad m, Prim a) => Int -> m a -> m (Vector a)-{-# INLINE replicateM #-}-replicateM = G.replicateM---- | Apply the monadic action to all elements of the vector, yielding a vector--- of results-mapM :: (Monad m, Prim a, Prim b) => (a -> m b) -> Vector a -> m (Vector b)-{-# INLINE mapM #-}-mapM = G.mapM---- | Apply the monadic action to all elements of a vector and ignore the--- results-mapM_ :: (Monad m, Prim a) => (a -> m b) -> Vector a -> m ()-{-# INLINE mapM_ #-}-mapM_ = G.mapM_---- | Apply the monadic action to all elements of the vector, yielding a vector--- of results-forM :: (Monad m, Prim a, Prim b) => Vector a -> (a -> m b) -> m (Vector b)-{-# INLINE forM #-}-forM = G.forM---- | Apply the monadic action to all elements of a vector and ignore the--- results-forM_ :: (Monad m, Prim a) => Vector a -> (a -> m b) -> m ()-{-# INLINE forM_ #-}-forM_ = G.forM_---- | Zip the two vectors with the monadic action and yield a vector of results-zipWithM :: (Monad m, Prim a, Prim b, Prim c)- => (a -> b -> m c) -> Vector a -> Vector b -> m (Vector c)-{-# INLINE zipWithM #-}-zipWithM = G.zipWithM---- | Zip the two vectors with the monadic action and ignore the results-zipWithM_ :: (Monad m, Prim a, Prim b)- => (a -> b -> m c) -> Vector a -> Vector b -> m ()-{-# INLINE zipWithM_ #-}-zipWithM_ = G.zipWithM_---- | Drop elements that do not satisfy the monadic predicate-filterM :: (Monad m, Prim a) => (a -> m Bool) -> Vector a -> m (Vector a)-{-# INLINE filterM #-}-filterM = G.filterM---- | Monadic fold-foldM :: (Monad m, Prim b) => (a -> b -> m a) -> a -> Vector b -> m a-{-# INLINE foldM #-}-foldM = G.foldM---- | Monadic fold over non-empty vectors-fold1M :: (Monad m, Prim a) => (a -> a -> m a) -> Vector a -> m a-{-# INLINE fold1M #-}-fold1M = G.fold1M---- | Monadic fold with strict accumulator-foldM' :: (Monad m, Prim b) => (a -> b -> m a) -> a -> Vector b -> m a-{-# INLINE foldM' #-}-foldM' = G.foldM'---- | Monad fold over non-empty vectors with strict accumulator-fold1M' :: (Monad m, Prim a) => (a -> a -> m a) -> Vector a -> m a-{-# INLINE fold1M' #-}-fold1M' = G.fold1M'---- Destructive operations--- -------------------------- | Destructively initialise a vector.-create :: Prim a => (forall s. ST s (MVector s a)) -> Vector a-{-# INLINE create #-}-create = G.create---- | Apply a destructive operation to a vector. The operation is applied to a--- copy of the vector unless it can be safely performed in place.-modify :: Prim a => (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a-{-# INLINE modify #-}-modify = G.modify+-- Conversions - Mutable vectors+-- ----------------------------- --- | Copy an immutable vector into a mutable one. The two vectors must have--- the same length. This is not checked.+-- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must+-- have the same length. unsafeCopy :: (Prim a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE unsafeCopy #-} unsafeCopy = G.unsafeCopy --- | Copy an immutable vector into a mutable one. The two vectors must have the--- same length.+-- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must+-- have the same length. This is not checked. copy :: (Prim a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE copy #-} copy = G.copy+
Data/Vector/Storable.hs view
@@ -13,57 +13,103 @@ -- module Data.Vector.Storable (+ -- * Storable vectors Vector, MVector(..), Storable, - -- * Length information- length, null,+ -- * Accessors - -- * Construction- empty, singleton, cons, snoc, replicate, generate, (++), force,+ -- ** Length information+ length, null, - -- * Accessing individual elements- (!), head, last, indexM, headM, lastM,+ -- ** Indexing+ (!), head, last, unsafeIndex, unsafeHead, unsafeLast,++ -- ** Monadic indexing+ indexM, headM, lastM, unsafeIndexM, unsafeHeadM, unsafeLastM, - -- * Subvectors+ -- ** Extracting subvectors (slicing) slice, init, tail, take, drop, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, - -- * Permutations- accum, accumulate_, (//), update_, backpermute, reverse,- unsafeAccum, unsafeAccumulate_,+ -- * Construction++ -- ** Initialisation+ empty, singleton, replicate, generate,++ -- ** Monadic initialisation+ replicateM, create,++ -- ** Unfolding+ unfoldr, unfoldrN,++ -- ** Enumeration+ enumFromN, enumFromStepN, enumFromTo, enumFromThenTo,++ -- ** Concatenation+ cons, snoc, (++),++ -- ** Restricting memory usage+ force,++ -- * Modifying vectors++ -- ** Bulk updates+ (//), update_, unsafeUpd, unsafeUpdate_,- unsafeBackpermute, - -- * Mapping+ -- ** Accumulations+ accum, accumulate_,+ unsafeAccum, unsafeAccumulate_,++ -- ** Permutations + reverse, backpermute, unsafeBackpermute,++ -- ** Safe destructive updates+ modify,++ -- * Elementwise operations++ -- ** Mapping map, imap, concatMap, - -- * Zipping and unzipping+ -- ** Monadic mapping+ mapM, mapM_, forM, forM_,++ -- ** Zipping zipWith, zipWith3, zipWith4, zipWith5, zipWith6, izipWith, izipWith3, izipWith4, izipWith5, izipWith6, - -- * Filtering- filter, ifilter, takeWhile, dropWhile,+ -- ** Monadic zipping+ zipWithM, zipWithM_,++ -- * Working with predicates++ -- ** Filtering+ filter, ifilter, filterM,+ takeWhile, dropWhile,++ -- ** Partitioning partition, unstablePartition, span, break, - -- * Searching+ -- ** Searching elem, notElem, find, findIndex, findIndices, elemIndex, elemIndices, -- * Folding foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1', ifoldl, ifoldl', ifoldr, ifoldr', - -- * Specialised folds+ -- ** Specialised folds all, any, and, or, sum, product, maximum, maximumBy, minimum, minimumBy, minIndex, minIndexBy, maxIndex, maxIndexBy, - -- * Unfolding- unfoldr, unfoldrN,+ -- ** Monadic folds+ foldM, foldM', fold1M, fold1M', - -- * Scans+ -- * Prefix sums (scans) prescanl, prescanl', postscanl, postscanl', scanl, scanl', scanl1, scanl1',@@ -71,20 +117,15 @@ postscanr, postscanr', scanr, scanr', scanr1, scanr1', - -- * Enumeration- enumFromN, enumFromStepN, enumFromTo, enumFromThenTo,+ -- * Conversions - -- * Conversion to/from lists+ -- ** Lists toList, fromList, fromListN, - -- * Monadic operations- replicateM, mapM, mapM_, forM, forM_, zipWithM, zipWithM_, filterM,- foldM, foldM', fold1M, fold1M',-- -- * Destructive operations- create, modify, copy, unsafeCopy,+ -- ** Mutable vectors+ copy, unsafeCopy, - -- * Accessing the underlying memory+ -- * Raw pointers unsafeFromForeignPtr, unsafeToForeignPtr, unsafeWith ) where @@ -219,248 +260,475 @@ -- Length -- ------ +-- | /O(1)/ Yield the length of the vector. length :: Storable a => Vector a -> Int {-# INLINE length #-} length = G.length +-- | /O(1)/ Test whether a vector if empty null :: Storable a => Vector a -> Bool {-# INLINE null #-} null = G.null --- Construction--- ---------------- | Empty vector-empty :: Storable a => Vector a-{-# INLINE empty #-}-empty = G.empty---- | Vector with exaclty one element-singleton :: Storable a => a -> Vector a-{-# INLINE singleton #-}-singleton = G.singleton---- | Vector of the given length with the given value in each position-replicate :: Storable a => Int -> a -> Vector a-{-# INLINE replicate #-}-replicate = G.replicate---- | Generate a vector of the given length by applying the function to each--- index-generate :: Storable a => Int -> (Int -> a) -> Vector a-{-# INLINE generate #-}-generate = G.generate---- | Prepend an element-cons :: Storable a => a -> Vector a -> Vector a-{-# INLINE cons #-}-cons = G.cons---- | Append an element-snoc :: Storable a => Vector a -> a -> Vector a-{-# INLINE snoc #-}-snoc = G.snoc--infixr 5 ++--- | Concatenate two vectors-(++) :: Storable a => Vector a -> Vector a -> Vector a-{-# INLINE (++) #-}-(++) = (G.++)---- | Create a copy of a vector. Useful when dealing with slices.-force :: Storable a => Vector a -> Vector a-{-# INLINE force #-}-force = G.force---- Accessing individual elements--- -----------------------------+-- Indexing+-- -------- --- | Indexing+-- | O(1) Indexing (!) :: Storable a => Vector a -> Int -> a {-# INLINE (!) #-} (!) = (G.!) --- | First element+-- | /O(1)/ First element head :: Storable a => Vector a -> a {-# INLINE head #-} head = G.head --- | Last element+-- | /O(1)/ Last element last :: Storable a => Vector a -> a {-# INLINE last #-} last = G.last --- | Unsafe indexing without bounds checking+-- | /O(1)/ Unsafe indexing without bounds checking unsafeIndex :: Storable a => Vector a -> Int -> a {-# INLINE unsafeIndex #-} unsafeIndex = G.unsafeIndex --- | Yield the first element of a vector without checking if the vector is--- empty+-- | /O(1)/ First element without checking if the vector is empty unsafeHead :: Storable a => Vector a -> a {-# INLINE unsafeHead #-} unsafeHead = G.unsafeHead --- | Yield the last element of a vector without checking if the vector is--- empty+-- | /O(1)/ Last element without checking if the vector is empty unsafeLast :: Storable a => Vector a -> a {-# INLINE unsafeLast #-} unsafeLast = G.unsafeLast --- | Monadic indexing which can be strict in the vector while remaining lazy in--- the element+-- Monadic indexing+-- ----------------++-- | /O(1)/ Indexing in a monad.+--+-- The monad allows operations to be strict in the vector when necessary.+-- Suppose vector copying is implemented like this:+--+-- > copy mv v = ... write mv i (v ! i) ...+--+-- For lazy vectors, @v ! i@ would not be evaluated which means that @mv@+-- would unnecessarily retain a reference to @v@ in each element written.+--+-- With 'indexM', copying can be implemented like this instead:+--+-- > copy mv v = ... do+-- > x <- indexM v i+-- > write mv i x+--+-- Here, no references to @v@ are retained because indexing (but /not/ the+-- elements) is evaluated eagerly.+-- indexM :: (Storable a, Monad m) => Vector a -> Int -> m a {-# INLINE indexM #-} indexM = G.indexM +-- | /O(1)/ First element of a vector in a monad. See 'indexM' for an+-- explanation of why this is useful. headM :: (Storable a, Monad m) => Vector a -> m a {-# INLINE headM #-} headM = G.headM +-- | /O(1)/ Last element of a vector in a monad. See 'indexM' for an+-- explanation of why this is useful. lastM :: (Storable a, Monad m) => Vector a -> m a {-# INLINE lastM #-} lastM = G.lastM --- | Unsafe monadic indexing without bounds checks+-- | /O(1)/ Indexing in a monad without bounds checks. See 'indexM' for an+-- explanation of why this is useful. unsafeIndexM :: (Storable a, Monad m) => Vector a -> Int -> m a {-# INLINE unsafeIndexM #-} unsafeIndexM = G.unsafeIndexM +-- | /O(1)/ First element in a monad without checking for empty vectors.+-- See 'indexM' for an explanation of why this is useful. unsafeHeadM :: (Storable a, Monad m) => Vector a -> m a {-# INLINE unsafeHeadM #-} unsafeHeadM = G.unsafeHeadM +-- | /O(1)/ Last element in a monad without checking for empty vectors.+-- See 'indexM' for an explanation of why this is useful. unsafeLastM :: (Storable a, Monad m) => Vector a -> m a {-# INLINE unsafeLastM #-} unsafeLastM = G.unsafeLastM --- Subarrays--- ---------+-- Extracting subvectors (slicing)+-- ------------------------------- --- | Yield a part of the vector without copying it. Safer version of--- 'basicUnsafeSlice'.-slice :: Storable a => Int -- ^ starting index- -> Int -- ^ length- -> Vector a- -> Vector a+-- | /O(1)/ Yield a slice of the vector without copying it. The vector must+-- contain at least @i+n@ elements.+slice :: Storable a+ => Int -- ^ @i@ starting index+ -> Int -- ^ @n@ length+ -> Vector a+ -> Vector a {-# INLINE slice #-} slice = G.slice --- | Yield all but the last element without copying.+-- | /O(1)/ Yield all but the last element without copying. The vector may not+-- be empty. init :: Storable a => Vector a -> Vector a {-# INLINE init #-} init = G.init --- | All but the first element (without copying).+-- | /O(1)/ Yield all but the first element without copying. The vector may not+-- be empty. tail :: Storable a => Vector a -> Vector a {-# INLINE tail #-} tail = G.tail --- | Yield the first @n@ elements without copying.+-- | /O(1)/ Yield at the first @n@ elements without copying. The vector may+-- contain less than @n@ elements in which case it is returned unchanged. take :: Storable a => Int -> Vector a -> Vector a {-# INLINE take #-} take = G.take --- | Yield all but the first @n@ elements without copying.+-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may+-- contain less than @n@ elements in which case an empty vector is returned. drop :: Storable a => Int -> Vector a -> Vector a {-# INLINE drop #-} drop = G.drop --- | Unsafely yield a part of the vector without copying it and without--- performing bounds checks.-unsafeSlice :: Storable a => Int -- ^ starting index- -> Int -- ^ length- -> Vector a- -> Vector a+-- | /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+ -> Int -- ^ @n@ length+ -> Vector a+ -> Vector a {-# INLINE unsafeSlice #-} unsafeSlice = G.unsafeSlice +-- | /O(1)/ Yield all but the last element without copying. The vector may not+-- be empty but this is not checked. unsafeInit :: Storable a => Vector a -> Vector a {-# INLINE unsafeInit #-} unsafeInit = G.unsafeInit +-- | /O(1)/ Yield all but the first element without copying. The vector may not+-- be empty but this is not checked. unsafeTail :: Storable a => Vector a -> Vector a {-# INLINE unsafeTail #-} unsafeTail = G.unsafeTail +-- | /O(1)/ Yield the first @n@ elements without copying. The vector must+-- contain at least @n@ elements but this is not checked. unsafeTake :: Storable a => Int -> Vector a -> Vector a {-# INLINE unsafeTake #-} unsafeTake = G.unsafeTake +-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector+-- must contain at least @n@ elements but this is not checked. unsafeDrop :: Storable a => Int -> Vector a -> Vector a {-# INLINE unsafeDrop #-} unsafeDrop = G.unsafeDrop --- Permutations--- ------------+-- Initialisation+-- -------------- -unsafeAccum :: Storable a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a-{-# INLINE unsafeAccum #-}-unsafeAccum = G.unsafeAccum+-- | /O(1)/ Empty vector+empty :: Storable a => Vector a+{-# INLINE empty #-}+empty = G.empty -unsafeAccumulate_ :: (Storable a, Storable b) =>- (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a-{-# INLINE unsafeAccumulate_ #-}-unsafeAccumulate_ = G.unsafeAccumulate_+-- | /O(1)/ Vector with exactly one element+singleton :: Storable a => a -> Vector a+{-# INLINE singleton #-}+singleton = G.singleton -accum :: Storable a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a-{-# INLINE accum #-}-accum = G.accum+-- | /O(n)/ Vector of the given length with the same value in each position+replicate :: Storable a => Int -> a -> Vector a+{-# INLINE replicate #-}+replicate = G.replicate -accumulate_ :: (Storable a, Storable b) =>- (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a-{-# INLINE accumulate_ #-}-accumulate_ = G.accumulate_+-- | /O(n)/ Construct a vector of the given length by applying the function to+-- each index+generate :: Storable a => Int -> (Int -> a) -> Vector a+{-# INLINE generate #-}+generate = G.generate +-- Unfolding+-- ---------++-- | /O(n)/ Construct a vector by repeatedly applying the generator function+-- to a seed. The generator function yields 'Just' the next element and the+-- new seed or 'Nothing' if there are no more elements.+--+-- > unfoldr (\n -> if n == 0 then Nothing else Just (n,n-1)) 10+-- > = <10,9,8,7,6,5,4,3,2,1>+unfoldr :: Storable a => (b -> Maybe (a, b)) -> b -> Vector a+{-# INLINE unfoldr #-}+unfoldr = G.unfoldr++-- | /O(n)/ Construct a vector with at most @n@ by repeatedly applying the+-- generator function to the a seed. The generator function yields 'Just' the+-- next element and the new seed or 'Nothing' if there are no more elements.+--+-- > unfoldrN 3 (\n -> Just (n,n-1)) 10 = <10,9,8>+unfoldrN :: Storable a => Int -> (b -> Maybe (a, b)) -> b -> Vector a+{-# INLINE unfoldrN #-}+unfoldrN = G.unfoldrN++-- Enumeration+-- -----------++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+1@+-- etc. This operation is usually more efficient than 'enumFromTo'.+--+-- > enumFromN 5 3 = <5,6,7>+enumFromN :: (Storable a, Num a) => a -> Int -> Vector a+{-# INLINE enumFromN #-}+enumFromN = G.enumFromN++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,+-- @x+y+y@ etc. This operations is usually more efficient than 'enumFromThenTo'.+--+-- > enumFromStepN 1 0.1 5 = <1,1.1,1.2,1.3,1.4>+enumFromStepN :: (Storable a, Num a) => a -> a -> Int -> Vector a+{-# INLINE enumFromStepN #-}+enumFromStepN = G.enumFromStepN++-- | /O(n)/ Enumerate values from @x@ to @y@.+--+-- /WARNING:/ This operation can be very inefficient. If at all possible, use+-- 'enumFromN' instead.+enumFromTo :: (Storable a, Enum a) => a -> a -> Vector a+{-# INLINE enumFromTo #-}+enumFromTo = G.enumFromTo++-- | /O(n)/ Enumerate values from @x@ to @y@ with a specific step @z@.+--+-- /WARNING:/ This operation can be very inefficient. If at all possible, use+-- 'enumFromStepN' instead.+enumFromThenTo :: (Storable a, Enum a) => a -> a -> a -> Vector a+{-# INLINE enumFromThenTo #-}+enumFromThenTo = G.enumFromThenTo++-- Concatenation+-- -------------++-- | /O(n)/ Prepend an element+cons :: Storable a => a -> Vector a -> Vector a+{-# INLINE cons #-}+cons = G.cons++-- | /O(n)/ Append an element+snoc :: Storable a => Vector a -> a -> Vector a+{-# INLINE snoc #-}+snoc = G.snoc++infixr 5 +++-- | /O(m+n)/ Concatenate two vectors+(++) :: Storable a => Vector a -> Vector a -> Vector a+{-# INLINE (++) #-}+(++) = (G.++)++-- Monadic initialisation+-- ----------------------++-- | /O(n)/ Execute the monadic action the given number of times and store the+-- results in a vector.+replicateM :: (Monad m, Storable a) => Int -> m a -> m (Vector a)+{-# INLINE replicateM #-}+replicateM = G.replicateM++-- | Execute the monadic action and freeze the resulting vector.+--+-- @+-- create (do { v \<- new 2; write v 0 \'a\'; write v 1 \'b\' }) = \<'a','b'\>+-- @+create :: Storable a => (forall s. ST s (MVector s a)) -> Vector a+{-# INLINE create #-}+create = G.create++-- Restricting memory usage+-- ------------------------++-- | /O(n)/ Yield the argument but force it not to retain any extra memory,+-- possibly by copying it.+--+-- This is especially useful when dealing with slices. For example:+--+-- > force (slice 0 2 <huge vector>)+--+-- Here, the slice retains a reference to the huge vector. Forcing it creates+-- a copy of just the elements that belong to the slice and allows the huge+-- vector to be garbage collected.+force :: Storable a => Vector a -> Vector a+{-# INLINE force #-}+force = G.force++-- Bulk updates+-- ------------++-- | /O(m+n)/ For each pair @(i,a)@ from the list, replace the vector+-- element at position @i@ by @a@.+--+-- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7>+--+(//) :: Storable a => Vector a -- ^ initial vector (of length @m@)+ -> [(Int, a)] -- ^ list of index/value pairs (of length @n@) + -> Vector a+{-# INLINE (//) #-}+(//) = (G.//)++-- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the+-- corresponding value @a@ from the value vector, replace the element of the+-- initial vector at position @i@ by @a@.+--+-- > update_ <5,9,2,7> <2,0,2> <1,3,8> = <3,9,8,7>+--+update_ :: Storable a+ => Vector a -- ^ initial vector (of length @m@)+ -> Vector Int -- ^ index vector (of length @n1@)+ -> Vector a -- ^ value vector (of length @n2@)+ -> Vector a+{-# INLINE update_ #-}+update_ = G.update_++-- | Same as ('//') but without bounds checking. unsafeUpd :: Storable a => Vector a -> [(Int, a)] -> Vector a {-# INLINE unsafeUpd #-} unsafeUpd = G.unsafeUpd +-- | Same as 'update_' but without bounds checking. unsafeUpdate_ :: Storable a => Vector a -> Vector Int -> Vector a -> Vector a {-# INLINE unsafeUpdate_ #-} unsafeUpdate_ = G.unsafeUpdate_ -(//) :: Storable a => Vector a -> [(Int, a)] -> Vector a-{-# INLINE (//) #-}-(//) = (G.//)+-- Accumulations+-- ------------- -update_ :: Storable a => Vector a -> Vector Int -> Vector a -> Vector a-{-# INLINE update_ #-}-update_ = G.update_+-- | /O(m+n)/ For each pair @(i,b)@ from the list, replace the vector element+-- @a@ at position @i@ by @f a b@.+--+-- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4>+accum :: Storable a+ => (a -> b -> a) -- ^ accumulating function @f@+ -> Vector a -- ^ initial vector (of length @m@)+ -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)+ -> Vector a+{-# INLINE accum #-}+accum = G.accum +-- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the+-- corresponding value @b@ from the the value vector,+-- replace the element of the initial vector at+-- position @i@ by @f a b@.+--+-- > accumulate_ (+) <5,9,2> <2,1,0,1> <4,6,3,7> = <5+3, 9+6+7, 2+4>+--+accumulate_ :: (Storable a, Storable b)+ => (a -> b -> a) -- ^ accumulating function @f@+ -> Vector a -- ^ initial vector (of length @m@)+ -> Vector Int -- ^ index vector (of length @n1@)+ -> Vector b -- ^ value vector (of length @n2@)+ -> Vector a+{-# INLINE accumulate_ #-}+accumulate_ = G.accumulate_++-- | Same as 'accum' but without bounds checking.+unsafeAccum :: Storable a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a+{-# INLINE unsafeAccum #-}+unsafeAccum = G.unsafeAccum++-- | Same as 'accumulate_' but without bounds checking.+unsafeAccumulate_ :: (Storable a, Storable b) =>+ (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a+{-# INLINE unsafeAccumulate_ #-}+unsafeAccumulate_ = G.unsafeAccumulate_++-- Permutations+-- ------------++-- | /O(n)/ Reverse a vector+reverse :: Storable a => Vector a -> Vector a+{-# INLINE reverse #-}+reverse = G.reverse++-- | /O(n)/ Yield the vector obtained by replacing each element @i@ of the+-- index vector by @xs'!'i@. This is equivalent to @'map' (xs'!') is@ but is+-- often much more efficient.+--+-- > backpermute <a,b,c,d> <0,3,2,3,1,0> = <a,d,c,d,b,a> backpermute :: Storable a => Vector a -> Vector Int -> Vector a {-# INLINE backpermute #-} backpermute = G.backpermute +-- | Same as 'backpermute' but without bounds checking. unsafeBackpermute :: Storable a => Vector a -> Vector Int -> Vector a {-# INLINE unsafeBackpermute #-} unsafeBackpermute = G.unsafeBackpermute -reverse :: Storable a => Vector a -> Vector a-{-# INLINE reverse #-}-reverse = G.reverse+-- Safe destructive updates+-- ------------------------ +-- | Apply a destructive operation to a vector. The operation will be+-- performed in place if it is safe to do so and will modify a copy of the+-- vector otherwise.+--+-- @+-- modify (\\v -> write v 0 \'x\') ('replicate' 3 \'a\') = \<\'x\',\'a\',\'a\'\>+-- @+modify :: Storable a => (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a+{-# INLINE modify #-}+modify = G.modify+ -- Mapping -- ------- --- | Map a function over a vector+-- | /O(n)/ Map a function over a vector map :: (Storable a, Storable b) => (a -> b) -> Vector a -> Vector b {-# INLINE map #-} map = G.map --- | Apply a function to every index/value pair+-- | /O(n)/ Apply a function to every element of a vector and its index imap :: (Storable a, Storable b) => (Int -> a -> b) -> Vector a -> Vector b {-# INLINE imap #-} imap = G.imap +-- | Map a function over a vector and concatenate the results. concatMap :: (Storable a, Storable b) => (a -> Vector b) -> Vector a -> Vector b {-# INLINE concatMap #-} concatMap = G.concatMap --- Zipping/unzipping--- -----------------+-- Monadic mapping+-- --------------- --- | Zip two vectors with the given function.+-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a+-- vector of results+mapM :: (Monad m, Storable a, Storable b) => (a -> m b) -> Vector a -> m (Vector b)+{-# INLINE mapM #-}+mapM = G.mapM++-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the+-- results+mapM_ :: (Monad m, Storable a) => (a -> m b) -> Vector a -> m ()+{-# INLINE mapM_ #-}+mapM_ = G.mapM_++-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a+-- vector of results. Equvalent to @flip 'mapM'@.+forM :: (Monad m, Storable a, Storable b) => Vector a -> (a -> m b) -> m (Vector b)+{-# INLINE forM #-}+forM = G.forM++-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the+-- results. Equivalent to @flip 'mapM_'@.+forM_ :: (Monad m, Storable a) => Vector a -> (a -> m b) -> m ()+{-# INLINE forM_ #-}+forM_ = G.forM_++-- Zipping+-- -------++-- | /O(min(m,n))/ Zip two vectors with the given function. zipWith :: (Storable a, Storable b, Storable c) => (a -> b -> c) -> Vector a -> Vector b -> Vector c {-# INLINE zipWith #-}@@ -494,7 +762,8 @@ {-# INLINE zipWith6 #-} zipWith6 = G.zipWith6 --- | Zip two vectors and their indices with the given function.+-- | /O(min(m,n))/ Zip two vectors with a function that also takes the+-- elements' indices. izipWith :: (Storable a, Storable b, Storable c) => (Int -> a -> b -> c) -> Vector a -> Vector b -> Vector c {-# INLINE izipWith #-}@@ -529,54 +798,81 @@ {-# INLINE izipWith6 #-} izipWith6 = G.izipWith6 +-- Monadic zipping+-- ---------------++-- | /O(min(m,n))/ Zip the two vectors with the monadic action and yield a+-- vector of results+zipWithM :: (Monad m, Storable a, Storable b, Storable c)+ => (a -> b -> m c) -> Vector a -> Vector b -> m (Vector c)+{-# INLINE zipWithM #-}+zipWithM = G.zipWithM++-- | /O(min(m,n))/ Zip the two vectors with the monadic action and ignore the+-- results+zipWithM_ :: (Monad m, Storable a, Storable b)+ => (a -> b -> m c) -> Vector a -> Vector b -> m ()+{-# INLINE zipWithM_ #-}+zipWithM_ = G.zipWithM_+ -- Filtering -- --------- --- | Drop elements which do not satisfy the predicate+-- | /O(n)/ Drop elements that do not satisfy the predicate filter :: Storable a => (a -> Bool) -> Vector a -> Vector a {-# INLINE filter #-} filter = G.filter --- | Drop elements that do not satisfy the predicate (applied to values and--- their indices)+-- | /O(n)/ Drop elements that do not satisfy the predicate which is applied to+-- values and their indices ifilter :: Storable a => (Int -> a -> Bool) -> Vector a -> Vector a {-# INLINE ifilter #-} ifilter = G.ifilter --- | Yield the longest prefix of elements satisfying the predicate.+-- | /O(n)/ Drop elements that do not satisfy the monadic predicate+filterM :: (Monad m, Storable a) => (a -> m Bool) -> Vector a -> m (Vector a)+{-# INLINE filterM #-}+filterM = G.filterM++-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate+-- without copying. takeWhile :: Storable a => (a -> Bool) -> Vector a -> Vector a {-# INLINE takeWhile #-} takeWhile = G.takeWhile --- | Drop the longest prefix of elements that satisfy the predicate.+-- | /O(n)/ Drop the longest prefix of elements that satisfy the predicate+-- without copying. dropWhile :: Storable a => (a -> Bool) -> Vector a -> Vector a {-# INLINE dropWhile #-} dropWhile = G.dropWhile --- | Split the vector in two parts, the first one containing those elements--- that satisfy the predicate and the second one those that don't. The--- relative order of the elements is preserved at the cost of a (sometimes)+-- Parititioning+-- -------------++-- | /O(n)/ Split the vector in two parts, the first one containing those+-- elements that satisfy the predicate and the second one those that don't. The+-- relative order of the elements is preserved at the cost of a sometimes -- reduced performance compared to 'unstablePartition'. partition :: Storable a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE partition #-} partition = G.partition --- | Split the vector in two parts, the first one containing those elements--- that satisfy the predicate and the second one those that don't. The order--- of the elements is not preserved.-unstablePartition- :: Storable a => (a -> Bool) -> Vector a -> (Vector a, Vector a)+-- | /O(n)/ Split the vector in two parts, the first one containing those+-- elements that satisfy the predicate and the second one those that don't.+-- The order of the elements is not preserved but the operation is often+-- faster than 'partition'.+unstablePartition :: Storable a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE unstablePartition #-} unstablePartition = G.unstablePartition --- | Split the vector into the longest prefix of elements that satisfy the--- predicate and the rest.+-- | /O(n)/ Split the vector into the longest prefix of elements that satisfy+-- the predicate and the rest without copying. span :: Storable a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE span #-} span = G.span --- | Split the vector into the longest prefix of elements that do not satisfy--- the predicate and the rest.+-- | /O(n)/ Split the vector into the longest prefix of elements that do not+-- satisfy the predicate and the rest without copying. break :: Storable a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE break #-} break = G.break@@ -585,41 +881,44 @@ -- --------- infix 4 `elem`--- | Check whether the vector contains an element+-- | /O(n)/ Check if the vector contains an element elem :: (Storable a, Eq a) => a -> Vector a -> Bool {-# INLINE elem #-} elem = G.elem infix 4 `notElem`--- | Inverse of `elem`+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem') notElem :: (Storable a, Eq a) => a -> Vector a -> Bool {-# INLINE notElem #-} notElem = G.notElem --- | Yield 'Just' the first element matching the predicate or 'Nothing' if no--- such element exists.+-- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing'+-- if no such element exists. find :: Storable a => (a -> Bool) -> Vector a -> Maybe a {-# INLINE find #-} find = G.find --- | Yield 'Just' the index of the first element matching the predicate or--- 'Nothing' if no such element exists.+-- | /O(n)/ Yield 'Just' the index of the first element matching the predicate+-- or 'Nothing' if no such element exists. findIndex :: Storable a => (a -> Bool) -> Vector a -> Maybe Int {-# INLINE findIndex #-} findIndex = G.findIndex --- | Yield the indices of elements satisfying the predicate+-- | /O(n)/ Yield the indices of elements satisfying the predicate in ascending+-- order. findIndices :: Storable a => (a -> Bool) -> Vector a -> Vector Int {-# INLINE findIndices #-} findIndices = G.findIndices --- | Yield 'Just' the index of the first occurence of the given element or--- 'Nothing' if the vector does not contain the element+-- | /O(n)/ Yield 'Just' the index of the first occurence of the given element or+-- 'Nothing' if the vector does not contain the element. This is a specialised+-- version of 'findIndex'. elemIndex :: (Storable a, Eq a) => a -> Vector a -> Maybe Int {-# INLINE elemIndex #-} elemIndex = G.elemIndex --- | Yield the indices of all occurences of the given element+-- | /O(n)/ Yield the indices of all occurences of the given element in+-- ascending order. This is a specialised version of 'findIndices'. elemIndices :: (Storable a, Eq a) => a -> Vector a -> Vector Int {-# INLINE elemIndices #-} elemIndices = G.elemIndices@@ -627,64 +926,64 @@ -- Folding -- ------- --- | Left fold+-- | /O(n)/ Left fold foldl :: Storable b => (a -> b -> a) -> a -> Vector b -> a {-# INLINE foldl #-} foldl = G.foldl --- | Lefgt fold on non-empty vectors+-- | /O(n)/ Left fold on non-empty vectors foldl1 :: Storable a => (a -> a -> a) -> Vector a -> a {-# INLINE foldl1 #-} foldl1 = G.foldl1 --- | Left fold with strict accumulator+-- | /O(n)/ Left fold with strict accumulator foldl' :: Storable b => (a -> b -> a) -> a -> Vector b -> a {-# INLINE foldl' #-} foldl' = G.foldl' --- | Left fold on non-empty vectors with strict accumulator+-- | /O(n)/ Left fold on non-empty vectors with strict accumulator foldl1' :: Storable a => (a -> a -> a) -> Vector a -> a {-# INLINE foldl1' #-} foldl1' = G.foldl1' --- | Right fold+-- | /O(n)/ Right fold foldr :: Storable a => (a -> b -> b) -> b -> Vector a -> b {-# INLINE foldr #-} foldr = G.foldr --- | Right fold on non-empty vectors+-- | /O(n)/ Right fold on non-empty vectors foldr1 :: Storable a => (a -> a -> a) -> Vector a -> a {-# INLINE foldr1 #-} foldr1 = G.foldr1 --- | Right fold with a strict accumulator+-- | /O(n)/ Right fold with a strict accumulator foldr' :: Storable a => (a -> b -> b) -> b -> Vector a -> b {-# INLINE foldr' #-} foldr' = G.foldr' --- | Right fold on non-empty vectors with strict accumulator+-- | /O(n)/ Right fold on non-empty vectors with strict accumulator foldr1' :: Storable a => (a -> a -> a) -> Vector a -> a {-# INLINE foldr1' #-} foldr1' = G.foldr1' --- | Left fold (function applied to each element and its index)+-- | /O(n)/ Left fold (function applied to each element and its index) ifoldl :: Storable b => (a -> Int -> b -> a) -> a -> Vector b -> a {-# INLINE ifoldl #-} ifoldl = G.ifoldl --- | Left fold with strict accumulator (function applied to each element and--- its index)+-- | /O(n)/ Left fold with strict accumulator (function applied to each element+-- and its index) ifoldl' :: Storable b => (a -> Int -> b -> a) -> a -> Vector b -> a {-# INLINE ifoldl' #-} ifoldl' = G.ifoldl' --- | Right fold (function applied to each element and its index)+-- | /O(n)/ Right fold (function applied to each element and its index) ifoldr :: Storable a => (Int -> a -> b -> b) -> b -> Vector a -> b {-# INLINE ifoldr #-} ifoldr = G.ifoldr --- | Right fold with strict accumulator (function applied to each element and--- its index)+-- | /O(n)/ Right fold with strict accumulator (function applied to each+-- element and its index) ifoldr' :: Storable a => (Int -> a -> b -> b) -> b -> Vector a -> b {-# INLINE ifoldr' #-} ifoldr' = G.ifoldr'@@ -692,329 +991,265 @@ -- Specialised folds -- ----------------- +-- | /O(n)/ Check if all elements satisfy the predicate. all :: Storable a => (a -> Bool) -> Vector a -> Bool {-# INLINE all #-} all = G.all +-- | /O(n)/ Check if any element satisfies the predicate. any :: Storable a => (a -> Bool) -> Vector a -> Bool {-# INLINE any #-} any = G.any +-- | /O(n)/ Check if all elements are 'True' and :: Vector Bool -> Bool {-# INLINE and #-} and = G.and +-- | /O(n)/ Check if any element is 'True' or :: Vector Bool -> Bool {-# INLINE or #-} or = G.or +-- | /O(n)/ Compute the sum of the elements sum :: (Storable a, Num a) => Vector a -> a {-# INLINE sum #-} sum = G.sum +-- | /O(n)/ Compute the produce of the elements product :: (Storable a, Num a) => Vector a -> a {-# INLINE product #-} product = G.product +-- | /O(n)/ Yield the maximum element of the vector. The vector may not be+-- empty. maximum :: (Storable a, Ord a) => Vector a -> a {-# INLINE maximum #-} maximum = G.maximum +-- | /O(n)/ Yield the maximum element of the vector according to the given+-- comparison function. The vector may not be empty. maximumBy :: Storable a => (a -> a -> Ordering) -> Vector a -> a {-# INLINE maximumBy #-} maximumBy = G.maximumBy +-- | /O(n)/ Yield the minimum element of the vector. The vector may not be+-- empty. minimum :: (Storable a, Ord a) => Vector a -> a {-# INLINE minimum #-} minimum = G.minimum +-- | /O(n)/ Yield the minimum element of the vector according to the given+-- comparison function. The vector may not be empty. minimumBy :: Storable a => (a -> a -> Ordering) -> Vector a -> a {-# INLINE minimumBy #-} minimumBy = G.minimumBy +-- | /O(n)/ Yield the index of the maximum element of the vector. The vector+-- may not be empty. maxIndex :: (Storable a, Ord a) => Vector a -> Int {-# INLINE maxIndex #-} maxIndex = G.maxIndex +-- | /O(n)/ Yield the index of the maximum element of the vector according to+-- the given comparison function. The vector may not be empty. maxIndexBy :: Storable a => (a -> a -> Ordering) -> Vector a -> Int {-# INLINE maxIndexBy #-} maxIndexBy = G.maxIndexBy +-- | /O(n)/ Yield the index of the minimum element of the vector. The vector+-- may not be empty. minIndex :: (Storable a, Ord a) => Vector a -> Int {-# INLINE minIndex #-} minIndex = G.minIndex +-- | /O(n)/ Yield the index of the minimum element of the vector according to+-- the given comparison function. The vector may not be empty. minIndexBy :: Storable a => (a -> a -> Ordering) -> Vector a -> Int {-# INLINE minIndexBy #-} minIndexBy = G.minIndexBy --- Unfolding--- ---------+-- Monadic folds+-- ------------- --- | The 'unfoldr' function is a \`dual\' to 'foldr': while 'foldr'--- reduces a vector to a summary value, 'unfoldr' builds a list from--- a seed value. The function takes the element and returns 'Nothing'--- if it is done generating the vector or returns 'Just' @(a,b)@, in which--- case, @a@ is a prepended to the vector and @b@ is used as the next--- element in a recursive call.------ A simple use of unfoldr:------ > unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10--- > [10,9,8,7,6,5,4,3,2,1]----unfoldr :: Storable a => (b -> Maybe (a, b)) -> b -> Vector a-{-# INLINE unfoldr #-}-unfoldr = G.unfoldr+-- | /O(n)/ Monadic fold+foldM :: (Monad m, Storable b) => (a -> b -> m a) -> a -> Vector b -> m a+{-# INLINE foldM #-}+foldM = G.foldM --- | Unfold at most @n@ elements-unfoldrN :: Storable a => Int -> (b -> Maybe (a, b)) -> b -> Vector a-{-# INLINE unfoldrN #-}-unfoldrN = G.unfoldrN+-- | /O(n)/ Monadic fold over non-empty vectors+fold1M :: (Monad m, Storable a) => (a -> a -> m a) -> Vector a -> m a+{-# INLINE fold1M #-}+fold1M = G.fold1M --- Scans--- -----+-- | /O(n)/ Monadic fold with strict accumulator+foldM' :: (Monad m, Storable b) => (a -> b -> m a) -> a -> Vector b -> m a+{-# INLINE foldM' #-}+foldM' = G.foldM' --- | Prefix scan+-- | /O(n)/ Monad fold over non-empty vectors with strict accumulator+fold1M' :: (Monad m, Storable a) => (a -> a -> m a) -> Vector a -> m a+{-# INLINE fold1M' #-}+fold1M' = G.fold1M'++-- Prefix sums (scans)+-- -------------------++-- | /O(n)/ Prescan+--+-- @+-- prescanl f z = 'init' . 'scanl' f z+-- @+--+-- Example: @prescanl (+) 0 \<1,2,3,4\> = \<0,1,3,6\>@+-- prescanl :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE prescanl #-} prescanl = G.prescanl --- | Prefix scan with strict accumulator+-- | /O(n)/ Prescan with strict accumulator prescanl' :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE prescanl' #-} prescanl' = G.prescanl' --- | Suffix scan+-- | /O(n)/ Scan+--+-- @+-- postscanl f z = 'tail' . 'scanl' f z+-- @+--+-- Example: @postscanl (+) 0 \<1,2,3,4\> = \<1,3,6,10\>@+-- postscanl :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE postscanl #-} postscanl = G.postscanl --- | Suffix scan with strict accumulator+-- | /O(n)/ Scan with strict accumulator postscanl' :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE postscanl' #-} postscanl' = G.postscanl' --- | Haskell-style scan+-- | /O(n)/ Haskell-style scan+--+-- > scanl f z <x1,...,xn> = <y1,...,y(n+1)>+-- > where y1 = z+-- > yi = f y(i-1) x(i-1)+--+-- Example: @scanl (+) 0 \<1,2,3,4\> = \<0,1,3,6,10\>@+-- scanl :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE scanl #-} scanl = G.scanl --- | Haskell-style scan with strict accumulator+-- | /O(n)/ Haskell-style scan with strict accumulator scanl' :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE scanl' #-} scanl' = G.scanl' --- | Scan over a non-empty 'Vector'+-- | /O(n)/ Scan over a non-empty vector+--+-- > scanl f <x1,...,xn> = <y1,...,yn>+-- > where y1 = x1+-- > yi = f y(i-1) xi+-- scanl1 :: Storable a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanl1 #-} scanl1 = G.scanl1 --- | Scan over a non-empty 'Vector' with a strict accumulator+-- | /O(n)/ Scan over a non-empty vector with a strict accumulator scanl1' :: Storable a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanl1' #-} scanl1' = G.scanl1' ---- | Prefix right-to-left scan-prescanr- :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector a -> Vector b+-- | /O(n)/ Right-to-left prescan+--+-- @+-- prescanr f z = 'reverse' . 'prescanl' (flip f) z . 'reverse'+-- @+--+prescanr :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE prescanr #-} prescanr = G.prescanr --- | Prefix right-to-left scan with strict accumulator-prescanr'- :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector a -> Vector b+-- | /O(n)/ Right-to-left prescan with strict accumulator+prescanr' :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE prescanr' #-} prescanr' = G.prescanr' --- | Suffix right-to-left scan-postscanr- :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector a -> Vector b+-- | /O(n)/ Right-to-left scan+postscanr :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE postscanr #-} postscanr = G.postscanr --- | Suffix right-to-left scan with strict accumulator-postscanr'- :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector a -> Vector b+-- | /O(n)/ Right-to-left scan with strict accumulator+postscanr' :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE postscanr' #-} postscanr' = G.postscanr' --- | Haskell-style right-to-left scan+-- | /O(n)/ Right-to-left Haskell-style scan scanr :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE scanr #-} scanr = G.scanr --- | Haskell-style right-to-left scan with strict accumulator+-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator scanr' :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE scanr' #-} scanr' = G.scanr' --- | Right-to-left scan over a non-empty vector+-- | /O(n)/ Right-to-left scan over a non-empty vector scanr1 :: Storable a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanr1 #-} scanr1 = G.scanr1 --- | Right-to-left scan over a non-empty vector with a strict accumulator+-- | /O(n)/ Right-to-left scan over a non-empty vector with a strict+-- accumulator scanr1' :: Storable a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanr1' #-} scanr1' = G.scanr1' --- Enumeration--- --------------- | Yield a vector of the given length containing the values @x@, @x+1@ etc.--- This operation is usually more efficient than 'enumFromTo'.-enumFromN :: (Storable a, Num a) => a -> Int -> Vector a-{-# INLINE enumFromN #-}-enumFromN = G.enumFromN---- | Yield a vector of the given length containing the values @x@, @x+y@,--- @x+y+y@ etc. This operations is usually more efficient than--- 'enumFromThenTo'.-enumFromStepN :: (Storable a, Num a) => a -> a -> Int -> Vector a-{-# INLINE enumFromStepN #-}-enumFromStepN = G.enumFromStepN---- | Enumerate values from @x@ to @y@.------ /WARNING:/ This operation can be very inefficient. If at all possible, use--- 'enumFromN' instead.-enumFromTo :: (Storable a, Enum a) => a -> a -> Vector a-{-# INLINE enumFromTo #-}-enumFromTo = G.enumFromTo---- | Enumerate values from @x@ to @y@ with a specific step @z@.------ /WARNING:/ This operation can be very inefficient. If at all possible, use--- 'enumFromStepN' instead.-enumFromThenTo :: (Storable a, Enum a) => a -> a -> a -> Vector a-{-# INLINE enumFromThenTo #-}-enumFromThenTo = G.enumFromThenTo---- Conversion to/from lists+-- Conversions - Lists -- ------------------------ --- | Convert a vector to a list+-- | /O(n)/ Convert a vector to a list toList :: Storable a => Vector a -> [a] {-# INLINE toList #-} toList = G.toList --- | Convert a list to a vector+-- | /O(n)/ Convert a list to a vector fromList :: Storable a => [a] -> Vector a {-# INLINE fromList #-} fromList = G.fromList --- | Convert the first @n@ elements of a list to a vector+-- | /O(n)/ Convert the first @n@ elements of a list to a vector ----- > fromListN n xs = fromList (take n xs)+-- @+-- fromListN n xs = 'fromList' ('take' n xs)+-- @ fromListN :: Storable a => Int -> [a] -> Vector a {-# INLINE fromListN #-} fromListN = G.fromListN --- Monadic operations--- ---------------------- | Perform the monadic action the given number of times and store the--- results in a vector.-replicateM :: (Monad m, Storable a) => Int -> m a -> m (Vector a)-{-# INLINE replicateM #-}-replicateM = G.replicateM---- | Apply the monadic action to all elements of the vector, yielding a vector--- of results-mapM :: (Monad m, Storable a, Storable b) => (a -> m b) -> Vector a -> m (Vector b)-{-# INLINE mapM #-}-mapM = G.mapM---- | Apply the monadic action to all elements of a vector and ignore the--- results-mapM_ :: (Monad m, Storable a) => (a -> m b) -> Vector a -> m ()-{-# INLINE mapM_ #-}-mapM_ = G.mapM_---- | Apply the monadic action to all elements of the vector, yielding a vector--- of results-forM :: (Monad m, Storable a, Storable b) => Vector a -> (a -> m b) -> m (Vector b)-{-# INLINE forM #-}-forM = G.forM---- | Apply the monadic action to all elements of a vector and ignore the--- results-forM_ :: (Monad m, Storable a) => Vector a -> (a -> m b) -> m ()-{-# INLINE forM_ #-}-forM_ = G.forM_---- | Zip the two vectors with the monadic action and yield a vector of results-zipWithM :: (Monad m, Storable a, Storable b, Storable c)- => (a -> b -> m c) -> Vector a -> Vector b -> m (Vector c)-{-# INLINE zipWithM #-}-zipWithM = G.zipWithM---- | Zip the two vectors with the monadic action and ignore the results-zipWithM_ :: (Monad m, Storable a, Storable b)- => (a -> b -> m c) -> Vector a -> Vector b -> m ()-{-# INLINE zipWithM_ #-}-zipWithM_ = G.zipWithM_---- | Drop elements that do not satisfy the monadic predicate-filterM :: (Monad m, Storable a) => (a -> m Bool) -> Vector a -> m (Vector a)-{-# INLINE filterM #-}-filterM = G.filterM---- | Monadic fold-foldM :: (Monad m, Storable b) => (a -> b -> m a) -> a -> Vector b -> m a-{-# INLINE foldM #-}-foldM = G.foldM---- | Monadic fold over non-empty vectors-fold1M :: (Monad m, Storable a) => (a -> a -> m a) -> Vector a -> m a-{-# INLINE fold1M #-}-fold1M = G.fold1M---- | Monadic fold with strict accumulator-foldM' :: (Monad m, Storable b) => (a -> b -> m a) -> a -> Vector b -> m a-{-# INLINE foldM' #-}-foldM' = G.foldM'---- | Monad fold over non-empty vectors with strict accumulator-fold1M' :: (Monad m, Storable a) => (a -> a -> m a) -> Vector a -> m a-{-# INLINE fold1M' #-}-fold1M' = G.fold1M'---- Destructive operations--- -------------------------- | Destructively initialise a vector.-create :: Storable a => (forall s. ST s (MVector s a)) -> Vector a-{-# INLINE create #-}-create = G.create---- | Apply a destructive operation to a vector. The operation is applied to a--- copy of the vector unless it can be safely performed in place.-modify- :: Storable a => (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a-{-# INLINE modify #-}-modify = G.modify+-- Conversions - Mutable vectors+-- ----------------------------- --- | Copy an immutable vector into a mutable one. The two vectors must have--- the same length. This is not checked.+-- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must+-- have the same length. unsafeCopy :: (Storable a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE unsafeCopy #-} unsafeCopy = G.unsafeCopy --- | Copy an immutable vector into a mutable one. The two vectors must have the--- same length.+-- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must+-- have the same length. This is not checked. copy :: (Storable a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE copy #-} copy = G.copy --- Accessing the underlying memory--- -------------------------------+-- Conversions - Raw pointers+-- -------------------------- --- | Create a vector from a 'ForeignPtr' with an offset and a length. The data--- may not be modified through the 'ForeignPtr' afterwards.+-- | /O(1)/ Create a vector from a 'ForeignPtr' with an offset and a length.+-- The data may not be modified through the 'ForeignPtr' afterwards. unsafeFromForeignPtr :: Storable a => ForeignPtr a -- ^ pointer -> Int -- ^ offset@@ -1023,8 +1258,8 @@ {-# INLINE unsafeFromForeignPtr #-} unsafeFromForeignPtr fp i n = Vector (offsetToPtr fp i) n fp --- | Yield the underlying 'ForeignPtr' together with the offset to the data--- and its length. The data may not be modified through the 'ForeignPtr'.+-- | /O(1)/ Yield the underlying 'ForeignPtr' together with the offset to the+-- data and its length. The data may not be modified through the 'ForeignPtr'. unsafeToForeignPtr :: Storable a => Vector a -> (ForeignPtr a, Int, Int) {-# INLINE unsafeToForeignPtr #-} unsafeToForeignPtr (Vector p n fp) = (fp, ptrToOffset fp p, n)
Data/Vector/Unboxed.hs view
@@ -9,65 +9,134 @@ -- Stability : experimental -- Portability : non-portable ----- Adaptive unboxed vectors+-- Adaptive unboxed vectors. The implementation is based on type families+-- and picks an efficient, specialised representation for every element type.+-- In particular, unboxed vectors of pairs are represented as pairs of unboxed+-- vectors. --+-- Implementing unboxed vectors for new data types can be very easy. Here is+-- how the library does this for 'Complex' by simply wrapping vectors of+-- pairs.+--+-- @+-- newtype instance 'MVector' s ('Complex' a) = MV_Complex ('MVector' s (a,a))+-- newtype instance 'Vector' ('Complex' a) = V_Complex ('Vector' (a,a))+--+-- instance ('RealFloat' a, 'Unbox' a) => 'Data.Vector.Generic.Mutable.MVector' 'MVector' ('Complex' a) where+-- {-\# INLINE basicLength \#-}+-- basicLength (MV_Complex v) = 'Data.Vector.Generic.Mutable.basicLength' v+-- ...+--+-- instance ('RealFloat' a, 'Unbox' a) => Data.Vector.Generic.Vector 'Vector' ('Complex' a) where+-- {-\# INLINE basicLength \#-}+-- basicLength (V_Complex v) = Data.Vector.Generic.basicLength v+-- ...+--+-- instance ('RealFloat' a, 'Unbox' a) => 'Unbox' ('Complex' a)+-- @ module Data.Vector.Unboxed (+ -- * Unboxed vectors Vector, MVector(..), Unbox, - -- * Length information- length, null,+ -- * Accessors - -- * Construction- empty, singleton, cons, snoc, replicate, generate, (++), force,+ -- ** Length information+ length, null, - -- * Accessing individual elements- (!), head, last, indexM, headM, lastM,+ -- ** Indexing+ (!), head, last, unsafeIndex, unsafeHead, unsafeLast,++ -- ** Monadic indexing+ indexM, headM, lastM, unsafeIndexM, unsafeHeadM, unsafeLastM, - -- * Subvectors+ -- ** Extracting subvectors (slicing) slice, init, tail, take, drop, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, - -- * Permutations- accum, accumulate, accumulate_,+ -- * Construction++ -- ** Initialisation+ empty, singleton, replicate, generate,++ -- ** Monadic initialisation+ replicateM, create,++ -- ** Unfolding+ unfoldr, unfoldrN,++ -- ** Enumeration+ enumFromN, enumFromStepN, enumFromTo, enumFromThenTo,++ -- ** Concatenation+ cons, snoc, (++),++ -- ** Restricting memory usage+ force,++ -- * Modifying vectors++ -- ** Bulk updates (//), update, update_,- backpermute, reverse,- unsafeAccum, unsafeAccumulate, unsafeAccumulate_, unsafeUpd, unsafeUpdate, unsafeUpdate_,- unsafeBackpermute, - -- * Mapping+ -- ** Accumulations+ accum, accumulate, accumulate_,+ unsafeAccum, unsafeAccumulate, unsafeAccumulate_,++ -- ** Permutations + reverse, backpermute, unsafeBackpermute,++ -- ** Safe destructive updates+ modify,++ -- * Elementwise operations++ -- ** Mapping map, imap, concatMap, - -- * Zipping and unzipping+ -- ** Monadic mapping+ mapM, mapM_, forM, forM_,++ -- ** Zipping zipWith, zipWith3, zipWith4, zipWith5, zipWith6, izipWith, izipWith3, izipWith4, izipWith5, izipWith6, zip, zip3, zip4, zip5, zip6,++ -- ** Monadic zipping+ zipWithM, zipWithM_,++ -- ** Unzipping unzip, unzip3, unzip4, unzip5, unzip6, - -- * Filtering- filter, ifilter, takeWhile, dropWhile,+ -- * Working with predicates++ -- ** Filtering+ filter, ifilter, filterM,+ takeWhile, dropWhile,++ -- ** Partitioning partition, unstablePartition, span, break, - -- * Searching+ -- ** Searching elem, notElem, find, findIndex, findIndices, elemIndex, elemIndices, -- * Folding foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1', ifoldl, ifoldl', ifoldr, ifoldr', - -- * Specialised folds+ -- ** Specialised folds all, any, and, or, sum, product, maximum, maximumBy, minimum, minimumBy, minIndex, minIndexBy, maxIndex, maxIndexBy, - -- * Unfolding- unfoldr, unfoldrN,+ -- ** Monadic folds+ foldM, foldM', fold1M, fold1M', - -- * Scans+ -- * Prefix sums (scans) prescanl, prescanl', postscanl, postscanl', scanl, scanl', scanl1, scanl1',@@ -75,18 +144,13 @@ postscanr, postscanr', scanr, scanr', scanr1, scanr1', - -- * Enumeration- enumFromN, enumFromStepN, enumFromTo, enumFromThenTo,+ -- * Conversions - -- * Conversion to/from lists+ -- ** Lists toList, fromList, fromListN, - -- * Monadic operations- replicateM, mapM, mapM_, forM, forM_, zipWithM, zipWithM_, filterM,- foldM, foldM', fold1M, fold1M',-- -- * Destructive operations- create, modify, copy, unsafeCopy+ -- ** Mutable vectors+ copy, unsafeCopy ) where import Data.Vector.Unboxed.Base@@ -141,269 +205,524 @@ instance (Show a, Unbox a) => Show (Vector a) where show = (Prelude.++ " :: Data.Vector.Unboxed.Vector") . ("fromList " Prelude.++) . show . toList --- Length--- ------+-- Length information+-- ------------------ +-- | /O(1)/ Yield the length of the vector. length :: Unbox a => Vector a -> Int {-# INLINE length #-} length = G.length +-- | /O(1)/ Test whether a vector if empty null :: Unbox a => Vector a -> Bool {-# INLINE null #-} null = G.null --- Construction--- ---------------- | Empty vector-empty :: Unbox a => Vector a-{-# INLINE empty #-}-empty = G.empty---- | Vector with exaclty one element-singleton :: Unbox a => a -> Vector a-{-# INLINE singleton #-}-singleton = G.singleton---- | Vector of the given length with the given value in each position-replicate :: Unbox a => Int -> a -> Vector a-{-# INLINE replicate #-}-replicate = G.replicate---- | Generate a vector of the given length by applying the function to each--- index-generate :: Unbox a => Int -> (Int -> a) -> Vector a-{-# INLINE generate #-}-generate = G.generate---- | Prepend an element-cons :: Unbox a => a -> Vector a -> Vector a-{-# INLINE cons #-}-cons = G.cons---- | Append an element-snoc :: Unbox a => Vector a -> a -> Vector a-{-# INLINE snoc #-}-snoc = G.snoc--infixr 5 ++--- | Concatenate two vectors-(++) :: Unbox a => Vector a -> Vector a -> Vector a-{-# INLINE (++) #-}-(++) = (G.++)---- | Create a copy of a vector. Useful when dealing with slices.-force :: Unbox a => Vector a -> Vector a-{-# INLINE force #-}-force = G.force---- Accessing individual elements--- -----------------------------+-- Indexing+-- -------- --- | Indexing+-- | O(1) Indexing (!) :: Unbox a => Vector a -> Int -> a {-# INLINE (!) #-} (!) = (G.!) --- | First element+-- | /O(1)/ First element head :: Unbox a => Vector a -> a {-# INLINE head #-} head = G.head --- | Last element+-- | /O(1)/ Last element last :: Unbox a => Vector a -> a {-# INLINE last #-} last = G.last --- | Unsafe indexing without bounds checking+-- | /O(1)/ Unsafe indexing without bounds checking unsafeIndex :: Unbox a => Vector a -> Int -> a {-# INLINE unsafeIndex #-} unsafeIndex = G.unsafeIndex --- | Yield the first element of a vector without checking if the vector is--- empty+-- | /O(1)/ First element without checking if the vector is empty unsafeHead :: Unbox a => Vector a -> a {-# INLINE unsafeHead #-} unsafeHead = G.unsafeHead --- | Yield the last element of a vector without checking if the vector is--- empty+-- | /O(1)/ Last element without checking if the vector is empty unsafeLast :: Unbox a => Vector a -> a {-# INLINE unsafeLast #-} unsafeLast = G.unsafeLast --- | Monadic indexing which can be strict in the vector while remaining lazy in--- the element+-- Monadic indexing+-- ----------------++-- | /O(1)/ Indexing in a monad.+--+-- The monad allows operations to be strict in the vector when necessary.+-- Suppose vector copying is implemented like this:+--+-- > copy mv v = ... write mv i (v ! i) ...+--+-- For lazy vectors, @v ! i@ would not be evaluated which means that @mv@+-- would unnecessarily retain a reference to @v@ in each element written.+--+-- With 'indexM', copying can be implemented like this instead:+--+-- > copy mv v = ... do+-- > x <- indexM v i+-- > write mv i x+--+-- Here, no references to @v@ are retained because indexing (but /not/ the+-- elements) is evaluated eagerly.+-- indexM :: (Unbox a, Monad m) => Vector a -> Int -> m a {-# INLINE indexM #-} indexM = G.indexM +-- | /O(1)/ First element of a vector in a monad. See 'indexM' for an+-- explanation of why this is useful. headM :: (Unbox a, Monad m) => Vector a -> m a {-# INLINE headM #-} headM = G.headM +-- | /O(1)/ Last element of a vector in a monad. See 'indexM' for an+-- explanation of why this is useful. lastM :: (Unbox a, Monad m) => Vector a -> m a {-# INLINE lastM #-} lastM = G.lastM --- | Unsafe monadic indexing without bounds checks+-- | /O(1)/ Indexing in a monad without bounds checks. See 'indexM' for an+-- explanation of why this is useful. unsafeIndexM :: (Unbox a, Monad m) => Vector a -> Int -> m a {-# INLINE unsafeIndexM #-} unsafeIndexM = G.unsafeIndexM +-- | /O(1)/ First element in a monad without checking for empty vectors.+-- See 'indexM' for an explanation of why this is useful. unsafeHeadM :: (Unbox a, Monad m) => Vector a -> m a {-# INLINE unsafeHeadM #-} unsafeHeadM = G.unsafeHeadM +-- | /O(1)/ Last element in a monad without checking for empty vectors.+-- See 'indexM' for an explanation of why this is useful. unsafeLastM :: (Unbox a, Monad m) => Vector a -> m a {-# INLINE unsafeLastM #-} unsafeLastM = G.unsafeLastM --- Subarrays--- ---------+-- Extracting subvectors (slicing)+-- ------------------------------- --- | Yield a part of the vector without copying it. Safer version of--- 'basicUnsafeSlice'.-slice :: Unbox a => Int -- ^ starting index- -> Int -- ^ length+-- | /O(1)/ Yield a slice of the vector without copying it. The vector must+-- contain at least @i+n@ elements.+slice :: Unbox a => Int -- ^ @i@ starting index+ -> Int -- ^ @n@ length -> Vector a -> Vector a {-# INLINE slice #-} slice = G.slice --- | Yield all but the last element without copying.+-- | /O(1)/ Yield all but the last element without copying. The vector may not+-- be empty. init :: Unbox a => Vector a -> Vector a {-# INLINE init #-} init = G.init --- | All but the first element (without copying).+-- | /O(1)/ Yield all but the first element without copying. The vector may not+-- be empty. tail :: Unbox a => Vector a -> Vector a {-# INLINE tail #-} tail = G.tail --- | Yield the first @n@ elements without copying.+-- | /O(1)/ Yield at the first @n@ elements without copying. The vector may+-- contain less than @n@ elements in which case it is returned unchanged. take :: Unbox a => Int -> Vector a -> Vector a {-# INLINE take #-} take = G.take --- | Yield all but the first @n@ elements without copying.+-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may+-- contain less than @n@ elements in which case an empty vector is returned. drop :: Unbox a => Int -> Vector a -> Vector a {-# INLINE drop #-} drop = G.drop --- | Unsafely yield a part of the vector without copying it and without--- performing bounds checks.-unsafeSlice :: Unbox a => Int -- ^ starting index- -> Int -- ^ length+-- | /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+ -> Int -- ^ @n@ length -> Vector a -> Vector a {-# INLINE unsafeSlice #-} unsafeSlice = G.unsafeSlice +-- | /O(1)/ Yield all but the last element without copying. The vector may not+-- be empty but this is not checked. unsafeInit :: Unbox a => Vector a -> Vector a {-# INLINE unsafeInit #-} unsafeInit = G.unsafeInit +-- | /O(1)/ Yield all but the first element without copying. The vector may not+-- be empty but this is not checked. unsafeTail :: Unbox a => Vector a -> Vector a {-# INLINE unsafeTail #-} unsafeTail = G.unsafeTail +-- | /O(1)/ Yield the first @n@ elements without copying. The vector must+-- contain at least @n@ elements but this is not checked. unsafeTake :: Unbox a => Int -> Vector a -> Vector a {-# INLINE unsafeTake #-} unsafeTake = G.unsafeTake +-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector+-- must contain at least @n@ elements but this is not checked. unsafeDrop :: Unbox a => Int -> Vector a -> Vector a {-# INLINE unsafeDrop #-} unsafeDrop = G.unsafeDrop --- Permutations--- ------------+-- Initialisation+-- -------------- -unsafeAccum :: Unbox a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a-{-# INLINE unsafeAccum #-}-unsafeAccum = G.unsafeAccum+-- | /O(1)/ Empty vector+empty :: Unbox a => Vector a+{-# INLINE empty #-}+empty = G.empty -unsafeAccumulate :: (Unbox a, Unbox b)- => (a -> b -> a) -> Vector a -> Vector (Int,b) -> Vector a-{-# INLINE unsafeAccumulate #-}-unsafeAccumulate = G.unsafeAccumulate+-- | /O(1)/ Vector with exactly one element+singleton :: Unbox a => a -> Vector a+{-# INLINE singleton #-}+singleton = G.singleton -unsafeAccumulate_ :: (Unbox a, Unbox b) =>- (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a-{-# INLINE unsafeAccumulate_ #-}-unsafeAccumulate_ = G.unsafeAccumulate_+-- | /O(n)/ Vector of the given length with the same value in each position+replicate :: Unbox a => Int -> a -> Vector a+{-# INLINE replicate #-}+replicate = G.replicate -accum :: Unbox a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a-{-# INLINE accum #-}-accum = G.accum+-- | /O(n)/ Construct a vector of the given length by applying the function to+-- each index+generate :: Unbox a => Int -> (Int -> a) -> Vector a+{-# INLINE generate #-}+generate = G.generate -accumulate :: (Unbox a, Unbox b)- => (a -> b -> a) -> Vector a -> Vector (Int,b) -> Vector a-{-# INLINE accumulate #-}-accumulate = G.accumulate+-- Unfolding+-- --------- -accumulate_ :: (Unbox a, Unbox b) =>- (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a-{-# INLINE accumulate_ #-}-accumulate_ = G.accumulate_+-- | /O(n)/ Construct a vector by repeatedly applying the generator function+-- to a seed. The generator function yields 'Just' the next element and the+-- new seed or 'Nothing' if there are no more elements.+--+-- > unfoldr (\n -> if n == 0 then Nothing else Just (n,n-1)) 10+-- > = <10,9,8,7,6,5,4,3,2,1>+unfoldr :: Unbox a => (b -> Maybe (a, b)) -> b -> Vector a+{-# INLINE unfoldr #-}+unfoldr = G.unfoldr +-- | /O(n)/ Construct a vector with at most @n@ by repeatedly applying the+-- generator function to the a seed. The generator function yields 'Just' the+-- next element and the new seed or 'Nothing' if there are no more elements.+--+-- > unfoldrN 3 (\n -> Just (n,n-1)) 10 = <10,9,8>+unfoldrN :: Unbox a => Int -> (b -> Maybe (a, b)) -> b -> Vector a+{-# INLINE unfoldrN #-}+unfoldrN = G.unfoldrN++-- Enumeration+-- -----------++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+1@+-- etc. This operation is usually more efficient than 'enumFromTo'.+--+-- > enumFromN 5 3 = <5,6,7>+enumFromN :: (Unbox a, Num a) => a -> Int -> Vector a+{-# INLINE enumFromN #-}+enumFromN = G.enumFromN++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,+-- @x+y+y@ etc. This operations is usually more efficient than 'enumFromThenTo'.+--+-- > enumFromStepN 1 0.1 5 = <1,1.1,1.2,1.3,1.4>+enumFromStepN :: (Unbox a, Num a) => a -> a -> Int -> Vector a+{-# INLINE enumFromStepN #-}+enumFromStepN = G.enumFromStepN++-- | /O(n)/ Enumerate values from @x@ to @y@.+--+-- /WARNING:/ This operation can be very inefficient. If at all possible, use+-- 'enumFromN' instead.+enumFromTo :: (Unbox a, Enum a) => a -> a -> Vector a+{-# INLINE enumFromTo #-}+enumFromTo = G.enumFromTo++-- | /O(n)/ Enumerate values from @x@ to @y@ with a specific step @z@.+--+-- /WARNING:/ This operation can be very inefficient. If at all possible, use+-- 'enumFromStepN' instead.+enumFromThenTo :: (Unbox a, Enum a) => a -> a -> a -> Vector a+{-# INLINE enumFromThenTo #-}+enumFromThenTo = G.enumFromThenTo++-- Concatenation+-- -------------++-- | /O(n)/ Prepend an element+cons :: Unbox a => a -> Vector a -> Vector a+{-# INLINE cons #-}+cons = G.cons++-- | /O(n)/ Append an element+snoc :: Unbox a => Vector a -> a -> Vector a+{-# INLINE snoc #-}+snoc = G.snoc++infixr 5 +++-- | /O(m+n)/ Concatenate two vectors+(++) :: Unbox a => Vector a -> Vector a -> Vector a+{-# INLINE (++) #-}+(++) = (G.++)++-- Monadic initialisation+-- ----------------------++-- | /O(n)/ Execute the monadic action the given number of times and store the+-- results in a vector.+replicateM :: (Monad m, Unbox a) => Int -> m a -> m (Vector a)+{-# INLINE replicateM #-}+replicateM = G.replicateM++-- | Execute the monadic action and freeze the resulting vector.+--+-- @+-- create (do { v \<- new 2; write v 0 \'a\'; write v 1 \'b\' }) = \<'a','b'\>+-- @+create :: Unbox a => (forall s. ST s (MVector s a)) -> Vector a+{-# INLINE create #-}+create = G.create++-- Restricting memory usage+-- ------------------------++-- | /O(n)/ Yield the argument but force it not to retain any extra memory,+-- possibly by copying it.+--+-- This is especially useful when dealing with slices. For example:+--+-- > force (slice 0 2 <huge vector>)+--+-- Here, the slice retains a reference to the huge vector. Forcing it creates+-- a copy of just the elements that belong to the slice and allows the huge+-- vector to be garbage collected.+force :: Unbox a => Vector a -> Vector a+{-# INLINE force #-}+force = G.force++-- Bulk updates+-- ------------++-- | /O(m+n)/ For each pair @(i,a)@ from the list, replace the vector+-- element at position @i@ by @a@.+--+-- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7>+--+(//) :: Unbox a => Vector a -- ^ initial vector (of length @m@)+ -> [(Int, a)] -- ^ list of index/value pairs (of length @n@) + -> Vector a+{-# INLINE (//) #-}+(//) = (G.//)++-- | /O(m+n)/ For each pair @(i,a)@ from the vector of index/value pairs,+-- replace the vector element at position @i@ by @a@.+--+-- > update <5,9,2,7> <(2,1),(0,3),(2,8)> = <3,9,8,7>+--+update :: Unbox a+ => Vector a -- ^ initial vector (of length @m@)+ -> Vector (Int, a) -- ^ vector of index/value pairs (of length @n@)+ -> Vector a+{-# INLINE update #-}+update = G.update++-- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the+-- corresponding value @a@ from the value vector, replace the element of the+-- initial vector at position @i@ by @a@.+--+-- > update_ <5,9,2,7> <2,0,2> <1,3,8> = <3,9,8,7>+--+-- The function 'update' provides the same functionality and is usually more+-- convenient.+--+-- @+-- update_ xs is ys = 'update' xs ('zip' is ys)+-- @+update_ :: Unbox a+ => Vector a -- ^ initial vector (of length @m@)+ -> Vector Int -- ^ index vector (of length @n1@)+ -> Vector a -- ^ value vector (of length @n2@)+ -> Vector a+{-# INLINE update_ #-}+update_ = G.update_++-- | Same as ('//') but without bounds checking. unsafeUpd :: Unbox a => Vector a -> [(Int, a)] -> Vector a {-# INLINE unsafeUpd #-} unsafeUpd = G.unsafeUpd +-- | Same as 'update' but without bounds checking. unsafeUpdate :: Unbox a => Vector a -> Vector (Int, a) -> Vector a {-# INLINE unsafeUpdate #-} unsafeUpdate = G.unsafeUpdate +-- | Same as 'update_' but without bounds checking. unsafeUpdate_ :: Unbox a => Vector a -> Vector Int -> Vector a -> Vector a {-# INLINE unsafeUpdate_ #-} unsafeUpdate_ = G.unsafeUpdate_ -(//) :: Unbox a => Vector a -> [(Int, a)] -> Vector a-{-# INLINE (//) #-}-(//) = (G.//)+-- Accumulations+-- ------------- -update :: Unbox a => Vector a -> Vector (Int, a) -> Vector a-{-# INLINE update #-}-update = G.update+-- | /O(m+n)/ For each pair @(i,b)@ from the list, replace the vector element+-- @a@ at position @i@ by @f a b@.+--+-- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4>+accum :: Unbox a+ => (a -> b -> a) -- ^ accumulating function @f@+ -> Vector a -- ^ initial vector (of length @m@)+ -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)+ -> Vector a+{-# INLINE accum #-}+accum = G.accum -update_ :: Unbox a => Vector a -> Vector Int -> Vector a -> Vector a-{-# INLINE update_ #-}-update_ = G.update_+-- | /O(m+n)/ For each pair @(i,b)@ from the vector of pairs, replace the vector+-- element @a@ at position @i@ by @f a b@.+--+-- > accumulate (+) <5,9,2> <(2,4),(1,6),(0,3),(1,7)> = <5+3, 9+6+7, 2+4>+accumulate :: (Unbox a, Unbox b)+ => (a -> b -> a) -- ^ accumulating function @f@+ -> Vector a -- ^ initial vector (of length @m@)+ -> Vector (Int,b) -- ^ vector of index/value pairs (of length @n@)+ -> Vector a+{-# INLINE accumulate #-}+accumulate = G.accumulate +-- | /O(m+min(n1,n2))/ For each index @i@ from the index vector and the+-- corresponding value @b@ from the the value vector,+-- replace the element of the initial vector at+-- position @i@ by @f a b@.+--+-- > accumulate_ (+) <5,9,2> <2,1,0,1> <4,6,3,7> = <5+3, 9+6+7, 2+4>+--+-- The function 'accumulate' provides the same functionality and is usually more+-- convenient.+--+-- @+-- accumulate_ f as is bs = 'accumulate' f as ('zip' is bs)+-- @+accumulate_ :: (Unbox a, Unbox b)+ => (a -> b -> a) -- ^ accumulating function @f@+ -> Vector a -- ^ initial vector (of length @m@)+ -> Vector Int -- ^ index vector (of length @n1@)+ -> Vector b -- ^ value vector (of length @n2@)+ -> Vector a+{-# INLINE accumulate_ #-}+accumulate_ = G.accumulate_++-- | Same as 'accum' but without bounds checking.+unsafeAccum :: Unbox a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a+{-# INLINE unsafeAccum #-}+unsafeAccum = G.unsafeAccum++-- | Same as 'accumulate' but without bounds checking.+unsafeAccumulate :: (Unbox a, Unbox b)+ => (a -> b -> a) -> Vector a -> Vector (Int,b) -> Vector a+{-# INLINE unsafeAccumulate #-}+unsafeAccumulate = G.unsafeAccumulate++-- | Same as 'accumulate_' but without bounds checking.+unsafeAccumulate_ :: (Unbox a, Unbox b) =>+ (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a+{-# INLINE unsafeAccumulate_ #-}+unsafeAccumulate_ = G.unsafeAccumulate_++-- Permutations+-- ------------++-- | /O(n)/ Reverse a vector+reverse :: Unbox a => Vector a -> Vector a+{-# INLINE reverse #-}+reverse = G.reverse++-- | /O(n)/ Yield the vector obtained by replacing each element @i@ of the+-- index vector by @xs'!'i@. This is equivalent to @'map' (xs'!') is@ but is+-- often much more efficient.+--+-- > backpermute <a,b,c,d> <0,3,2,3,1,0> = <a,d,c,d,b,a> backpermute :: Unbox a => Vector a -> Vector Int -> Vector a {-# INLINE backpermute #-} backpermute = G.backpermute +-- | Same as 'backpermute' but without bounds checking. unsafeBackpermute :: Unbox a => Vector a -> Vector Int -> Vector a {-# INLINE unsafeBackpermute #-} unsafeBackpermute = G.unsafeBackpermute -reverse :: Unbox a => Vector a -> Vector a-{-# INLINE reverse #-}-reverse = G.reverse+-- Safe destructive updates+-- ------------------------ +-- | Apply a destructive operation to a vector. The operation will be+-- performed in place if it is safe to do so and will modify a copy of the+-- vector otherwise.+--+-- @+-- modify (\\v -> write v 0 \'x\') ('replicate' 3 \'a\') = \<\'x\',\'a\',\'a\'\>+-- @+modify :: Unbox a => (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a+{-# INLINE modify #-}+modify = G.modify+ -- Mapping -- ------- --- | Map a function over a vector+-- | /O(n)/ Map a function over a vector map :: (Unbox a, Unbox b) => (a -> b) -> Vector a -> Vector b {-# INLINE map #-} map = G.map --- | Apply a function to every index/value pair+-- | /O(n)/ Apply a function to every element of a vector and its index imap :: (Unbox a, Unbox b) => (Int -> a -> b) -> Vector a -> Vector b {-# INLINE imap #-} imap = G.imap +-- | Map a function over a vector and concatenate the results. concatMap :: (Unbox a, Unbox b) => (a -> Vector b) -> Vector a -> Vector b {-# INLINE concatMap #-} concatMap = G.concatMap --- Zipping/unzipping--- -----------------+-- Monadic mapping+-- --------------- --- | Zip two vectors with the given function.+-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a+-- vector of results+mapM :: (Monad m, Unbox a, Unbox b) => (a -> m b) -> Vector a -> m (Vector b)+{-# INLINE mapM #-}+mapM = G.mapM++-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the+-- results+mapM_ :: (Monad m, Unbox a) => (a -> m b) -> Vector a -> m ()+{-# INLINE mapM_ #-}+mapM_ = G.mapM_++-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a+-- vector of results. Equvalent to @flip 'mapM'@.+forM :: (Monad m, Unbox a, Unbox b) => Vector a -> (a -> m b) -> m (Vector b)+{-# INLINE forM #-}+forM = G.forM++-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the+-- results. Equivalent to @flip 'mapM_'@.+forM_ :: (Monad m, Unbox a) => Vector a -> (a -> m b) -> m ()+{-# INLINE forM_ #-}+forM_ = G.forM_++-- Zipping+-- -------++-- | /O(min(m,n))/ Zip two vectors with the given function. zipWith :: (Unbox a, Unbox b, Unbox c) => (a -> b -> c) -> Vector a -> Vector b -> Vector c {-# INLINE zipWith #-}@@ -435,7 +754,8 @@ {-# INLINE zipWith6 #-} zipWith6 = G.zipWith6 --- | Zip two vectors and their indices with the given function.+-- | /O(min(m,n))/ Zip two vectors with a function that also takes the+-- elements' indices. izipWith :: (Unbox a, Unbox b, Unbox c) => (Int -> a -> b -> c) -> Vector a -> Vector b -> Vector c {-# INLINE izipWith #-}@@ -468,53 +788,81 @@ {-# INLINE izipWith6 #-} izipWith6 = G.izipWith6 +-- Monadic zipping+-- ---------------++-- | /O(min(m,n))/ Zip the two vectors with the monadic action and yield a+-- vector of results+zipWithM :: (Monad m, Unbox a, Unbox b, Unbox c)+ => (a -> b -> m c) -> Vector a -> Vector b -> m (Vector c)+{-# INLINE zipWithM #-}+zipWithM = G.zipWithM++-- | /O(min(m,n))/ Zip the two vectors with the monadic action and ignore the+-- results+zipWithM_ :: (Monad m, Unbox a, Unbox b)+ => (a -> b -> m c) -> Vector a -> Vector b -> m ()+{-# INLINE zipWithM_ #-}+zipWithM_ = G.zipWithM_+ -- Filtering -- --------- --- | Drop elements which do not satisfy the predicate+-- | /O(n)/ Drop elements that do not satisfy the predicate filter :: Unbox a => (a -> Bool) -> Vector a -> Vector a {-# INLINE filter #-} filter = G.filter --- | Drop elements that do not satisfy the predicate (applied to values and--- their indices)+-- | /O(n)/ Drop elements that do not satisfy the predicate which is applied to+-- values and their indices ifilter :: Unbox a => (Int -> a -> Bool) -> Vector a -> Vector a {-# INLINE ifilter #-} ifilter = G.ifilter --- | Yield the longest prefix of elements satisfying the predicate.+-- | /O(n)/ Drop elements that do not satisfy the monadic predicate+filterM :: (Monad m, Unbox a) => (a -> m Bool) -> Vector a -> m (Vector a)+{-# INLINE filterM #-}+filterM = G.filterM++-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate+-- without copying. takeWhile :: Unbox a => (a -> Bool) -> Vector a -> Vector a {-# INLINE takeWhile #-} takeWhile = G.takeWhile --- | Drop the longest prefix of elements that satisfy the predicate.+-- | /O(n)/ Drop the longest prefix of elements that satisfy the predicate+-- without copying. dropWhile :: Unbox a => (a -> Bool) -> Vector a -> Vector a {-# INLINE dropWhile #-} dropWhile = G.dropWhile --- | Split the vector in two parts, the first one containing those elements--- that satisfy the predicate and the second one those that don't. The--- relative order of the elements is preserved at the cost of a (sometimes)+-- Parititioning+-- -------------++-- | /O(n)/ Split the vector in two parts, the first one containing those+-- elements that satisfy the predicate and the second one those that don't. The+-- relative order of the elements is preserved at the cost of a sometimes -- reduced performance compared to 'unstablePartition'. partition :: Unbox a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE partition #-} partition = G.partition --- | Split the vector in two parts, the first one containing those elements--- that satisfy the predicate and the second one those that don't. The order--- of the elements is not preserved.+-- | /O(n)/ Split the vector in two parts, the first one containing those+-- elements that satisfy the predicate and the second one those that don't.+-- The order of the elements is not preserved but the operation is often+-- faster than 'partition'. unstablePartition :: Unbox a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE unstablePartition #-} unstablePartition = G.unstablePartition --- | Split the vector into the longest prefix of elements that satisfy the--- predicate and the rest.+-- | /O(n)/ Split the vector into the longest prefix of elements that satisfy+-- the predicate and the rest without copying. span :: Unbox a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE span #-} span = G.span --- | Split the vector into the longest prefix of elements that do not satisfy--- the predicate and the rest.+-- | /O(n)/ Split the vector into the longest prefix of elements that do not+-- satisfy the predicate and the rest without copying. break :: Unbox a => (a -> Bool) -> Vector a -> (Vector a, Vector a) {-# INLINE break #-} break = G.break@@ -523,41 +871,44 @@ -- --------- infix 4 `elem`--- | Check whether the vector contains an element+-- | /O(n)/ Check if the vector contains an element elem :: (Unbox a, Eq a) => a -> Vector a -> Bool {-# INLINE elem #-} elem = G.elem infix 4 `notElem`--- | Inverse of `elem`+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem') notElem :: (Unbox a, Eq a) => a -> Vector a -> Bool {-# INLINE notElem #-} notElem = G.notElem --- | Yield 'Just' the first element matching the predicate or 'Nothing' if no--- such element exists.+-- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing'+-- if no such element exists. find :: Unbox a => (a -> Bool) -> Vector a -> Maybe a {-# INLINE find #-} find = G.find --- | Yield 'Just' the index of the first element matching the predicate or--- 'Nothing' if no such element exists.+-- | /O(n)/ Yield 'Just' the index of the first element matching the predicate+-- or 'Nothing' if no such element exists. findIndex :: Unbox a => (a -> Bool) -> Vector a -> Maybe Int {-# INLINE findIndex #-} findIndex = G.findIndex --- | Yield the indices of elements satisfying the predicate+-- | /O(n)/ Yield the indices of elements satisfying the predicate in ascending+-- order. findIndices :: Unbox a => (a -> Bool) -> Vector a -> Vector Int {-# INLINE findIndices #-} findIndices = G.findIndices --- | Yield 'Just' the index of the first occurence of the given element or--- 'Nothing' if the vector does not contain the element+-- | /O(n)/ Yield 'Just' the index of the first occurence of the given element or+-- 'Nothing' if the vector does not contain the element. This is a specialised+-- version of 'findIndex'. elemIndex :: (Unbox a, Eq a) => a -> Vector a -> Maybe Int {-# INLINE elemIndex #-} elemIndex = G.elemIndex --- | Yield the indices of all occurences of the given element+-- | /O(n)/ Yield the indices of all occurences of the given element in+-- ascending order. This is a specialised version of 'findIndices'. elemIndices :: (Unbox a, Eq a) => a -> Vector a -> Vector Int {-# INLINE elemIndices #-} elemIndices = G.elemIndices@@ -565,64 +916,64 @@ -- Folding -- ------- --- | Left fold+-- | /O(n)/ Left fold foldl :: Unbox b => (a -> b -> a) -> a -> Vector b -> a {-# INLINE foldl #-} foldl = G.foldl --- | Lefgt fold on non-empty vectors+-- | /O(n)/ Left fold on non-empty vectors foldl1 :: Unbox a => (a -> a -> a) -> Vector a -> a {-# INLINE foldl1 #-} foldl1 = G.foldl1 --- | Left fold with strict accumulator+-- | /O(n)/ Left fold with strict accumulator foldl' :: Unbox b => (a -> b -> a) -> a -> Vector b -> a {-# INLINE foldl' #-} foldl' = G.foldl' --- | Left fold on non-empty vectors with strict accumulator+-- | /O(n)/ Left fold on non-empty vectors with strict accumulator foldl1' :: Unbox a => (a -> a -> a) -> Vector a -> a {-# INLINE foldl1' #-} foldl1' = G.foldl1' --- | Right fold+-- | /O(n)/ Right fold foldr :: Unbox a => (a -> b -> b) -> b -> Vector a -> b {-# INLINE foldr #-} foldr = G.foldr --- | Right fold on non-empty vectors+-- | /O(n)/ Right fold on non-empty vectors foldr1 :: Unbox a => (a -> a -> a) -> Vector a -> a {-# INLINE foldr1 #-} foldr1 = G.foldr1 --- | Right fold with a strict accumulator+-- | /O(n)/ Right fold with a strict accumulator foldr' :: Unbox a => (a -> b -> b) -> b -> Vector a -> b {-# INLINE foldr' #-} foldr' = G.foldr' --- | Right fold on non-empty vectors with strict accumulator+-- | /O(n)/ Right fold on non-empty vectors with strict accumulator foldr1' :: Unbox a => (a -> a -> a) -> Vector a -> a {-# INLINE foldr1' #-} foldr1' = G.foldr1' --- | Left fold (function applied to each element and its index)+-- | /O(n)/ Left fold (function applied to each element and its index) ifoldl :: Unbox b => (a -> Int -> b -> a) -> a -> Vector b -> a {-# INLINE ifoldl #-} ifoldl = G.ifoldl --- | Left fold with strict accumulator (function applied to each element and--- its index)+-- | /O(n)/ Left fold with strict accumulator (function applied to each element+-- and its index) ifoldl' :: Unbox b => (a -> Int -> b -> a) -> a -> Vector b -> a {-# INLINE ifoldl' #-} ifoldl' = G.ifoldl' --- | Right fold (function applied to each element and its index)+-- | /O(n)/ Right fold (function applied to each element and its index) ifoldr :: Unbox a => (Int -> a -> b -> b) -> b -> Vector a -> b {-# INLINE ifoldr #-} ifoldr = G.ifoldr --- | Right fold with strict accumulator (function applied to each element and--- its index)+-- | /O(n)/ Right fold with strict accumulator (function applied to each+-- element and its index) ifoldr' :: Unbox a => (Int -> a -> b -> b) -> b -> Vector a -> b {-# INLINE ifoldr' #-} ifoldr' = G.ifoldr'@@ -630,315 +981,256 @@ -- Specialised folds -- ----------------- +-- | /O(n)/ Check if all elements satisfy the predicate. all :: Unbox a => (a -> Bool) -> Vector a -> Bool {-# INLINE all #-} all = G.all +-- | /O(n)/ Check if any element satisfies the predicate. any :: Unbox a => (a -> Bool) -> Vector a -> Bool {-# INLINE any #-} any = G.any +-- | /O(n)/ Check if all elements are 'True' and :: Vector Bool -> Bool {-# INLINE and #-} and = G.and +-- | /O(n)/ Check if any element is 'True' or :: Vector Bool -> Bool {-# INLINE or #-} or = G.or +-- | /O(n)/ Compute the sum of the elements sum :: (Unbox a, Num a) => Vector a -> a {-# INLINE sum #-} sum = G.sum +-- | /O(n)/ Compute the produce of the elements product :: (Unbox a, Num a) => Vector a -> a {-# INLINE product #-} product = G.product +-- | /O(n)/ Yield the maximum element of the vector. The vector may not be+-- empty. maximum :: (Unbox a, Ord a) => Vector a -> a {-# INLINE maximum #-} maximum = G.maximum +-- | /O(n)/ Yield the maximum element of the vector according to the given+-- comparison function. The vector may not be empty. maximumBy :: Unbox a => (a -> a -> Ordering) -> Vector a -> a {-# INLINE maximumBy #-} maximumBy = G.maximumBy +-- | /O(n)/ Yield the minimum element of the vector. The vector may not be+-- empty. minimum :: (Unbox a, Ord a) => Vector a -> a {-# INLINE minimum #-} minimum = G.minimum +-- | /O(n)/ Yield the minimum element of the vector according to the given+-- comparison function. The vector may not be empty. minimumBy :: Unbox a => (a -> a -> Ordering) -> Vector a -> a {-# INLINE minimumBy #-} minimumBy = G.minimumBy +-- | /O(n)/ Yield the index of the maximum element of the vector. The vector+-- may not be empty. maxIndex :: (Unbox a, Ord a) => Vector a -> Int {-# INLINE maxIndex #-} maxIndex = G.maxIndex +-- | /O(n)/ Yield the index of the maximum element of the vector according to+-- the given comparison function. The vector may not be empty. maxIndexBy :: Unbox a => (a -> a -> Ordering) -> Vector a -> Int {-# INLINE maxIndexBy #-} maxIndexBy = G.maxIndexBy +-- | /O(n)/ Yield the index of the minimum element of the vector. The vector+-- may not be empty. minIndex :: (Unbox a, Ord a) => Vector a -> Int {-# INLINE minIndex #-} minIndex = G.minIndex +-- | /O(n)/ Yield the index of the minimum element of the vector according to+-- the given comparison function. The vector may not be empty. minIndexBy :: Unbox a => (a -> a -> Ordering) -> Vector a -> Int {-# INLINE minIndexBy #-} minIndexBy = G.minIndexBy --- Unfolding--- ---------+-- Monadic folds+-- ------------- --- | The 'unfoldr' function is a \`dual\' to 'foldr': while 'foldr'--- reduces a vector to a summary value, 'unfoldr' builds a list from--- a seed value. The function takes the element and returns 'Nothing'--- if it is done generating the vector or returns 'Just' @(a,b)@, in which--- case, @a@ is a prepended to the vector and @b@ is used as the next--- element in a recursive call.------ A simple use of unfoldr:------ > unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10--- > [10,9,8,7,6,5,4,3,2,1]----unfoldr :: Unbox a => (b -> Maybe (a, b)) -> b -> Vector a-{-# INLINE unfoldr #-}-unfoldr = G.unfoldr+-- | /O(n)/ Monadic fold+foldM :: (Monad m, Unbox b) => (a -> b -> m a) -> a -> Vector b -> m a+{-# INLINE foldM #-}+foldM = G.foldM --- | Unfold at most @n@ elements-unfoldrN :: Unbox a => Int -> (b -> Maybe (a, b)) -> b -> Vector a-{-# INLINE unfoldrN #-}-unfoldrN = G.unfoldrN+-- | /O(n)/ Monadic fold over non-empty vectors+fold1M :: (Monad m, Unbox a) => (a -> a -> m a) -> Vector a -> m a+{-# INLINE fold1M #-}+fold1M = G.fold1M --- Scans--- -----+-- | /O(n)/ Monadic fold with strict accumulator+foldM' :: (Monad m, Unbox b) => (a -> b -> m a) -> a -> Vector b -> m a+{-# INLINE foldM' #-}+foldM' = G.foldM' --- | Prefix scan+-- | /O(n)/ Monad fold over non-empty vectors with strict accumulator+fold1M' :: (Monad m, Unbox a) => (a -> a -> m a) -> Vector a -> m a+{-# INLINE fold1M' #-}+fold1M' = G.fold1M'++-- Prefix sums (scans)+-- -------------------++-- | /O(n)/ Prescan+--+-- @+-- prescanl f z = 'init' . 'scanl' f z+-- @+--+-- Example: @prescanl (+) 0 \<1,2,3,4\> = \<0,1,3,6\>@+-- prescanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE prescanl #-} prescanl = G.prescanl --- | Prefix scan with strict accumulator+-- | /O(n)/ Prescan with strict accumulator prescanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE prescanl' #-} prescanl' = G.prescanl' --- | Suffix scan+-- | /O(n)/ Scan+--+-- @+-- postscanl f z = 'tail' . 'scanl' f z+-- @+--+-- Example: @postscanl (+) 0 \<1,2,3,4\> = \<1,3,6,10\>@+-- postscanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE postscanl #-} postscanl = G.postscanl --- | Suffix scan with strict accumulator+-- | /O(n)/ Scan with strict accumulator postscanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE postscanl' #-} postscanl' = G.postscanl' --- | Haskell-style scan+-- | /O(n)/ Haskell-style scan+--+-- > scanl f z <x1,...,xn> = <y1,...,y(n+1)>+-- > where y1 = z+-- > yi = f y(i-1) x(i-1)+--+-- Example: @scanl (+) 0 \<1,2,3,4\> = \<0,1,3,6,10\>@+-- scanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE scanl #-} scanl = G.scanl --- | Haskell-style scan with strict accumulator+-- | /O(n)/ Haskell-style scan with strict accumulator scanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE scanl' #-} scanl' = G.scanl' --- | Scan over a non-empty 'Vector'+-- | /O(n)/ Scan over a non-empty vector+--+-- > scanl f <x1,...,xn> = <y1,...,yn>+-- > where y1 = x1+-- > yi = f y(i-1) xi+-- scanl1 :: Unbox a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanl1 #-} scanl1 = G.scanl1 --- | Scan over a non-empty 'Vector' with a strict accumulator+-- | /O(n)/ Scan over a non-empty vector with a strict accumulator scanl1' :: Unbox a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanl1' #-} scanl1' = G.scanl1' ---- | Prefix right-to-left scan+-- | /O(n)/ Right-to-left prescan+--+-- @+-- prescanr f z = 'reverse' . 'prescanl' (flip f) z . 'reverse'+-- @+-- prescanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE prescanr #-} prescanr = G.prescanr --- | Prefix right-to-left scan with strict accumulator+-- | /O(n)/ Right-to-left prescan with strict accumulator prescanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE prescanr' #-} prescanr' = G.prescanr' --- | Suffix right-to-left scan+-- | /O(n)/ Right-to-left scan postscanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE postscanr #-} postscanr = G.postscanr --- | Suffix right-to-left scan with strict accumulator+-- | /O(n)/ Right-to-left scan with strict accumulator postscanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE postscanr' #-} postscanr' = G.postscanr' --- | Haskell-style right-to-left scan+-- | /O(n)/ Right-to-left Haskell-style scan scanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE scanr #-} scanr = G.scanr --- | Haskell-style right-to-left scan with strict accumulator+-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator scanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE scanr' #-} scanr' = G.scanr' --- | Right-to-left scan over a non-empty vector+-- | /O(n)/ Right-to-left scan over a non-empty vector scanr1 :: Unbox a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanr1 #-} scanr1 = G.scanr1 --- | Right-to-left scan over a non-empty vector with a strict accumulator+-- | /O(n)/ Right-to-left scan over a non-empty vector with a strict+-- accumulator scanr1' :: Unbox a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanr1' #-} scanr1' = G.scanr1' --- Enumeration--- --------------- | Yield a vector of the given length containing the values @x@, @x+1@ etc.--- This operation is usually more efficient than 'enumFromTo'.-enumFromN :: (Unbox a, Num a) => a -> Int -> Vector a-{-# INLINE enumFromN #-}-enumFromN = G.enumFromN---- | Yield a vector of the given length containing the values @x@, @x+y@,--- @x+y+y@ etc. This operations is usually more efficient than--- 'enumFromThenTo'.-enumFromStepN :: (Unbox a, Num a) => a -> a -> Int -> Vector a-{-# INLINE enumFromStepN #-}-enumFromStepN = G.enumFromStepN---- | Enumerate values from @x@ to @y@.------ /WARNING:/ This operation can be very inefficient. If at all possible, use--- 'enumFromN' instead.-enumFromTo :: (Unbox a, Enum a) => a -> a -> Vector a-{-# INLINE enumFromTo #-}-enumFromTo = G.enumFromTo---- | Enumerate values from @x@ to @y@ with a specific step @z@.------ /WARNING:/ This operation can be very inefficient. If at all possible, use--- 'enumFromStepN' instead.-enumFromThenTo :: (Unbox a, Enum a) => a -> a -> a -> Vector a-{-# INLINE enumFromThenTo #-}-enumFromThenTo = G.enumFromThenTo---- Conversion to/from lists+-- Conversions - Lists -- ------------------------ --- | Convert a vector to a list+-- | /O(n)/ Convert a vector to a list toList :: Unbox a => Vector a -> [a] {-# INLINE toList #-} toList = G.toList --- | Convert a list to a vector+-- | /O(n)/ Convert a list to a vector fromList :: Unbox a => [a] -> Vector a {-# INLINE fromList #-} fromList = G.fromList --- | Convert the first @n@ elements of a list to a vector+-- | /O(n)/ Convert the first @n@ elements of a list to a vector ----- > fromListN n xs = fromList (take n xs)+-- @+-- fromListN n xs = 'fromList' ('take' n xs)+-- @ fromListN :: Unbox a => Int -> [a] -> Vector a {-# INLINE fromListN #-} fromListN = G.fromListN --- Monadic operations--- ---------------------- | Perform the monadic action the given number of times and store the--- results in a vector.-replicateM :: (Monad m, Unbox a) => Int -> m a -> m (Vector a)-{-# INLINE replicateM #-}-replicateM = G.replicateM---- | Apply the monadic action to all elements of the vector, yielding a vector--- of results-mapM :: (Monad m, Unbox a, Unbox b) => (a -> m b) -> Vector a -> m (Vector b)-{-# INLINE mapM #-}-mapM = G.mapM---- | Apply the monadic action to all elements of a vector and ignore the--- results-mapM_ :: (Monad m, Unbox a) => (a -> m b) -> Vector a -> m ()-{-# INLINE mapM_ #-}-mapM_ = G.mapM_---- | Apply the monadic action to all elements of the vector, yielding a vector--- of results-forM :: (Monad m, Unbox a, Unbox b) => Vector a -> (a -> m b) -> m (Vector b)-{-# INLINE forM #-}-forM = G.forM---- | Apply the monadic action to all elements of a vector and ignore the--- results-forM_ :: (Monad m, Unbox a) => Vector a -> (a -> m b) -> m ()-{-# INLINE forM_ #-}-forM_ = G.forM_---- | Zip the two vectors with the monadic action and yield a vector of results-zipWithM :: (Monad m, Unbox a, Unbox b, Unbox c)- => (a -> b -> m c) -> Vector a -> Vector b -> m (Vector c)-{-# INLINE zipWithM #-}-zipWithM = G.zipWithM---- | Zip the two vectors with the monadic action and ignore the results-zipWithM_ :: (Monad m, Unbox a, Unbox b)- => (a -> b -> m c) -> Vector a -> Vector b -> m ()-{-# INLINE zipWithM_ #-}-zipWithM_ = G.zipWithM_---- | Drop elements that do not satisfy the monadic predicate-filterM :: (Monad m, Unbox a) => (a -> m Bool) -> Vector a -> m (Vector a)-{-# INLINE filterM #-}-filterM = G.filterM---- | Monadic fold-foldM :: (Monad m, Unbox b) => (a -> b -> m a) -> a -> Vector b -> m a-{-# INLINE foldM #-}-foldM = G.foldM---- | Monadic fold over non-empty vectors-fold1M :: (Monad m, Unbox a) => (a -> a -> m a) -> Vector a -> m a-{-# INLINE fold1M #-}-fold1M = G.fold1M---- | Monadic fold with strict accumulator-foldM' :: (Monad m, Unbox b) => (a -> b -> m a) -> a -> Vector b -> m a-{-# INLINE foldM' #-}-foldM' = G.foldM'---- | Monad fold over non-empty vectors with strict accumulator-fold1M' :: (Monad m, Unbox a) => (a -> a -> m a) -> Vector a -> m a-{-# INLINE fold1M' #-}-fold1M' = G.fold1M'---- Destructive operations--- -------------------------- | Destructively initialise a vector.-create :: Unbox a => (forall s. ST s (MVector s a)) -> Vector a-{-# INLINE create #-}-create = G.create---- | Apply a destructive operation to a vector. The operation is applied to a--- copy of the vector unless it can be safely performed in place.-modify :: Unbox a => (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a-{-# INLINE modify #-}-modify = G.modify+-- Conversions - Mutable vectors+-- ----------------------------- --- | Copy an immutable vector into a mutable one. The two vectors must have--- the same length. This is not checked.+-- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must+-- have the same length. unsafeCopy :: (Unbox a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE unsafeCopy #-} unsafeCopy = G.unsafeCopy --- | Copy an immutable vector into a mutable one. The two vectors must have the--- same length.+-- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must+-- have the same length. This is not checked. copy :: (Unbox a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE copy #-} copy = G.copy
Data/Vector/Unboxed/Base.hs view
@@ -1,4 +1,6 @@ {-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-}+{-# OPTIONS_HADDOCK hide #-}+ -- | -- Module : Data.Vector.Unboxed.Base -- Copyright : (c) Roman Leshchinskiy 2009-2010
benchmarks/vector-benchmarks.cabal view
@@ -1,5 +1,5 @@ Name: vector-benchmarks-Version: 0.6+Version: 0.6.0.1 License: BSD3 License-File: LICENSE Author: Roman Leshchinskiy <rl@cse.unsw.edu.au>@@ -14,7 +14,7 @@ Build-Depends: base >= 2 && < 5, array, criterion >= 0.5 && < 0.6, mwc-random >= 0.5 && < 0.6,- vector >= 0.6 && < 0.7+ vector == 0.6.0.1 if impl(ghc<6.13) Ghc-Options: -finline-if-enough-args -fno-method-sharing
internal/GenUnboxTuple.hs view
@@ -52,7 +52,8 @@ define_zip ty c- = sep [name <+> text "::"+ = sep [text "-- | /O(1)/ Zip" <+> int n <+> text "vectors"+ ,name <+> text "::" <+> vtuple [text "Unbox" <+> v | v <- vars] <+> text "=>" <+> sep (punctuate (text " ->") [text ty <+> v | v <- vars])@@ -92,7 +93,8 @@ define_unzip ty c- = sep [name <+> text "::"+ = sep [text "-- | /O(1)/ Unzip" <+> int n <+> text "vectors"+ ,name <+> text "::" <+> vtuple [text "Unbox" <+> v | v <- vars] <+> text "=>" <+> text ty <+> tuple vars
internal/unbox-tuple-instances view
@@ -91,17 +91,20 @@ . G.elemseq (undefined :: Vector b) b #endif #ifdef DEFINE_MUTABLE+-- | /O(1)/ Zip 2 vectors zip :: (Unbox a, Unbox b) => MVector s a -> MVector s b -> MVector s (a, b) {-# INLINE_STREAM zip #-} zip as bs = MV_2 len (unsafeSlice 0 len as) (unsafeSlice 0 len bs) where len = length as `min` length bs+-- | /O(1)/ Unzip 2 vectors unzip :: (Unbox a, Unbox b) => MVector s (a, b) -> (MVector s a, MVector s b) {-# INLINE unzip #-} unzip (MV_2 n_ as bs) = (as, bs) #endif #ifdef DEFINE_IMMUTABLE+-- | /O(1)/ Zip 2 vectors zip :: (Unbox a, Unbox b) => Vector a -> Vector b -> Vector (a, b) {-# INLINE_STREAM zip #-} zip as bs = V_2 len (unsafeSlice 0 len as) (unsafeSlice 0 len bs)@@ -110,6 +113,7 @@ G.stream (zip as bs) = Stream.zipWith (,) (G.stream as) (G.stream bs) #-}+-- | /O(1)/ Unzip 2 vectors unzip :: (Unbox a, Unbox b) => Vector (a, b) -> (Vector a, Vector b) {-# INLINE unzip #-}@@ -229,6 +233,7 @@ . G.elemseq (undefined :: Vector c) c #endif #ifdef DEFINE_MUTABLE+-- | /O(1)/ Zip 3 vectors zip3 :: (Unbox a, Unbox b, Unbox c) => MVector s a -> MVector s b -> MVector s c -> MVector s (a, b, c)@@ -237,6 +242,7 @@ (unsafeSlice 0 len bs) (unsafeSlice 0 len cs) where len = length as `min` length bs `min` length cs+-- | /O(1)/ Unzip 3 vectors unzip3 :: (Unbox a, Unbox b, Unbox c) => MVector s (a, b, c) -> (MVector s a,@@ -246,6 +252,7 @@ unzip3 (MV_3 n_ as bs cs) = (as, bs, cs) #endif #ifdef DEFINE_IMMUTABLE+-- | /O(1)/ Zip 3 vectors zip3 :: (Unbox a, Unbox b, Unbox c) => Vector a -> Vector b -> Vector c -> Vector (a, b, c)@@ -259,6 +266,7 @@ (G.stream bs) (G.stream cs) #-}+-- | /O(1)/ Unzip 3 vectors unzip3 :: (Unbox a, Unbox b, Unbox c) => Vector (a, b, c) -> (Vector a, Vector b, Vector c)@@ -404,6 +412,7 @@ . G.elemseq (undefined :: Vector d) d #endif #ifdef DEFINE_MUTABLE+-- | /O(1)/ Zip 4 vectors zip4 :: (Unbox a, Unbox b, Unbox c, Unbox d) => MVector s a -> MVector s b -> MVector s c ->@@ -415,6 +424,7 @@ (unsafeSlice 0 len ds) where len = length as `min` length bs `min` length cs `min` length ds+-- | /O(1)/ Unzip 4 vectors unzip4 :: (Unbox a, Unbox b, Unbox c,@@ -426,6 +436,7 @@ unzip4 (MV_4 n_ as bs cs ds) = (as, bs, cs, ds) #endif #ifdef DEFINE_IMMUTABLE+-- | /O(1)/ Zip 4 vectors zip4 :: (Unbox a, Unbox b, Unbox c, Unbox d) => Vector a -> Vector b -> Vector c ->@@ -443,6 +454,7 @@ (G.stream cs) (G.stream ds) #-}+-- | /O(1)/ Unzip 4 vectors unzip4 :: (Unbox a, Unbox b, Unbox c,@@ -621,6 +633,7 @@ . G.elemseq (undefined :: Vector e) e #endif #ifdef DEFINE_MUTABLE+-- | /O(1)/ Zip 5 vectors zip5 :: (Unbox a, Unbox b, Unbox c,@@ -642,6 +655,7 @@ length cs `min` length ds `min` length es+-- | /O(1)/ Unzip 5 vectors unzip5 :: (Unbox a, Unbox b, Unbox c,@@ -655,6 +669,7 @@ unzip5 (MV_5 n_ as bs cs ds es) = (as, bs, cs, ds, es) #endif #ifdef DEFINE_IMMUTABLE+-- | /O(1)/ Zip 5 vectors zip5 :: (Unbox a, Unbox b, Unbox c,@@ -687,6 +702,7 @@ (G.stream ds) (G.stream es) #-}+-- | /O(1)/ Unzip 5 vectors unzip5 :: (Unbox a, Unbox b, Unbox c,@@ -890,6 +906,7 @@ . G.elemseq (undefined :: Vector f) f #endif #ifdef DEFINE_MUTABLE+-- | /O(1)/ Zip 6 vectors zip6 :: (Unbox a, Unbox b, Unbox c,@@ -915,6 +932,7 @@ length ds `min` length es `min` length fs+-- | /O(1)/ Unzip 6 vectors unzip6 :: (Unbox a, Unbox b, Unbox c,@@ -930,6 +948,7 @@ unzip6 (MV_6 n_ as bs cs ds es fs) = (as, bs, cs, ds, es, fs) #endif #ifdef DEFINE_IMMUTABLE+-- | /O(1)/ Zip 6 vectors zip6 :: (Unbox a, Unbox b, Unbox c,@@ -968,6 +987,7 @@ (G.stream es) (G.stream fs) #-}+-- | /O(1)/ Unzip 6 vectors unzip6 :: (Unbox a, Unbox b, Unbox c,
tests/vector-tests.cabal view
@@ -1,10 +1,10 @@ Name: vector-tests-Version: 0.6+Version: 0.6.0.1 License: BSD3 License-File: LICENSE Author: Max Bolingbroke, Roman Leshchinskiy Maintainer: Roman Leshchinskiy <rl@cse.unsw.edu.au>-Copyright: (c) Max Bolinbroke, Roman Leshchinskiy 2008-2009+Copyright: (c) Max Bolinbroke, Roman Leshchinskiy 2008-2010 Homepage: http://darcs.haskell.org/vector Category: Data Structures Synopsis: Efficient Arrays@@ -27,7 +27,7 @@ TypeFamilies, TemplateHaskell - Build-Depends: base >= 4 && < 5, template-haskell, vector >= 0.6 && < 0.7,+ Build-Depends: base >= 4 && < 5, template-haskell, vector == 0.6.0.1, random, QuickCheck >= 2, test-framework, test-framework-quickcheck2
vector.cabal view
@@ -1,5 +1,5 @@ Name: vector-Version: 0.6+Version: 0.6.0.1 License: BSD3 License-File: LICENSE Author: Roman Leshchinskiy <rl@cse.unsw.edu.au>@@ -38,6 +38,10 @@ . * <http://trac.haskell.org/vector> .+ Changes since version 0.6+ .+ * Improved documentation+ . Changes since version 0.5 . * More efficient representation of @Storable@ vectors@@ -82,6 +86,7 @@ benchmarks/TestData/Random.hs internal/GenUnboxTuple.hs internal/unbox-tuple-instances+ Changelog Flag BoundsChecks Description: Enable bounds checking