vector 0.12.1.2 → 0.12.2.0
raw patch · 23 files changed
+2081/−285 lines, 23 filesdep +doctestdep ~QuickCheckdep ~basedep ~ghc-primnew-uploader
Dependencies added: doctest
Dependency ranges changed: QuickCheck, base, ghc-prim, primitive
Files
- Data/Vector.hs +296/−18
- Data/Vector/Fusion/Bundle.hs +20/−12
- Data/Vector/Fusion/Bundle/Monadic.hs +44/−7
- Data/Vector/Fusion/Stream/Monadic.hs +52/−11
- Data/Vector/Generic.hs +256/−30
- Data/Vector/Generic/Base.hs +2/−1
- Data/Vector/Generic/Mutable.hs +53/−7
- Data/Vector/Generic/Mutable/Base.hs +9/−4
- Data/Vector/Mutable.hs +71/−11
- Data/Vector/Primitive.hs +320/−19
- Data/Vector/Primitive/Mutable.hs +44/−5
- Data/Vector/Storable.hs +349/−19
- Data/Vector/Storable/Mutable.hs +44/−6
- Data/Vector/Unboxed.hs +266/−18
- Data/Vector/Unboxed/Mutable.hs +44/−5
- changelog.md +19/−0
- tests/Tests/Vector/Boxed.hs +1/−0
- tests/Tests/Vector/Property.hs +85/−80
- tests/Tests/Vector/Unboxed.hs +1/−0
- tests/Tests/Vector/UnitTests.hs +52/−4
- tests/Utilities.hs +21/−20
- tests/doctests.hs +4/−0
- vector.cabal +28/−8
Data/Vector.hs view
@@ -47,7 +47,7 @@ unsafeIndexM, unsafeHeadM, unsafeLastM, -- ** Extracting subvectors (slicing)- slice, init, tail, take, drop, splitAt,+ slice, init, tail, take, drop, splitAt, uncons, unsnoc, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, -- * Construction@@ -59,8 +59,8 @@ replicateM, generateM, iterateNM, create, createT, -- ** Unfolding- unfoldr, unfoldrN,- unfoldrM, unfoldrNM,+ unfoldr, unfoldrN, unfoldrExactN,+ unfoldrM, unfoldrNM, unfoldrExactNM, constructN, constructrN, -- ** Enumeration@@ -98,6 +98,7 @@ -- ** Monadic mapping mapM, imapM, mapM_, imapM_, forM, forM_,+ iforM, iforM_, -- ** Zipping zipWith, zipWith3, zipWith4, zipWith5, zipWith6,@@ -113,9 +114,10 @@ -- * Working with predicates -- ** Filtering- filter, ifilter, uniq,+ filter, ifilter, filterM, uniq, mapMaybe, imapMaybe,- filterM,+ mapMaybeM, imapMaybeM,+ catMaybes, takeWhile, dropWhile, -- ** Partitioning@@ -127,6 +129,7 @@ -- * Folding foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1', ifoldl, ifoldl', ifoldr, ifoldr',+ foldMap, foldMap', -- ** Specialised folds all, any, and, or,@@ -152,11 +155,17 @@ scanr, scanr', scanr1, scanr1', iscanr, iscanr', + -- ** Comparisons+ eqBy, cmpBy,+ -- * Conversions -- ** Lists toList, Data.Vector.fromList, Data.Vector.fromListN, + -- ** Arrays+ fromArray, toArray,+ -- ** Other vector types G.convert, @@ -176,11 +185,12 @@ ) import Control.Monad ( MonadPlus(..), liftM, ap )-import Control.Monad.ST ( ST )+import Control.Monad.ST ( ST, runST ) import Control.Monad.Primitive import qualified Control.Monad.Fail as Fail-+import Control.Monad.Fix ( MonadFix (mfix) ) import Control.Monad.Zip+import Data.Function ( fix ) import Prelude hiding ( length, null, replicate, (++), concat,@@ -191,6 +201,9 @@ filter, takeWhile, dropWhile, span, break, elem, notElem, foldl, foldl1, foldr, foldr1,+#if __GLASGOW_HASKELL__ >= 706+ foldMap,+#endif all, any, and, or, sum, product, minimum, maximum, scanl, scanl1, scanr, scanr1, enumFromTo, enumFromThenTo,@@ -347,6 +360,11 @@ {-# INLINE fmap #-} fmap = map +#if MIN_VERSION_base(4,8,0)+ {-# INLINE (<$) #-}+ (<$) = map . const+#endif+ instance Monad Vector where {-# INLINE return #-} return = Applicative.pure@@ -381,6 +399,29 @@ {-# INLINE munzip #-} munzip = unzip +-- | Instance has same semantics as one for lists+--+-- @since 0.12.2.0+instance MonadFix Vector where+ -- We take care to dispose of v0 as soon as possible (see headM docs).+ --+ -- It's perfectly safe to use non-monadic indexing within generate+ -- call since intermediate vector won't be created until result's+ -- value is demanded.+ {-# INLINE mfix #-}+ mfix f+ | null v0 = empty+ -- We take first element of resulting vector from v0 and create+ -- rest using generate. Note that cons should fuse with generate+ | otherwise = runST $ do+ h <- headM v0+ return $ cons h $+ generate (lv0 - 1) $+ \i -> fix (\a -> f a ! (i + 1))+ where+ -- Used to calculate size of resulting vector+ v0 = fix (f . head)+ !lv0 = length v0 instance Applicative.Applicative Vector where {-# INLINE pure #-}@@ -605,10 +646,26 @@ -- -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ -- but slightly more efficient.-{-# INLINE splitAt #-}+--+-- @since 0.7.1 splitAt :: Int -> Vector a -> (Vector a, Vector a)+{-# INLINE splitAt #-} splitAt = G.splitAt +-- | /O(1)/ Yield the 'head' and 'tail' of the vector, or 'Nothing' if empty.+--+-- @since 0.12.2.0+uncons :: Vector a -> Maybe (a, Vector a)+{-# INLINE uncons #-}+uncons = G.uncons++-- | /O(1)/ Yield the 'last' and 'init' of the vector, or 'Nothing' if empty.+--+-- @since 0.12.2.0+unsnoc :: Vector a -> Maybe (Vector a, a)+{-# INLINE unsnoc #-}+unsnoc = G.unsnoc+ -- | /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@@ -666,7 +723,21 @@ {-# INLINE generate #-} generate = G.generate --- | /O(n)/ Apply function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply function \(\max(n - 1, 0)\) times to an initial value, producing a vector+-- of length \(\max(n, 0)\). Zeroth element will contain the initial value, that's why there+-- is one less function application than the number of elements in the produced vector.+--+-- \( \underbrace{x, f (x), f (f (x)), \ldots}_{\max(0,n)\rm{~elements}} \)+--+-- ===__Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.iterateN 0 undefined undefined :: V.Vector String+-- []+-- >>> V.iterateN 4 (\x -> x <> x) "Hi"+-- ["Hi","HiHi","HiHiHiHi","HiHiHiHiHiHiHiHi"]+--+-- @since 0.7.1 iterateN :: Int -> (a -> a) -> a -> Vector a {-# INLINE iterateN #-} iterateN = G.iterateN@@ -693,6 +764,17 @@ {-# INLINE unfoldrN #-} unfoldrN = G.unfoldrN +-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying+-- the generator function to a seed. The generator function yields the+-- next element and the new seed.+--+-- > unfoldrExactN 3 (\n -> (n,n-1)) 10 = <10,9,8>+--+-- @since 0.12.2.0+unfoldrExactN :: Int -> (b -> (a, b)) -> b -> Vector a+{-# INLINE unfoldrExactN #-}+unfoldrExactN = G.unfoldrExactN+ -- | /O(n)/ Construct a vector by repeatedly applying the monadic -- generator function to a seed. The generator function yields 'Just' -- the next element and the new seed or 'Nothing' if there are no more@@ -709,6 +791,15 @@ {-# INLINE unfoldrNM #-} unfoldrNM = G.unfoldrNM +-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly+-- applying the monadic generator function to a seed. The generator+-- function yields the next element and the new seed.+--+-- @since 0.12.2.0+unfoldrExactNM :: (Monad m) => Int -> (b -> m (a, b)) -> b -> m (Vector a)+{-# INLINE unfoldrExactNM #-}+unfoldrExactNM = G.unfoldrExactNM+ -- | /O(n)/ Construct a vector with @n@ elements by repeatedly applying the -- generator function to the already constructed part of the vector. --@@ -802,7 +893,13 @@ {-# INLINE generateM #-} generateM = G.generateM --- | /O(n)/ Apply monadic function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply monadic function \(\max(n - 1, 0)\) times to an initial value, producing a vector+-- of length \(\max(n, 0)\). Zeroth element will contain the initial value, that's why there+-- is one less function application than the number of elements in the produced vector.+--+-- For non-monadic version see `iterateN`+--+-- @since 0.12.0.0 iterateNM :: Monad m => Int -> (a -> m a) -> a -> m (Vector a) {-# INLINE iterateNM #-} iterateNM = G.iterateNM@@ -906,7 +1003,11 @@ -- | /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>+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.accum (+) (V.fromList [1000.0,2000.0,3000.0]) [(2,4),(1,6),(0,3),(1,10)]+-- [1003.0,2016.0,3004.0] accum :: (a -> b -> a) -- ^ accumulating function @f@ -> Vector a -- ^ initial vector (of length @m@) -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)@@ -917,7 +1018,11 @@ -- | /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>+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.accumulate (+) (V.fromList [1000.0,2000.0,3000.0]) (V.fromList [(2,4),(1,6),(0,3),(1,10)])+-- [1003.0,2016.0,3004.0] 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@)@@ -1063,6 +1168,22 @@ {-# INLINE forM_ #-} forM_ = G.forM_ +-- | /O(n)/ Apply the monadic action to all elements of the vector and their indices, yielding a+-- vector of results. Equivalent to 'flip' 'imapM'.+--+-- @since 0.12.2.0+iforM :: Monad m => Vector a -> (Int -> a -> m b) -> m (Vector b)+{-# INLINE iforM #-}+iforM = G.iforM++-- | /O(n)/ Apply the monadic action to all elements of the vector and their indices and ignore the+-- results. Equivalent to 'flip' 'imapM_'.+--+-- @since 0.12.2.0+iforM_ :: Monad m => Vector a -> (Int -> a -> m b) -> m ()+{-# INLINE iforM_ #-}+iforM_ = G.iforM_+ -- Zipping -- ------- @@ -1229,13 +1350,37 @@ {-# INLINE imapMaybe #-} imapMaybe = G.imapMaybe +-- | /O(n)/ Return a Vector of all the `Just` values.+--+-- @since 0.12.2.0+catMaybes :: Vector (Maybe a) -> Vector a+{-# INLINE catMaybes #-}+catMaybes = mapMaybe id+ -- | /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.+-- | /O(n)/ Apply monadic function to each element of vector and+-- discard elements returning Nothing.+--+-- @since 0.12.2.0+mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Vector a -> m (Vector b)+{-# INLINE mapMaybeM #-}+mapMaybeM = G.mapMaybeM++-- | /O(n)/ Apply monadic function to each element of vector and its index.+-- Discards elements returning Nothing.+--+-- @since 0.12.2.0+imapMaybeM :: Monad m => (Int -> a -> m (Maybe b)) -> Vector a -> m (Vector b)+{-# INLINE imapMaybeM #-}+imapMaybeM = G.imapMaybeM++-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate.+-- Current implementation is not copy-free, unless the result vector is+-- fused away. takeWhile :: (a -> Bool) -> Vector a -> Vector a {-# INLINE takeWhile #-} takeWhile = G.takeWhile@@ -1265,11 +1410,11 @@ {-# INLINE unstablePartition #-} unstablePartition = G.unstablePartition --- | /O(n)/ Split the vector in two parts, the first one containing the--- @Right@ elements and the second containing the @Left@ elements.--- The relative order of the elements is preserved.+-- | /O(n)/ Split the vector into two parts, the first one containing the+-- @`Left`@ elements and the second containing the @`Right`@ elements.+-- The relative order of the elements is preserved. ----- @since 0.12.1.0+-- @since 0.12.1.0 partitionWith :: (a -> Either b c) -> Vector a -> (Vector b, Vector c) {-# INLINE partitionWith #-} partitionWith = G.partitionWith@@ -1397,41 +1542,121 @@ {-# INLINE ifoldr' #-} ifoldr' = G.ifoldr' +-- | /O(n)/ Map each element of the structure to a monoid, and combine+-- the results. It uses same implementation as corresponding method of+-- 'Foldable' type cless. Note it's implemented in terms of 'foldr'+-- and won't fuse with functions that traverse vector from left to+-- right ('map', 'generate', etc.).+--+-- @since 0.12.2.0+foldMap :: (Monoid m) => (a -> m) -> Vector a -> m+{-# INLINE foldMap #-}+foldMap = G.foldMap++-- | /O(n)/ 'foldMap' which is strict in accumulator. It uses same+-- implementation as corresponding method of 'Foldable' type class.+-- Note it's implemented in terms of 'foldl'' so it fuses in most+-- contexts.+--+-- @since 0.12.2.0+foldMap' :: (Monoid m) => (a -> m) -> Vector a -> m+{-# INLINE foldMap' #-}+foldMap' = G.foldMap'++ -- Specialised folds -- ----------------- -- | /O(n)/ Check if all elements satisfy the predicate.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.all even $ V.fromList [2, 4, 12 :: Int]+-- True+-- >>> V.all even $ V.fromList [2, 4, 13 :: Int]+-- False+-- >>> V.all even (V.empty :: V.Vector Int)+-- True all :: (a -> Bool) -> Vector a -> Bool {-# INLINE all #-} all = G.all -- | /O(n)/ Check if any element satisfies the predicate.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.any even $ V.fromList [1, 3, 7 :: Int]+-- False+-- >>> V.any even $ V.fromList [3, 2, 13 :: Int]+-- True+-- >>> V.any even (V.empty :: V.Vector Int)+-- False any :: (a -> Bool) -> Vector a -> Bool {-# INLINE any #-} any = G.any -- | /O(n)/ Check if all elements are 'True'+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.and $ V.fromList [True, False]+-- False+-- >>> V.and V.empty+-- True and :: Vector Bool -> Bool {-# INLINE and #-} and = G.and -- | /O(n)/ Check if any element is 'True'+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.or $ V.fromList [True, False]+-- True+-- >>> V.or V.empty+-- False or :: Vector Bool -> Bool {-# INLINE or #-} or = G.or -- | /O(n)/ Compute the sum of the elements+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.sum $ V.fromList [300,20,1 :: Int]+-- 321+-- >>> V.sum (V.empty :: V.Vector Int)+-- 0 sum :: Num a => Vector a -> a {-# INLINE sum #-} sum = G.sum -- | /O(n)/ Compute the produce of the elements+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.product $ V.fromList [1,2,3,4 :: Int]+-- 24+-- >>> V.product (V.empty :: V.Vector Int)+-- 1 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.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.maximum $ V.fromList [2.0, 1.0]+-- 2.0 maximum :: Ord a => Vector a -> a {-# INLINE maximum #-} maximum = G.maximum@@ -1444,6 +1669,12 @@ -- | /O(n)/ Yield the minimum element of the vector. The vector may not be -- empty.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.minimum $ V.fromList [2.0, 1.0]+-- 1.0 minimum :: Ord a => Vector a -> a {-# INLINE minimum #-} minimum = G.minimum@@ -1613,11 +1844,15 @@ scanl' = G.scanl' -- | /O(n)/ Scan over a vector with its index+--+-- @since 0.12.0.0 iscanl :: (Int -> a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE iscanl #-} iscanl = G.iscanl -- | /O(n)/ Scan over a vector (strictly) with its index+--+-- @since 0.12.0.0 iscanl' :: (Int -> a -> b -> a) -> a -> Vector b -> Vector a {-# INLINE iscanl' #-} iscanl' = G.iscanl'@@ -1673,11 +1908,15 @@ scanr' = G.scanr' -- | /O(n)/ Right-to-left scan over a vector with its index+--+-- @since 0.12.0.0 iscanr :: (Int -> a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE iscanr #-} iscanr = G.iscanr -- | /O(n)/ Right-to-left scan over a vector (strictly) with its index+--+-- @since 0.12.0.0 iscanr' :: (Int -> a -> b -> b) -> b -> Vector a -> Vector b {-# INLINE iscanr' #-} iscanr' = G.iscanr'@@ -1693,6 +1932,26 @@ {-# INLINE scanr1' #-} scanr1' = G.scanr1' +-- Comparisons+-- ------------------------++-- | /O(n)/ Check if two vectors are equal using supplied equality+-- predicate.+--+-- @since 0.12.2.0+eqBy :: (a -> b -> Bool) -> Vector a -> Vector b -> Bool+{-# INLINE eqBy #-}+eqBy = G.eqBy++-- | /O(n)/ Compare two vectors using supplied comparison function for+-- vector elements. Comparison works same as for lists.+--+-- > cmpBy compare == compare+--+-- @since 0.12.2.0+cmpBy :: (a -> b -> Ordering) -> Vector a -> Vector b -> Ordering+cmpBy = G.cmpBy+ -- Conversions - Lists -- ------------------------ @@ -1714,6 +1973,25 @@ fromListN :: Int -> [a] -> Vector a {-# INLINE fromListN #-} fromListN = G.fromListN++-- Conversions - Arrays+-- -----------------------------++-- | /O(1)/ Convert an array to a vector.+--+-- @since 0.12.2.0+fromArray :: Array a -> Vector a+{-# INLINE fromArray #-}+fromArray x = Vector 0 (sizeofArray x) x++-- | /O(n)/ Convert a vector to an array.+--+-- @since 0.12.2.0+toArray :: Vector a -> Array a+{-# INLINE toArray #-}+toArray (Vector offset size arr)+ | offset == 0 && size == sizeofArray arr = arr+ | otherwise = cloneArray arr offset size -- Conversions - Mutable vectors -- -----------------------------
Data/Vector/Fusion/Bundle.hs view
@@ -55,7 +55,7 @@ and, or, -- * Unfolding- unfoldr, unfoldrN, iterateN,+ unfoldr, unfoldrN, unfoldrExactN, iterateN, -- * Scans prescanl, prescanl',@@ -71,7 +71,7 @@ fromVector, reVector, fromVectors, concatVectors, -- * Monadic combinators- mapM, mapM_, zipWithM, zipWithM_, filterM, foldM, fold1M, foldM', fold1M',+ mapM, mapM_, zipWithM, zipWithM_, filterM, mapMaybeM, foldM, fold1M, foldM', fold1M', eq, cmp, eqBy, cmpBy ) where@@ -80,7 +80,7 @@ import Data.Vector.Fusion.Bundle.Size import Data.Vector.Fusion.Util import Data.Vector.Fusion.Stream.Monadic ( Stream(..), Step(..) )-import Data.Vector.Fusion.Bundle.Monadic ( Chunk(..) )+import Data.Vector.Fusion.Bundle.Monadic ( Chunk(..), lift ) import qualified Data.Vector.Fusion.Bundle.Monadic as M import qualified Data.Vector.Fusion.Stream.Monadic as S @@ -128,14 +128,6 @@ inplace f1 g1 (inplace f2 g2 s) = inplace (f1 . f2) (g1 . g2) s #-} ---- | Convert a pure stream to a monadic stream-lift :: Monad m => Bundle v a -> M.Bundle m v a-{-# INLINE_FUSED lift #-}-lift (M.Bundle (Stream step s) (Stream vstep t) v sz)- = M.Bundle (Stream (return . unId . step) s)- (Stream (return . unId . vstep) t) v sz- -- | 'Size' hint of a 'Bundle' size :: Bundle v a -> Size {-# INLINE size #-}@@ -437,7 +429,15 @@ {-# INLINE unfoldrN #-} unfoldrN = M.unfoldrN --- | Apply function n-1 times to value. Zeroth element is original value.+-- | Unfold exactly @n@ elements+--+-- @since 0.12.2.0+unfoldrExactN :: Int -> (s -> (a, s)) -> s -> Bundle v a+{-# INLINE unfoldrExactN #-}+unfoldrExactN = M.unfoldrExactN++-- | /O(n)/ Apply function \(\max(n - 1, 0)\) times to an initial value, producing a pure+-- bundle of exact length \(\max(n, 0)\). Zeroth element will contain the initial value. iterateN :: Int -> (a -> a) -> a -> Bundle v a {-# INLINE iterateN #-} iterateN = M.iterateN@@ -551,6 +551,14 @@ filterM :: Monad m => (a -> m Bool) -> Bundle v a -> M.Bundle m v a {-# INLINE filterM #-} filterM f = M.filterM f . lift++-- | /O(n)/ Apply monadic function to each element of a bundle and+-- discard elements returning Nothing.+--+-- @since 0.12.2.0+mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Bundle v a -> M.Bundle m v b+{-# INLINE mapMaybeM #-}+mapMaybeM f = M.mapMaybeM f . lift -- | Monadic fold foldM :: Monad m => (a -> b -> m a) -> a -> Bundle v b -> m a
Data/Vector/Fusion/Bundle/Monadic.hs view
@@ -13,7 +13,7 @@ -- module Data.Vector.Fusion.Bundle.Monadic (- Bundle(..), Chunk(..),+ Bundle(..), Chunk(..), lift, -- * Size hints size, sized,@@ -43,7 +43,7 @@ eqBy, cmpBy, -- * Filtering- filter, filterM, takeWhile, takeWhileM, dropWhile, dropWhileM,+ filter, filterM, mapMaybeM, takeWhile, takeWhileM, dropWhile, dropWhileM, -- * Searching elem, notElem, find, findM, findIndex, findIndexM,@@ -59,6 +59,7 @@ -- * Unfolding unfoldr, unfoldrM, unfoldrN, unfoldrNM,+ unfoldrExactN, unfoldrExactNM, iterateN, iterateNM, -- * Scans@@ -79,7 +80,7 @@ import Data.Vector.Generic.Base import qualified Data.Vector.Generic.Mutable.Base as M import Data.Vector.Fusion.Bundle.Size-import Data.Vector.Fusion.Util ( Box(..), delay_inline )+import Data.Vector.Fusion.Util ( Box(..), delay_inline, Id(..) ) import Data.Vector.Fusion.Stream.Monadic ( Stream(..), Step(..) ) import qualified Data.Vector.Fusion.Stream.Monadic as S import Control.Monad.Primitive@@ -124,6 +125,13 @@ , sSize :: Size } +-- | Convert a pure stream to a monadic stream+lift :: Monad m => Bundle Id v a -> Bundle m v a+{-# INLINE_FUSED lift #-}+lift (Bundle (Stream step s) (Stream vstep t) v sz)+ = Bundle (Stream (return . unId . step) s)+ (Stream (return . unId . vstep) t) v sz+ fromStream :: Monad m => Stream m a -> Size -> Bundle m v a {-# INLINE fromStream #-} fromStream (Stream step t) sz = Bundle (Stream step t) (Stream step' t) Nothing sz@@ -283,6 +291,10 @@ instance Monad m => Functor (Bundle m v) where {-# INLINE fmap #-} fmap = map+#if MIN_VERSION_base(4,8,0)+ {-# INLINE (<$) #-}+ (<$) = map . const+#endif -- | Map a function over a 'Bundle' map :: Monad m => (a -> b) -> Bundle m v a -> Bundle m v b@@ -334,7 +346,7 @@ {-# RULES "zipWithM xs xs [Vector.Bundle]" forall f xs.- zipWithM f xs xs = mapM (\x -> f x x) xs #-}+ zipWithM f (lift xs) (lift xs) = mapM (\x -> f x x) (lift xs) #-} zipWithM_ :: Monad m => (a -> b -> m c) -> Bundle m v a -> Bundle m v b -> m ()@@ -454,6 +466,13 @@ {-# INLINE_FUSED filterM #-} filterM f Bundle{sElems = s, sSize = n} = fromStream (S.filterM f s) (toMax n) +-- | Apply monadic function to each element and drop all Nothings+--+-- @since 0.12.2.0+mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Bundle m v a -> Bundle m v b+{-# INLINE_FUSED mapMaybeM #-}+mapMaybeM f Bundle{sElems = s, sSize = n} = fromStream (S.mapMaybeM f s) (toMax n)+ -- | Longest prefix of elements that satisfy the predicate takeWhile :: Monad m => (a -> Bool) -> Bundle m v a -> Bundle m v a {-# INLINE takeWhile #-}@@ -640,17 +659,35 @@ {-# INLINE_FUSED unfoldrN #-} unfoldrN n f = unfoldrNM n (return . f) --- | Unfold at most @n@ elements with a monadic functions+-- | Unfold at most @n@ elements with a monadic function. unfoldrNM :: Monad m => Int -> (s -> m (Maybe (a, s))) -> s -> Bundle m u a {-# INLINE_FUSED unfoldrNM #-} unfoldrNM n f s = fromStream (S.unfoldrNM n f s) (Max (delay_inline max n 0)) --- | Apply monadic function n times to value. Zeroth element is original value.+-- | Unfold exactly @n@ elements+--+-- @since 0.12.2.0+unfoldrExactN :: Monad m => Int -> (s -> (a, s)) -> s -> Bundle m u a+{-# INLINE_FUSED unfoldrExactN #-}+unfoldrExactN n f = unfoldrExactNM n (return . f)++-- | Unfold exactly @n@ elements with a monadic function.+--+-- @since 0.12.2.0+unfoldrExactNM :: Monad m => Int -> (s -> m (a, s)) -> s -> Bundle m u a+{-# INLINE_FUSED unfoldrExactNM #-}+unfoldrExactNM n f s = fromStream (S.unfoldrExactNM n f s) (Max (delay_inline max n 0))++-- | /O(n)/ Apply monadic function \(\max(n - 1, 0)\) times to an initial value, producing+-- a monadic bundle of exact length \(\max(n, 0)\). Zeroth element will contain the initial+-- value. iterateNM :: Monad m => Int -> (a -> m a) -> a -> Bundle m u a {-# INLINE_FUSED iterateNM #-} iterateNM n f x0 = fromStream (S.iterateNM n f x0) (Exact (delay_inline max n 0)) --- | Apply function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply function \(\max(n - 1, 0)\) times to an initial value, producing a+-- monadic bundle of exact length \(\max(n, 0)\). Zeroth element will contain the initial+-- value. iterateN :: Monad m => Int -> (a -> a) -> a -> Bundle m u a {-# INLINE_FUSED iterateN #-} iterateN n f x0 = iterateNM n (return . f) x0
Data/Vector/Fusion/Stream/Monadic.hs view
@@ -40,7 +40,7 @@ eqBy, cmpBy, -- * Filtering- filter, filterM, uniq, mapMaybe, takeWhile, takeWhileM, dropWhile, dropWhileM,+ filter, filterM, uniq, mapMaybe, mapMaybeM, catMaybes, takeWhile, takeWhileM, dropWhile, dropWhileM, -- * Searching elem, notElem, find, findM, findIndex, findIndexM,@@ -56,6 +56,7 @@ -- * Unfolding unfoldr, unfoldrM, unfoldrN, unfoldrNM,+ unfoldrExactN, unfoldrExactNM, iterateN, iterateNM, -- * Scans@@ -133,6 +134,10 @@ fmap f (Yield x s) = Yield (f x) s fmap _ (Skip s) = Skip s fmap _ Done = Done+#if MIN_VERSION_base(4,8,0)+ {-# INLINE (<$) #-}+ (<$) = fmap . const+#endif -- | Monadic streams data Stream m a = forall s. Stream (s -> m (Step s a)) s@@ -510,13 +515,6 @@ Skip sb' -> return $ Skip (sa, sb', Just x) Done -> return $ Done --- FIXME: This might expose an opportunity for inplace execution.-{-# RULES--"zipWithM xs xs [Vector.Stream]" forall f xs.- zipWithM f xs xs = mapM (\x -> f x x) xs #-}-- zipWithM_ :: Monad m => (a -> b -> m c) -> Stream m a -> Stream m b -> m () {-# INLINE zipWithM_ #-} zipWithM_ f sa sb = consume (zipWithM f sa sb)@@ -703,6 +701,9 @@ Skip s' -> return $ Skip s' Done -> return $ Done +catMaybes :: Monad m => Stream m (Maybe a) -> Stream m a+catMaybes = mapMaybe id+ -- | Drop elements which do not satisfy the monadic predicate filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a {-# INLINE_FUSED filterM #-}@@ -719,6 +720,25 @@ Skip s' -> return $ Skip s' Done -> return $ Done +-- | Apply monadic function to each element and drop all Nothings+--+-- @since 0.12.2.0+mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Stream m a -> Stream m b+{-# INLINE_FUSED mapMaybeM #-}+mapMaybeM f (Stream step t) = Stream step' t+ where+ {-# INLINE_INNER step' #-}+ step' s = do+ r <- step s+ case r of+ Yield x s' -> do+ fx <- f x+ return $ case fx of+ Nothing -> Skip s'+ Just b -> Yield b s'+ Skip s' -> return $ Skip s'+ Done -> return $ Done+ -- | Drop repeated adjacent elements. uniq :: (Eq a, Monad m) => Stream m a -> Stream m a {-# INLINE_FUSED uniq #-}@@ -1104,7 +1124,7 @@ {-# INLINE_FUSED unfoldrN #-} unfoldrN n f = unfoldrNM n (return . f) --- | Unfold at most @n@ elements with a monadic functions+-- | Unfold at most @n@ elements with a monadic function. unfoldrNM :: Monad m => Int -> (s -> m (Maybe (a, s))) -> s -> Stream m a {-# INLINE_FUSED unfoldrNM #-} unfoldrNM m f t = Stream step (t,m)@@ -1117,7 +1137,27 @@ Nothing -> Done ) (f s) --- | Apply monadic function n times to value. Zeroth element is original value.+-- | Unfold exactly @n@ elements+--+-- @since 0.12.2.0+unfoldrExactN :: Monad m => Int -> (s -> (a, s)) -> s -> Stream m a+{-# INLINE_FUSED unfoldrExactN #-}+unfoldrExactN n f = unfoldrExactNM n (return . f)++-- | Unfold exactly @n@ elements with a monadic function.+--+-- @since 0.12.2.0+unfoldrExactNM :: Monad m => Int -> (s -> m (a, s)) -> s -> Stream m a+{-# INLINE_FUSED unfoldrExactNM #-}+unfoldrExactNM m f t = Stream step (t,m)+ where+ {-# INLINE_INNER step #-}+ step (s,n) | n <= 0 = return Done+ | otherwise = do (x,s') <- f s+ return $ Yield x (s',n-1)++-- | /O(n)/ Apply monadic function \(\max(n - 1, 0)\) times to an initial value,+-- producing a stream of \(\max(n, 0)\) values. iterateNM :: Monad m => Int -> (a -> m a) -> a -> Stream m a {-# INLINE_FUSED iterateNM #-} iterateNM n f x0 = Stream step (x0,n)@@ -1128,7 +1168,8 @@ | otherwise = do a <- f x return $ Yield a (a,i-1) --- | Apply function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply function \(\max(n - 1, 0)\) times to an initial value,+-- producing a stream of \(\max(n, 0)\) values. iterateN :: Monad m => Int -> (a -> a) -> a -> Stream m a {-# INLINE_FUSED iterateN #-} iterateN n f x0 = iterateNM n (return . f) x0
Data/Vector/Generic.hs view
@@ -30,7 +30,7 @@ unsafeIndexM, unsafeHeadM, unsafeLastM, -- ** Extracting subvectors (slicing)- slice, init, tail, take, drop, splitAt,+ slice, init, tail, take, drop, splitAt, uncons, unsnoc, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, -- * Construction@@ -42,8 +42,8 @@ replicateM, generateM, iterateNM, create, createT, -- ** Unfolding- unfoldr, unfoldrN,- unfoldrM, unfoldrNM,+ unfoldr, unfoldrN, unfoldrExactN,+ unfoldrM, unfoldrNM, unfoldrExactNM, constructN, constructrN, -- ** Enumeration@@ -81,6 +81,7 @@ -- ** Monadic mapping mapM, imapM, mapM_, imapM_, forM, forM_,+ iforM, iforM_, -- ** Zipping zipWith, zipWith3, zipWith4, zipWith5, zipWith6,@@ -96,20 +97,21 @@ -- * Working with predicates -- ** Filtering- filter, ifilter, uniq,+ filter, ifilter, filterM, uniq, mapMaybe, imapMaybe,- filterM,+ mapMaybeM, imapMaybeM, takeWhile, dropWhile, -- ** Partitioning partition, partitionWith, unstablePartition, span, break, -- ** Searching- elem, notElem, find, findIndex, findIndices, elemIndex, elemIndices,+ elem, notElem, find, findIndex, findIndexR, findIndices, elemIndex, elemIndices, -- * Folding foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1', ifoldl, ifoldl', ifoldr, ifoldr',+ foldMap, foldMap', -- ** Specialised folds all, any, and, or,@@ -149,7 +151,7 @@ -- * Fusion support -- ** Conversion to/from Bundles- stream, unstream, streamR, unstreamR,+ stream, unstream, unstreamM, streamR, unstreamR, -- ** Recycling support new, clone,@@ -194,6 +196,9 @@ filter, takeWhile, dropWhile, span, break, elem, notElem, foldl, foldl1, foldr, foldr1,+#if __GLASGOW_HASKELL__ >= 706+ foldMap,+#endif all, any, and, or, sum, product, maximum, minimum, scanl, scanl1, scanr, scanr1, enumFromTo, enumFromThenTo,@@ -203,6 +208,10 @@ import qualified Text.Read as Read import qualified Data.List.NonEmpty as NonEmpty +#if __GLASGOW_HASKELL__ < 710+import Data.Monoid+#endif+ #if __GLASGOW_HASKELL__ >= 707 import Data.Typeable ( Typeable, gcast1 ) #else@@ -231,7 +240,7 @@ -- | /O(1)/ Yield the length of the vector length :: Vector v a => v a -> Int {-# INLINE length #-}-length = Bundle.length . stream'+length = Bundle.length . stream -- | /O(1)/ Test whether a vector is empty null :: Vector v a => v a -> Bool@@ -431,8 +440,10 @@ -- -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ -- but slightly more efficient.-{-# INLINE_FUSED splitAt #-}+--+-- @since 0.7.1 splitAt :: Vector v a => Int -> v a -> (v a, v a)+{-# INLINE_FUSED splitAt #-} splitAt n v = ( unsafeSlice 0 m v , unsafeSlice m (delay_inline max 0 (len - n')) v )@@ -441,6 +452,20 @@ n' = max n 0 len = length v +-- | /O(1)/ Yield the 'head' and 'tail' of the vector, or 'Nothing' if empty.+--+-- @since 0.12.2.0+uncons :: Vector v a => v a -> Maybe (a, v a)+{-# INLINE_FUSED uncons #-}+uncons xs = flip (,) (unsafeTail xs) `fmap` (xs !? 0)++-- | /O(1)/ Yield the 'last' and 'init' of the vector, or 'Nothing' if empty.+--+-- @since 0.12.2.0+unsnoc :: Vector v a => v a -> Maybe (v a, a)+{-# INLINE_FUSED unsnoc #-}+unsnoc xs = (,) (unsafeInit xs) `fmap` (xs !? (length xs - 1))+ -- | /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@@ -532,7 +557,13 @@ {-# INLINE generate #-} generate n f = unstream (Bundle.generate n f) --- | /O(n)/ Apply function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply function \(\max(n - 1, 0)\) times to an initial value, producing a vector+-- of length \(\max(n, 0)\). Zeroth element will contain the initial value, that's why there+-- is one less function application than the number of elements in the produced vector.+--+-- \( \underbrace{x, f (x), f (f (x)), \ldots}_{\max(0,n)\rm{~elements}} \)+--+-- @since 0.7.1 iterateN :: Vector v a => Int -> (a -> a) -> a -> v a {-# INLINE iterateN #-} iterateN n f x = unstream (Bundle.iterateN n f x)@@ -559,6 +590,17 @@ {-# INLINE unfoldrN #-} unfoldrN n f = unstream . Bundle.unfoldrN n f +-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying+-- the generator function to a seed. The generator function yields the+-- next element and the new seed.+--+-- > unfoldrExactN 3 (\n -> (n,n-1)) 10 = <10,9,8>+--+-- @since 0.12.2.0+unfoldrExactN :: Vector v a => Int -> (b -> (a, b)) -> b -> v a+{-# INLINE unfoldrExactN #-}+unfoldrExactN n f = unstream . Bundle.unfoldrExactN n f+ -- | /O(n)/ Construct a vector by repeatedly applying the monadic -- generator function to a seed. The generator function yields 'Just' -- the next element and the new seed or 'Nothing' if there are no more@@ -575,6 +617,15 @@ {-# INLINE unfoldrNM #-} unfoldrNM n f = unstreamM . MBundle.unfoldrNM n f +-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly+-- applying the monadic generator function to a seed. The generator+-- function yields the next element and the new seed.+--+-- @since 0.12.2.0+unfoldrExactNM :: (Monad m, Vector v a) => Int -> (b -> m (a, b)) -> b -> m (v a)+{-# INLINE unfoldrExactNM #-}+unfoldrExactNM n f = unstreamM . MBundle.unfoldrExactNM n f+ -- | /O(n)/ Construct a vector with @n@ elements by repeatedly applying the -- generator function to the already constructed part of the vector. --@@ -735,7 +786,13 @@ {-# INLINE generateM #-} generateM n f = unstreamM (MBundle.generateM n f) --- | /O(n)/ Apply monadic function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply monadic function \(\max(n - 1, 0)\) times to an initial value, producing a vector+-- of length \(\max(n, 0)\). Zeroth element will contain the initial value, that's why there+-- is one less function application than the number of elements in the produced vector.+--+-- For non-monadic version see `iterateN`+--+-- @since 0.12.0.0 iterateNM :: (Monad m, Vector v a) => Int -> (a -> m a) -> a -> m (v a) {-# INLINE iterateNM #-} iterateNM n f x = unstreamM (MBundle.iterateNM n f x)@@ -851,7 +908,11 @@ -- | /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>+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.accum (+) (V.fromList [1000.0,2000.0,3000.0]) [(2,4),(1,6),(0,3),(1,10)]+-- [1003.0,2016.0,3004.0] accum :: Vector v a => (a -> b -> a) -- ^ accumulating function @f@ -> v a -- ^ initial vector (of length @m@)@@ -863,7 +924,11 @@ -- | /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>+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.accumulate (+) (V.fromList [1000.0,2000.0,3000.0]) (V.fromList [(2,4),(1,6),(0,3),(1,10)])+-- [1003.0,2016.0,3004.0] accumulate :: (Vector v a, Vector v (Int, b)) => (a -> b -> a) -- ^ accumulating function @f@ -> v a -- ^ initial vector (of length @m@)@@ -1096,6 +1161,22 @@ {-# INLINE forM_ #-} forM_ as f = mapM_ f as +-- | /O(n)/ Apply the monadic action to all elements of the vector and their indices, yielding a+-- vector of results. Equivalent to 'flip' 'imapM'.+--+-- @since 0.12.2.0+iforM :: (Monad m, Vector v a, Vector v b) => v a -> (Int -> a -> m b) -> m (v b)+{-# INLINE iforM #-}+iforM as f = imapM f as++-- | /O(n)/ Apply the monadic action to all elements of the vector and their indices and ignore the+-- results. Equivalent to 'flip' 'imapM_'.+--+-- @since 0.12.2.0+iforM_ :: (Monad m, Vector v a) => v a -> (Int -> a -> m b) -> m ()+{-# INLINE iforM_ #-}+iforM_ as f = imapM_ f as+ -- Zipping -- ------- @@ -1345,8 +1426,26 @@ {-# INLINE filterM #-} filterM f = unstreamM . Bundle.filterM f . stream --- | /O(n)/ Yield the longest prefix of elements satisfying the predicate--- without copying.+-- | /O(n)/ Apply monadic function to each element of vector and+-- discard elements returning Nothing.+--+-- @since 0.12.2.0+mapMaybeM :: (Monad m, Vector v a, Vector v b) => (a -> m (Maybe b)) -> v a -> m (v b)+{-# INLINE mapMaybeM #-}+mapMaybeM f = unstreamM . Bundle.mapMaybeM f . stream++-- | /O(n)/ Apply monadic function to each element of vector and its index.+-- Discards elements returning Nothing.+--+-- @since 0.12.2.0+imapMaybeM :: (Monad m, Vector v a, Vector v b)+ => (Int -> a -> m (Maybe b)) -> v a -> m (v b)+{-# INLINE imapMaybeM #-}+imapMaybeM f = unstreamM . Bundle.mapMaybeM (\(i, a) -> f i a) . Bundle.indexed . stream++-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate.+-- Current implementation is not copy-free, unless the result vector is+-- fused away. takeWhile :: Vector v a => (a -> Bool) -> v a -> v a {-# INLINE takeWhile #-} takeWhile f = unstream . Bundle.takeWhile f . stream@@ -1354,9 +1453,25 @@ -- | /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 . Bundle.dropWhile f . stream+{-# INLINE_FUSED dropWhile #-}+-- In the case that the argument is an actual vector,+-- this is a faster solution than stream fusion.+dropWhile f xs = case findIndex (not . f) xs of+ Just i -> unsafeDrop i xs+ Nothing -> empty +-- If we have optimization turned on+-- and the argument to 'dropWhile' comes from a stream,+-- we never allocate the argument vector, and+-- whenever possible, we avoid creating the resulting vector actually in heap.+--+-- Also note that @'new' . 'New.unstream'@+-- is the definition (to be @INLINE@d) of 'unstream'.+{-# RULES+"dropWhile/unstream [Vector]" forall f p.+ dropWhile f (new (New.unstream p)) = new (New.unstream (Bundle.dropWhile f p))+ #-}+ -- Parititioning -- ------------- @@ -1380,6 +1495,11 @@ v2 <- unsafeFreeze mv2 return (v1,v2)) +-- | /O(n)/ Split the vector into two parts, the first one containing the+-- @`Left`@ elements and the second containing the @`Right`@ elements.+-- The relative order of the elements is preserved.+--+-- @since 0.12.1.0 partitionWith :: (Vector v a, Vector v b, Vector v c) => (a -> Either b c) -> v a -> (v b, v c) {-# INLINE partitionWith #-} partitionWith f = partition_with_stream f . stream@@ -1473,6 +1593,14 @@ {-# INLINE findIndex #-} findIndex f = Bundle.findIndex f . stream +-- | /O(n)/ Yield 'Just' the index of the /last/ element matching the predicate+-- or 'Nothing' if no such element exists.+--+-- @since 0.12.2.0+findIndexR :: Vector v a => (a -> Bool) -> v a -> Maybe Int+{-# INLINE findIndexR #-}+findIndexR f v = fmap (length v - 1 -) . Bundle.findIndex f $ streamR v+ -- | /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@@ -1560,41 +1688,121 @@ ifoldr' f z xs = Bundle.foldl' (flip (uncurry f)) z $ Bundle.indexedR (length xs) $ streamR xs +-- | /O(n)/ Map each element of the structure to a monoid, and combine+-- the results. It uses same implementation as corresponding method of+-- 'Foldable' type cless. Note it's implemented in terms of 'foldr'+-- and won't fuse with functions that traverse vector from left to+-- right ('map', 'generate', etc.).+--+-- @since 0.12.2.0+foldMap :: (Monoid m, Vector v a) => (a -> m) -> v a -> m+{-# INLINE foldMap #-}+foldMap f = foldr (mappend . f) mempty++-- | /O(n)/ 'foldMap' which is strict in accumulator. It uses same+-- implementation as corresponding method of 'Foldable' type class.+-- Note it's implemented in terms of 'foldl'' so it fuses in most+-- contexts.+--+-- @since 0.12.2.0+foldMap' :: (Monoid m, Vector v a) => (a -> m) -> v a -> m+{-# INLINE foldMap' #-}+foldMap' f = foldl' (\acc a -> acc `mappend` f a) mempty++ -- Specialised folds -- ----------------- -- | /O(n)/ Check if all elements satisfy the predicate.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.all even $ V.fromList [2, 4, 12 :: Int]+-- True+-- >>> V.all even $ V.fromList [2, 4, 13 :: Int]+-- False+-- >>> V.all even (V.empty :: V.Vector Int)+-- True all :: Vector v a => (a -> Bool) -> v a -> Bool {-# INLINE all #-} all f = Bundle.and . Bundle.map f . stream -- | /O(n)/ Check if any element satisfies the predicate.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.any even $ V.fromList [1, 3, 7 :: Int]+-- False+-- >>> V.any even $ V.fromList [3, 2, 13 :: Int]+-- True+-- >>> V.any even (V.empty :: V.Vector Int)+-- False any :: Vector v a => (a -> Bool) -> v a -> Bool {-# INLINE any #-} any f = Bundle.or . Bundle.map f . stream -- | /O(n)/ Check if all elements are 'True'+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.and $ V.fromList [True, False]+-- False+-- >>> V.and V.empty+-- True and :: Vector v Bool => v Bool -> Bool {-# INLINE and #-} and = Bundle.and . stream -- | /O(n)/ Check if any element is 'True'+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.or $ V.fromList [True, False]+-- True+-- >>> V.or V.empty+-- False or :: Vector v Bool => v Bool -> Bool {-# INLINE or #-} or = Bundle.or . stream -- | /O(n)/ Compute the sum of the elements+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.sum $ V.fromList [300,20,1 :: Int]+-- 321+-- >>> V.sum (V.empty :: V.Vector Int)+-- 0 sum :: (Vector v a, Num a) => v a -> a {-# INLINE sum #-} sum = Bundle.foldl' (+) 0 . stream -- | /O(n)/ Compute the produce of the elements+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.product $ V.fromList [1,2,3,4 :: Int]+-- 24+-- >>> V.product (V.empty :: V.Vector Int)+-- 1 product :: (Vector v a, Num a) => v a -> a {-# INLINE product #-} product = Bundle.foldl' (*) 1 . stream -- | /O(n)/ Yield the maximum element of the vector. The vector may not be -- empty.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.maximum $ V.fromList [2.0, 1.0]+-- 2.0 maximum :: (Vector v a, Ord a) => v a -> a {-# INLINE maximum #-} maximum = Bundle.foldl1' max . stream@@ -1612,6 +1820,12 @@ -- | /O(n)/ Yield the minimum element of the vector. The vector may not be -- empty.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.minimum $ V.fromList [2.0, 1.0]+-- 1.0 minimum :: (Vector v a, Ord a) => v a -> a {-# INLINE minimum #-} minimum = Bundle.foldl1' min . stream@@ -1915,6 +2129,14 @@ -- @ -- fromListN n xs = 'fromList' ('take' n xs) -- @+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> V.fromListN 3 [1,2,3,4,5::Int]+-- [1,2,3]+-- >>> V.fromListN 3 [1::Int]+-- [1] fromListN :: Vector v a => Int -> [a] -> v a {-# INLINE fromListN #-} fromListN n = unstream . Bundle.fromListN n@@ -1995,7 +2217,7 @@ :: (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)+ (M.length dst == basicLength src) $ unsafeCopy dst src -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must@@ -2004,7 +2226,7 @@ :: (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)+ (M.length dst == basicLength src) $ (dst `seq` src `seq` basicUnsafeCopy dst src) -- Conversions to/from Bundles@@ -2013,13 +2235,7 @@ -- | /O(1)/ Convert a vector to a 'Bundle' stream :: Vector v a => v a -> Bundle v a {-# INLINE_FUSED stream #-}-stream v = stream' v---- Same as 'stream', but can be used to avoid having a cycle in the dependency--- graph of functions, which forces GHC to create a loop breaker.-stream' :: Vector v a => v a -> Bundle v a-{-# INLINE stream' #-}-stream' v = Bundle.fromVector v+stream v = Bundle.fromVector v {- stream v = v `seq` n `seq` (Bundle.unfoldr get 0 `Bundle.sized` Exact n)@@ -2100,7 +2316,10 @@ streamR (new (New.transformR f g m)) = inplace f g (streamR (new m)) #-} -+-- | Load monadic stream bundle into a newly allocated vector. This function goes through+-- a list, so prefer using `unstream`, unless you need to be in a monad.+--+-- @since 0.12.2.0 unstreamM :: (Monad m, Vector v a) => MBundle m u a -> m (v a) {-# INLINE_FUSED unstreamM #-} unstreamM s = do@@ -2142,7 +2361,7 @@ {-# INLINE_FUSED clone #-} clone v = v `seq` New.create ( do- mv <- M.new (length v)+ mv <- M.new (basicLength v) unsafeCopy mv v return mv) @@ -2157,7 +2376,8 @@ {-# INLINE eq #-} xs `eq` ys = stream xs == stream ys --- | /O(n)/+-- | /O(n)/ Check if two vectors are equal using supplied equality+-- predicate. eqBy :: (Vector v a, Vector v b) => (a -> b -> Bool) -> v a -> v b -> Bool {-# INLINE eqBy #-} eqBy e xs ys = Bundle.eqBy e (stream xs) (stream ys)@@ -2170,7 +2390,10 @@ {-# INLINE cmp #-} cmp xs ys = compare (stream xs) (stream ys) --- | /O(n)/+-- | /O(n)/ Compare two vectors using supplied comparison function for+-- vector elements. Comparison works same as for lists.+--+-- > cmpBy compare == cmp cmpBy :: (Vector v a, Vector v b) => (a -> b -> Ordering) -> v a -> v b -> Ordering cmpBy c xs ys = Bundle.cmpBy c (stream xs) (stream ys) @@ -2238,3 +2461,6 @@ => (forall d. Data d => c (t d)) -> Maybe (c (v a)) {-# INLINE dataCast #-} dataCast f = gcast1 f++-- $setup+-- >>> :set -XFlexibleContexts
Data/Vector/Generic/Base.hs view
@@ -145,4 +145,5 @@ {-# INLINE elemseq #-} elemseq _ = \_ x -> x -+ {-# MINIMAL basicUnsafeFreeze, basicUnsafeThaw, basicLength,+ basicUnsafeSlice, basicUnsafeIndexM #-}
Data/Vector/Generic/Mutable.hs view
@@ -591,7 +591,14 @@ new n = BOUNDS_CHECK(checkLength) "new" n $ unsafeNew n >>= \v -> basicInitialize v >> return v --- | Create a mutable vector of the given length. The memory is not initialized.+-- | Create a mutable vector of the given length. The vector content+-- should be presumed uninitialized. However exact semantics depends+-- on vector implementation. For example unboxed and storable+-- vectors will create vector filled with whatever underlying memory+-- buffer happens to contain, while boxed vector's elements are+-- initialized to bottoms which will throw exception when evaluated.+--+-- @since 0.4 unsafeNew :: (PrimMonad m, MVector v a) => Int -> m (v (PrimState m) a) {-# INLINE unsafeNew #-} unsafeNew n = UNSAFE_CHECK(checkLength) "unsafeNew" n@@ -620,8 +627,18 @@ -- Growing -- ------- --- | Grow a vector by the given number of elements. The number must be--- positive.+-- | Grow a vector by the given number of elements. The number must not be+-- negative otherwise error is thrown. Semantics of this function is exactly the+-- same as `unsafeGrow`, except that it will initialize the newly+-- allocated memory first.+--+-- It is important to note that mutating the returned vector will not affect the+-- vector that was used as a source. In other words it does not, nor will it+-- ever have the semantics of @realloc@ from C.+--+-- > grow mv 0 === clone mv+--+-- @since 0.4.0 grow :: (PrimMonad m, MVector v a) => v (PrimState m) a -> Int -> m (v (PrimState m) a) {-# INLINE grow #-}@@ -630,6 +647,10 @@ basicInitialize $ basicUnsafeSlice (length v) by vnew return vnew +-- | Same as `grow`, except that it copies data towards the end of the newly+-- allocated vector making extra space available at the beginning.+--+-- @since 0.11.0.0 growFront :: (PrimMonad m, MVector v a) => v (PrimState m) a -> Int -> m (v (PrimState m) a) {-# INLINE growFront #-}@@ -661,14 +682,39 @@ where by = enlarge_delta v --- | Grow a vector by the given number of elements. The number must be--- positive but this is not checked.-unsafeGrow :: (PrimMonad m, MVector v a)- => v (PrimState m) a -> Int -> m (v (PrimState m) a)+-- | Grow a vector by allocating a new mutable vector of the same size plus the+-- the given number of elements and copying all the data over to the new vector+-- starting at its beginning. The newly allocated memory is not initialized and+-- the extra space at the end will likely contain garbage data or uninitialzed+-- error. Use `unsafeGrowFront` to make the extra space available in the front+-- of the new vector.+--+-- It is important to note that mutating the returned vector will not affect+-- elements of the vector that was used as a source. In other words it does not,+-- nor will it ever have the semantics of @realloc@ from C. Keep in mind,+-- however, that values themselves can be of a mutable type+-- (eg. `Foreign.Ptr.Ptr`), in which case it would be possible to affect values+-- stored in both vectors.+--+-- > unsafeGrow mv 0 === clone mv+--+-- @since 0.4.0+unsafeGrow ::+ (PrimMonad m, MVector v a)+ => v (PrimState m) a+ -- ^ A mutable vector to copy the data from.+ -> Int+ -- ^ Number of elements to grow the vector by. It must be non-negative but+ -- this is not checked.+ -> m (v (PrimState m) a) {-# INLINE unsafeGrow #-} unsafeGrow v n = UNSAFE_CHECK(checkLength) "unsafeGrow" n $ basicUnsafeGrow v n +-- | Same as `unsafeGrow`, except that it copies data towards the end of the+-- newly allocated vector making extra space available at the beginning.+--+-- @since 0.11.0.0 unsafeGrowFront :: (PrimMonad m, MVector v a) => v (PrimState m) a -> Int -> m (v (PrimState m) a) {-# INLINE unsafeGrowFront #-}
Data/Vector/Generic/Mutable/Base.hs view
@@ -87,10 +87,12 @@ -> v (PrimState m) a -- ^ source -> m () - -- | Grow a vector by the given number of elements. This method should not be- -- called directly, use 'unsafeGrow' instead.- basicUnsafeGrow :: PrimMonad m => v (PrimState m) a -> Int- -> m (v (PrimState m) a)+ -- | Grow a vector by the given number of elements. Allocates a new vector and+ -- copies all of the elements over starting at 0 index. This method should not+ -- be called directly, use 'grow'\/'unsafeGrow' instead.+ basicUnsafeGrow :: PrimMonad m => v (PrimState m) a+ -> Int+ -> m (v (PrimState m) a) {-# INLINE basicUnsafeReplicate #-} basicUnsafeReplicate n x@@ -145,3 +147,6 @@ where n = basicLength v + {-# MINIMAL basicLength, basicUnsafeSlice, basicOverlaps,+ basicUnsafeNew, basicInitialize, basicUnsafeRead,+ basicUnsafeWrite #-}
Data/Vector/Mutable.hs view
@@ -47,10 +47,14 @@ nextPermutation, -- ** Filling and copying- set, copy, move, unsafeCopy, unsafeMove++ set, copy, move, unsafeCopy, unsafeMove,++ -- ** Arrays+ fromMutableArray, toMutableArray ) where -import Control.Monad (when)+import Control.Monad (when, liftM) import qualified Data.Vector.Generic.Mutable as G import Data.Primitive.Array import Control.Monad.Primitive@@ -65,9 +69,9 @@ -- | Mutable boxed vectors keyed on the monad they live in ('IO' or @'ST' s@).-data MVector s a = MVector {-# UNPACK #-} !Int- {-# UNPACK #-} !Int- {-# UNPACK #-} !(MutableArray s a)+data MVector s a = MVector {-# UNPACK #-} !Int -- ^ Offset in underlying array+ {-# UNPACK #-} !Int -- ^ Size of slice+ {-# UNPACK #-} !(MutableArray s a) -- ^ Underlying array deriving ( Typeable ) type IOVector = MVector RealWorld@@ -187,7 +191,7 @@ in go 0 uninitialised :: a-uninitialised = error "Data.Vector.Mutable: uninitialised element. If you are trying to compact a vector, use the 'force' function to remove uninitialised elements from the underlying array."+uninitialised = error "Data.Vector.Mutable: uninitialised element. If you are trying to compact a vector, use the 'Data.Vector.force' function to remove uninitialised elements from the underlying array." -- Length information -- ------------------@@ -275,7 +279,10 @@ {-# INLINE new #-} new = G.new --- | Create a mutable vector of the given length. The memory is not initialized.+-- | Create a mutable vector of the given length. The vector elements+-- are set to bottom so accessing them will cause an exception.+--+-- @since 0.5 unsafeNew :: PrimMonad m => Int -> m (MVector (PrimState m) a) {-# INLINE unsafeNew #-} unsafeNew = G.unsafeNew@@ -300,15 +307,49 @@ -- Growing -- ------- --- | Grow a vector by the given number of elements. The number must be--- positive.+-- | Grow a boxed vector by the given number of elements. The number must be+-- non-negative. Same semantics as in `G.grow` for generic vector. It differs+-- from @grow@ functions for unpacked vectors, however, in that only pointers to+-- values are copied over, therefore values themselves will be shared between+-- two vectors. This is an important distinction to know about during memory+-- usage analysis and in case when values themselves are of a mutable type, eg.+-- `Data.IORef.IORef` or another mutable vector.+--+-- ====__Examples__+--+-- >>> import qualified Data.Vector as V+-- >>> import qualified Data.Vector.Mutable as MV+-- >>> mv <- V.thaw $ V.fromList ([10, 20, 30] :: [Integer])+-- >>> mv' <- MV.grow mv 2+--+-- The two extra elements at the end of the newly allocated vector will be+-- uninitialized and will result in an error if evaluated, so me must overwrite+-- them with new values first:+--+-- >>> MV.write mv' 3 999+-- >>> MV.write mv' 4 777+-- >>> V.unsafeFreeze mv'+-- [10,20,30,999,777]+--+-- It is important to note that the source mutable vector is not affected when+-- the newly allocated one is mutated.+--+-- >>> MV.write mv' 2 888+-- >>> V.unsafeFreeze mv'+-- [10,20,888,999,777]+-- >>> V.unsafeFreeze mv+-- [10,20,30]+--+-- @since 0.5 grow :: PrimMonad m => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a) {-# INLINE grow #-} grow = G.grow --- | Grow a vector by the given number of elements. The number must be--- positive but this is not checked.+-- | Grow a vector by the given number of elements. The number must be non-negative but+-- this is not checked. Same semantics as in `G.unsafeGrow` for generic vector.+--+-- @since 0.5 unsafeGrow :: PrimMonad m => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a) {-# INLINE unsafeGrow #-}@@ -422,3 +463,22 @@ nextPermutation :: (PrimMonad m,Ord e) => MVector (PrimState m) e -> m Bool {-# INLINE nextPermutation #-} nextPermutation = G.nextPermutation++-- Conversions - Arrays+-- -----------------------------++-- | /O(n)/ Make a copy of a mutable array to a new mutable vector.+--+-- @since 0.12.2.0+fromMutableArray :: PrimMonad m => MutableArray (PrimState m) a -> m (MVector (PrimState m) a)+{-# INLINE fromMutableArray #-}+fromMutableArray marr =+ let size = sizeofMutableArray marr+ in MVector 0 size `liftM` cloneMutableArray marr 0 size++-- | /O(n)/ Make a copy of a mutable vector into a new mutable array.+--+-- @since 0.12.2.0+toMutableArray :: PrimMonad m => MVector (PrimState m) a -> m (MutableArray (PrimState m) a)+{-# INLINE toMutableArray #-}+toMutableArray (MVector offset size marr) = cloneMutableArray marr offset size
Data/Vector/Primitive.hs view
@@ -34,7 +34,7 @@ unsafeIndexM, unsafeHeadM, unsafeLastM, -- ** Extracting subvectors (slicing)- slice, init, tail, take, drop, splitAt,+ slice, init, tail, take, drop, splitAt, uncons, unsnoc, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, -- * Construction@@ -46,8 +46,8 @@ replicateM, generateM, iterateNM, create, createT, -- ** Unfolding- unfoldr, unfoldrN,- unfoldrM, unfoldrNM,+ unfoldr, unfoldrN, unfoldrExactN,+ unfoldrM, unfoldrNM, unfoldrExactNM, constructN, constructrN, -- ** Enumeration@@ -81,21 +81,22 @@ map, imap, concatMap, -- ** Monadic mapping- mapM, mapM_, forM, forM_,+ mapM, imapM, mapM_, imapM_, forM, forM_,+ iforM, iforM_, -- ** Zipping zipWith, zipWith3, zipWith4, zipWith5, zipWith6, izipWith, izipWith3, izipWith4, izipWith5, izipWith6, -- ** Monadic zipping- zipWithM, zipWithM_,+ zipWithM, izipWithM, zipWithM_, izipWithM_, -- * Working with predicates -- ** Filtering- filter, ifilter, uniq,+ filter, ifilter, filterM, uniq, mapMaybe, imapMaybe,- filterM,+ mapMaybeM, imapMaybeM, takeWhile, dropWhile, -- ** Partitioning@@ -107,6 +108,7 @@ -- * Folding foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1', ifoldl, ifoldl', ifoldr, ifoldr',+ foldMap, foldMap', -- ** Specialised folds all, any,@@ -115,17 +117,23 @@ minIndex, minIndexBy, maxIndex, maxIndexBy, -- ** Monadic folds- foldM, foldM', fold1M, fold1M',- foldM_, foldM'_, fold1M_, fold1M'_,+ foldM, ifoldM, foldM', ifoldM',+ fold1M, fold1M', foldM_, ifoldM_,+ foldM'_, ifoldM'_, fold1M_, fold1M'_, -- * Prefix sums (scans) prescanl, prescanl', postscanl, postscanl', scanl, scanl', scanl1, scanl1',+ iscanl, iscanl', prescanr, prescanr', postscanr, postscanr', scanr, scanr', scanr1, scanr1',+ iscanr, iscanr', + -- ** Comparisons+ eqBy, cmpBy,+ -- * Conversions -- ** Lists@@ -163,6 +171,9 @@ filter, takeWhile, dropWhile, span, break, elem, notElem, foldl, foldl1, foldr, foldr1,+#if __GLASGOW_HASKELL__ >= 706+ foldMap,+#endif all, any, sum, product, minimum, maximum, scanl, scanl1, scanr, scanr1, enumFromTo, enumFromThenTo,@@ -441,10 +452,26 @@ -- -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ -- but slightly more efficient.-{-# INLINE splitAt #-}+--+-- @since 0.7.1 splitAt :: Prim a => Int -> Vector a -> (Vector a, Vector a)+{-# INLINE splitAt #-} splitAt = G.splitAt +-- | /O(1)/ Yield the 'head' and 'tail' of the vector, or 'Nothing' if empty.+--+-- @since 0.12.2.0+uncons :: Prim a => Vector a -> Maybe (a, Vector a)+{-# INLINE uncons #-}+uncons = G.uncons++-- | /O(1)/ Yield the 'last' and 'init' of the vector, or 'Nothing' if empty.+--+-- @since 0.12.2.0+unsnoc :: Prim a => Vector a -> Maybe (Vector a, a)+{-# INLINE unsnoc #-}+unsnoc = G.unsnoc+ -- | /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@@ -502,7 +529,21 @@ {-# INLINE generate #-} generate = G.generate --- | /O(n)/ Apply function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply function \(\max(n - 1, 0)\) times to an initial value, producing a vector+-- of length \(\max(n, 0)\). Zeroth element will contain the initial value, that's why there+-- is one less function application than the number of elements in the produced vector.+--+-- \( \underbrace{x, f (x), f (f (x)), \ldots}_{\max(0,n)\rm{~elements}} \)+--+-- ===__Examples__+--+-- >>> import qualified Data.Vector.Primitive as VP+-- >>> VP.iterateN 0 undefined undefined :: VP.Vector Int+-- []+-- >>> VP.iterateN 26 succ 'a'+-- "abcdefghijklmnopqrstuvwxyz"+--+-- @since 0.7.1 iterateN :: Prim a => Int -> (a -> a) -> a -> Vector a {-# INLINE iterateN #-} iterateN = G.iterateN@@ -529,6 +570,17 @@ {-# INLINE unfoldrN #-} unfoldrN = G.unfoldrN +-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying+-- the generator function to a seed. The generator function yields the+-- next element and the new seed.+--+-- > unfoldrExactN 3 (\n -> (n,n-1)) 10 = <10,9,8>+--+-- @since 0.12.2.0+unfoldrExactN :: (Prim a) => Int -> (b -> (a, b)) -> b -> Vector a+{-# INLINE unfoldrExactN #-}+unfoldrExactN = G.unfoldrExactN+ -- | /O(n)/ Construct a vector by repeatedly applying the monadic -- generator function to a seed. The generator function yields 'Just' -- the next element and the new seed or 'Nothing' if there are no more@@ -545,6 +597,15 @@ {-# INLINE unfoldrNM #-} unfoldrNM = G.unfoldrNM +-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly+-- applying the monadic generator function to a seed. The generator+-- function yields the next element and the new seed.+--+-- @since 0.12.2.0+unfoldrExactNM :: (Monad m, Prim a) => Int -> (b -> m (a, b)) -> b -> m (Vector a)+{-# INLINE unfoldrExactNM #-}+unfoldrExactNM = G.unfoldrExactNM+ -- | /O(n)/ Construct a vector with @n@ elements by repeatedly applying the -- generator function to the already constructed part of the vector. --@@ -638,7 +699,13 @@ {-# INLINE generateM #-} generateM = G.generateM --- | /O(n)/ Apply monadic function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply monadic function \(\max(n - 1, 0)\) times to an initial value, producing a vector+-- of length \(\max(n, 0)\). Zeroth element will contain the initial value, that's why there+-- is one less function application than the number of elements in the produced vector.+--+-- For non-monadic version see `iterateN`+--+-- @since 0.12.0.0 iterateNM :: (Monad m, Prim a) => Int -> (a -> m a) -> a -> m (Vector a) {-# INLINE iterateNM #-} iterateNM = G.iterateNM@@ -719,7 +786,11 @@ -- | /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>+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Primitive as VP+-- >>> VP.accum (+) (VP.fromList [1000.0,2000.0,3000.0]) [(2,4),(1,6),(0,3),(1,10)]+-- [1003.0,2016.0,3004.0] accum :: Prim a => (a -> b -> a) -- ^ accumulating function @f@ -> Vector a -- ^ initial vector (of length @m@)@@ -818,12 +889,29 @@ {-# INLINE mapM #-} mapM = G.mapM +-- | /O(n)/ Apply the monadic action to every element of a vector and its+-- index, yielding a vector of results+--+-- @since 0.12.2.0+imapM :: (Monad m, Prim a, Prim b)+ => (Int -> a -> m b) -> Vector a -> m (Vector b)+{-# INLINE imapM #-}+imapM = G.imapM+ -- | /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 every element of a vector and its+-- index, ignoring the results+--+-- @since 0.12.2.0+imapM_ :: (Monad m, Prim a) => (Int -> a -> m b) -> Vector a -> m ()+{-# INLINE imapM_ #-}+imapM_ = G.imapM_+ -- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a -- vector of results. Equivalent to @flip 'mapM'@. forM :: (Monad m, Prim a, Prim b) => Vector a -> (a -> m b) -> m (Vector b)@@ -836,6 +924,22 @@ {-# INLINE forM_ #-} forM_ = G.forM_ +-- | /O(n)/ Apply the monadic action to all elements of the vector and their indices, yielding a+-- vector of results. Equivalent to 'flip' 'imapM'.+--+-- @since 0.12.2.0+iforM :: (Monad m, Prim a, Prim b) => Vector a -> (Int -> a -> m b) -> m (Vector b)+{-# INLINE iforM #-}+iforM = G.iforM++-- | /O(n)/ Apply the monadic action to all elements of the vector and their indices and ignore the+-- results. Equivalent to 'flip' 'imapM_'.+--+-- @since 0.12.2.0+iforM_ :: (Monad m, Prim a) => Vector a -> (Int -> a -> m b) -> m ()+{-# INLINE iforM_ #-}+iforM_ = G.iforM_+ -- Zipping -- ------- @@ -919,6 +1023,15 @@ {-# INLINE zipWithM #-} zipWithM = G.zipWithM +-- | /O(min(m,n))/ Zip the two vectors with a monadic action that also takes+-- the element index and yield a vector of results+--+-- @since 0.12.2.0+izipWithM :: (Monad m, Prim a, Prim b, Prim c)+ => (Int -> a -> b -> m c) -> Vector a -> Vector b -> m (Vector c)+{-# INLINE izipWithM #-}+izipWithM = G.izipWithM+ -- | /O(min(m,n))/ Zip the two vectors with the monadic action and ignore the -- results zipWithM_ :: (Monad m, Prim a, Prim b)@@ -926,6 +1039,15 @@ {-# INLINE zipWithM_ #-} zipWithM_ = G.zipWithM_ +-- | /O(min(m,n))/ Zip the two vectors with a monadic action that also takes+-- the element index and ignore the results+--+-- @since 0.12.2.0+izipWithM_ :: (Monad m, Prim a, Prim b)+ => (Int -> a -> b -> m c) -> Vector a -> Vector b -> m ()+{-# INLINE izipWithM_ #-}+izipWithM_ = G.izipWithM_+ -- Filtering -- --------- @@ -950,18 +1072,39 @@ {-# INLINE mapMaybe #-} mapMaybe = G.mapMaybe +-- | /O(n)/ Apply monadic function to each element of vector and+-- discard elements returning Nothing.+--+-- @since 0.12.2.0+mapMaybeM+ :: (Monad m, Prim a, Prim b)+ => (a -> m (Maybe b)) -> Vector a -> m (Vector b)+{-# INLINE mapMaybeM #-}+mapMaybeM = G.mapMaybeM+ -- | /O(n)/ Drop elements when predicate, applied to index and value, returns Nothing imapMaybe :: (Prim a, Prim b) => (Int -> a -> Maybe b) -> Vector a -> Vector b {-# INLINE imapMaybe #-} imapMaybe = G.imapMaybe +-- | /O(n)/ Apply monadic function to each element of vector and its index.+-- Discards elements returning Nothing.+--+-- @since 0.12.2.0+imapMaybeM+ :: (Monad m, Prim a, Prim b)+ => (Int -> a -> m (Maybe b)) -> Vector a -> m (Vector b)+{-# INLINE imapMaybeM #-}+imapMaybeM = G.imapMaybeM+ -- | /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.+-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate.+-- Current implementation is not copy-free, unless the result vector is+-- fused away. takeWhile :: Prim a => (a -> Bool) -> Vector a -> Vector a {-# INLINE takeWhile #-} takeWhile = G.takeWhile@@ -991,11 +1134,11 @@ {-# INLINE unstablePartition #-} unstablePartition = G.unstablePartition --- | /O(n)/ Split the vector in two parts, the first one containing the--- @Right@ elements and the second containing the @Left@ elements.--- The relative order of the elements is preserved.+-- | /O(n)/ Split the vector into two parts, the first one containing the+-- @`Left`@ elements and the second containing the @`Right`@ elements.+-- The relative order of the elements is preserved. ----- @since 0.12.1.0+-- @since 0.12.1.0 partitionWith :: (Prim a, Prim b, Prim c) => (a -> Either b c) -> Vector a -> (Vector b, Vector c) {-# INLINE partitionWith #-} partitionWith = G.partitionWith@@ -1123,31 +1266,94 @@ {-# INLINE ifoldr' #-} ifoldr' = G.ifoldr' +-- | /O(n)/ Map each element of the structure to a monoid, and combine+-- the results. It uses same implementation as corresponding method of+-- 'Foldable' type cless. Note it's implemented in terms of 'foldr'+-- and won't fuse with functions that traverse vector from left to+-- right ('map', 'generate', etc.).+--+-- @since 0.12.2.0+foldMap :: (Monoid m, Prim a) => (a -> m) -> Vector a -> m+{-# INLINE foldMap #-}+foldMap = G.foldMap++-- | /O(n)/ 'foldMap' which is strict in accumulator. It uses same+-- implementation as corresponding method of 'Foldable' type class.+-- Note it's implemented in terms of 'foldl'' so it fuses in most+-- contexts.+--+-- @since 0.12.2.0+foldMap' :: (Monoid m, Prim a) => (a -> m) -> Vector a -> m+{-# INLINE foldMap' #-}+foldMap' = G.foldMap'+ -- Specialised folds -- ----------------- -- | /O(n)/ Check if all elements satisfy the predicate.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Primitive as VP+-- >>> VP.all even $ VP.fromList [2, 4, 12 :: Int]+-- True+-- >>> VP.all even $ VP.fromList [2, 4, 13 :: Int]+-- False+-- >>> VP.all even (VP.empty :: VP.Vector Int)+-- True all :: Prim a => (a -> Bool) -> Vector a -> Bool {-# INLINE all #-} all = G.all -- | /O(n)/ Check if any element satisfies the predicate.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Primitive as VP+-- >>> VP.any even $ VP.fromList [1, 3, 7 :: Int]+-- False+-- >>> VP.any even $ VP.fromList [3, 2, 13 :: Int]+-- True+-- >>> VP.any even (VP.empty :: VP.Vector Int)+-- False any :: Prim a => (a -> Bool) -> Vector a -> Bool {-# INLINE any #-} any = G.any -- | /O(n)/ Compute the sum of the elements+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Primitive as VP+-- >>> VP.sum $ VP.fromList [300,20,1 :: Int]+-- 321+-- >>> VP.sum (VP.empty :: VP.Vector Int)+-- 0 sum :: (Prim a, Num a) => Vector a -> a {-# INLINE sum #-} sum = G.sum -- | /O(n)/ Compute the produce of the elements+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Primitive as VP+-- >>> VP.product $ VP.fromList [1,2,3,4 :: Int]+-- 24+-- >>> VP.product (VP.empty :: VP.Vector Int)+-- 1 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.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Primitive as VP+-- >>> VP.maximum $ VP.fromList [2.0, 1.0]+-- 2.0 maximum :: (Prim a, Ord a) => Vector a -> a {-# INLINE maximum #-} maximum = G.maximum@@ -1160,6 +1366,12 @@ -- | /O(n)/ Yield the minimum element of the vector. The vector may not be -- empty.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Primitive as VP+-- >>> VP.minimum $ VP.fromList [2.0, 1.0]+-- 1.0 minimum :: (Prim a, Ord a) => Vector a -> a {-# INLINE minimum #-} minimum = G.minimum@@ -1202,6 +1414,13 @@ {-# INLINE foldM #-} foldM = G.foldM +-- | /O(n)/ Monadic fold (action applied to each element and its index)+--+-- @since 0.12.2.0+ifoldM :: (Monad m, Prim b) => (a -> Int -> b -> m a) -> a -> Vector b -> m a+{-# INLINE ifoldM #-}+ifoldM = G.ifoldM+ -- | /O(n)/ Monadic fold over non-empty vectors fold1M :: (Monad m, Prim a) => (a -> a -> m a) -> Vector a -> m a {-# INLINE fold1M #-}@@ -1212,6 +1431,14 @@ {-# INLINE foldM' #-} foldM' = G.foldM' +-- | /O(n)/ Monadic fold with strict accumulator (action applied to each+-- element and its index)+--+-- @since 0.12.2.0+ifoldM' :: (Monad m, Prim b) => (a -> Int -> b -> m a) -> a -> Vector b -> m a+{-# INLINE ifoldM' #-}+ifoldM' = G.ifoldM'+ -- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator fold1M' :: (Monad m, Prim a) => (a -> a -> m a) -> Vector a -> m a {-# INLINE fold1M' #-}@@ -1222,6 +1449,14 @@ {-# INLINE foldM_ #-} foldM_ = G.foldM_ +-- | /O(n)/ Monadic fold that discards the result (action applied to each+-- element and its index)+--+-- @since 0.12.2.0+ifoldM_ :: (Monad m, Prim b) => (a -> Int -> b -> m a) -> a -> Vector b -> m ()+{-# INLINE ifoldM_ #-}+ifoldM_ = G.ifoldM_+ -- | /O(n)/ Monadic fold over non-empty vectors that discards the result fold1M_ :: (Monad m, Prim a) => (a -> a -> m a) -> Vector a -> m () {-# INLINE fold1M_ #-}@@ -1232,6 +1467,15 @@ {-# INLINE foldM'_ #-} foldM'_ = G.foldM'_ +-- | /O(n)/ Monadic fold with strict accumulator that discards the result+-- (action applied to each element and its index)+--+-- @since 0.12.2.0+ifoldM'_ :: (Monad m, Prim b)+ => (a -> Int -> b -> m a) -> a -> Vector b -> m ()+{-# INLINE ifoldM'_ #-}+ifoldM'_ = G.ifoldM'_+ -- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator -- that discards the result fold1M'_ :: (Monad m, Prim a) => (a -> a -> m a) -> Vector a -> m ()@@ -1292,6 +1536,21 @@ {-# INLINE scanl' #-} scanl' = G.scanl' +-- | /O(n)/ Scan over a vector with its index+--+-- @since 0.12.2.0+iscanl :: (Prim a, Prim b) => (Int -> a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE iscanl #-}+iscanl = G.iscanl++-- | /O(n)/ Scan over a vector (strictly) with its index+--+-- @since 0.12.2.0+iscanl' :: (Prim a, Prim b) => (Int -> a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE iscanl' #-}+iscanl' = G.iscanl'++ -- | /O(n)/ Scan over a non-empty vector -- -- > scanl f <x1,...,xn> = <y1,...,yn>@@ -1342,6 +1601,20 @@ {-# INLINE scanr' #-} scanr' = G.scanr' +-- | /O(n)/ Right-to-left scan over a vector with its index+--+-- @since 0.12.2.0+iscanr :: (Prim a, Prim b) => (Int -> a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE iscanr #-}+iscanr = G.iscanr++-- | /O(n)/ Right-to-left scan over a vector (strictly) with its index+--+-- @since 0.12.2.0+iscanr' :: (Prim a, Prim b) => (Int -> a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE iscanr' #-}+iscanr' = G.iscanr'+ -- | /O(n)/ Right-to-left scan over a non-empty vector scanr1 :: Prim a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanr1 #-}@@ -1353,6 +1626,26 @@ {-# INLINE scanr1' #-} scanr1' = G.scanr1' +-- Comparisons+-- ------------------------++-- | /O(n)/ Check if two vectors are equal using supplied equality+-- predicate.+--+-- @since 0.12.2.0+eqBy :: (Prim a, Prim b) => (a -> b -> Bool) -> Vector a -> Vector b -> Bool+{-# INLINE eqBy #-}+eqBy = G.eqBy++-- | /O(n)/ Compare two vectors using supplied comparison function for+-- vector elements. Comparison works same as for lists.+--+-- > cmpBy compare == compare+--+-- @since 0.12.2.0+cmpBy :: (Prim a, Prim b) => (a -> b -> Ordering) -> Vector a -> Vector b -> Ordering+cmpBy = G.cmpBy+ -- Conversions - Lists -- ------------------------ @@ -1371,6 +1664,14 @@ -- @ -- fromListN n xs = 'fromList' ('take' n xs) -- @+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Primitive as VP+-- >>> VP.fromListN 3 [1,2,3,4,5::Int]+-- [1,2,3]+-- >>> VP.fromListN 3 [1::Int]+-- [1] fromListN :: Prim a => Int -> [a] -> Vector a {-# INLINE fromListN #-} fromListN = G.fromListN
Data/Vector/Primitive/Mutable.hs view
@@ -226,7 +226,11 @@ {-# INLINE new #-} new = G.new --- | Create a mutable vector of the given length. The memory is not initialized.+-- | Create a mutable vector of the given length. The vector content+-- is uninitialized, which means it is filled with whatever underlying memory+-- buffer happens to contain.+--+-- @since 0.5 unsafeNew :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a) {-# INLINE unsafeNew #-} unsafeNew = G.unsafeNew@@ -252,15 +256,50 @@ -- Growing -- ------- --- | Grow a vector by the given number of elements. The number must be--- positive.+-- | Grow a primitive vector by the given number of elements. The number must be+-- non-negative. Same semantics as in `G.grow` for generic vector.+--+-- ====__Examples__+--+-- >>> import qualified Data.Vector.Primitive as VP+-- >>> import qualified Data.Vector.Primitive.Mutable as MVP+-- >>> mv <- VP.thaw $ VP.fromList ([10, 20, 30] :: [Int])+-- >>> mv' <- MVP.grow mv 2+--+-- Extra memory at the end of the newly allocated vector is initialized to 0+-- bytes, which for `Prim` instance will usually correspond to some default+-- value for a particular type, eg. @0@ for @Int@, @\NUL@ for @Char@,+-- etc. However, if `unsafeGrow` was used instead this would not have been+-- guaranteed and some garbage would be there instead:+--+-- >>> VP.unsafeFreeze mv'+-- [10,20,30,0,0]+--+-- Having the extra space we can write new values in there:+--+-- >>> MVP.write mv' 3 999+-- >>> VP.unsafeFreeze mv'+-- [10,20,30,999,0]+--+-- It is important to note that the source mutable vector is not affected when+-- the newly allocated one is mutated.+--+-- >>> MVP.write mv' 2 888+-- >>> VP.unsafeFreeze mv'+-- [10,20,888,999,0]+-- >>> VP.unsafeFreeze mv+-- [10,20,30]+--+-- @since 0.5 grow :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a) {-# INLINE grow #-} grow = G.grow --- | Grow a vector by the given number of elements. The number must be--- positive but this is not checked.+-- | Grow a vector by the given number of elements. The number must be non-negative but+-- this is not checked. Same semantics as in `G.unsafeGrow` for generic vector.+--+-- @since 0.5 unsafeGrow :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a) {-# INLINE unsafeGrow #-}
Data/Vector/Storable.hs view
@@ -31,7 +31,7 @@ unsafeIndexM, unsafeHeadM, unsafeLastM, -- ** Extracting subvectors (slicing)- slice, init, tail, take, drop, splitAt,+ slice, init, tail, take, drop, splitAt, uncons, unsnoc, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, -- * Construction@@ -43,8 +43,8 @@ replicateM, generateM, iterateNM, create, createT, -- ** Unfolding- unfoldr, unfoldrN,- unfoldrM, unfoldrNM,+ unfoldr, unfoldrN, unfoldrExactN,+ unfoldrM, unfoldrNM, unfoldrExactNM, constructN, constructrN, -- ** Enumeration@@ -78,21 +78,22 @@ map, imap, concatMap, -- ** Monadic mapping- mapM, mapM_, forM, forM_,+ mapM, imapM, mapM_, imapM_, forM, forM_,+ iforM, iforM_, -- ** Zipping zipWith, zipWith3, zipWith4, zipWith5, zipWith6, izipWith, izipWith3, izipWith4, izipWith5, izipWith6, -- ** Monadic zipping- zipWithM, zipWithM_,+ zipWithM, izipWithM, zipWithM_, izipWithM_, -- * Working with predicates -- ** Filtering- filter, ifilter, uniq,+ filter, ifilter, filterM, uniq, mapMaybe, imapMaybe,- filterM,+ mapMaybeM, imapMaybeM, takeWhile, dropWhile, -- ** Partitioning@@ -104,6 +105,7 @@ -- * Folding foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1', ifoldl, ifoldl', ifoldr, ifoldr',+ foldMap, foldMap', -- ** Specialised folds all, any, and, or,@@ -112,17 +114,27 @@ minIndex, minIndexBy, maxIndex, maxIndexBy, -- ** Monadic folds- foldM, foldM', fold1M, fold1M',- foldM_, foldM'_, fold1M_, fold1M'_,+ foldM, ifoldM, foldM', ifoldM',+ fold1M, fold1M', foldM_, ifoldM_,+ foldM'_, ifoldM'_, fold1M_, fold1M'_, -- * Prefix sums (scans) prescanl, prescanl', postscanl, postscanl', scanl, scanl', scanl1, scanl1',+ iscanl, iscanl', prescanr, prescanr', postscanr, postscanr', scanr, scanr', scanr1, scanr1',+ iscanr, iscanr', + -- ** Comparisons+ eqBy, cmpBy,++ -- * Utilities+ -- ** Comparisons+ isSameVector,+ -- * Conversions -- ** Lists@@ -168,6 +180,9 @@ filter, takeWhile, dropWhile, span, break, elem, notElem, foldl, foldl1, foldr, foldr1,+#if __GLASGOW_HASKELL__ >= 706+ foldMap,+#endif all, any, and, or, sum, product, minimum, maximum, scanl, scanl1, scanr, scanr1, enumFromTo, enumFromThenTo,@@ -453,10 +468,26 @@ -- -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ -- but slightly more efficient.-{-# INLINE splitAt #-}+--+-- @since 0.7.1 splitAt :: Storable a => Int -> Vector a -> (Vector a, Vector a)+{-# INLINE splitAt #-} splitAt = G.splitAt +-- | /O(1)/ Yield the 'head' and 'tail' of the vector, or 'Nothing' if empty.+--+-- @since 0.12.2.0+uncons :: Storable a => Vector a -> Maybe (a, Vector a)+{-# INLINE uncons #-}+uncons = G.uncons++-- | /O(1)/ Yield the 'last' and 'init' of the vector, or 'Nothing' if empty.+--+-- @since 0.12.2.0+unsnoc :: Storable a => Vector a -> Maybe (Vector a, a)+{-# INLINE unsnoc #-}+unsnoc = G.unsnoc+ -- | /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@@ -514,7 +545,21 @@ {-# INLINE generate #-} generate = G.generate --- | /O(n)/ Apply function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply function \(\max(n - 1, 0)\) times to an initial value, producing a vector+-- of length \(\max(n, 0)\). Zeroth element will contain the initial value, that's why there+-- is one less function application than the number of elements in the produced vector.+--+-- \( \underbrace{x, f (x), f (f (x)), \ldots}_{\max(0,n)\rm{~elements}} \)+--+-- ===__Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> VS.iterateN 0 undefined undefined :: VS.Vector Int+-- []+-- >>> VS.iterateN 26 succ 'a'+-- "abcdefghijklmnopqrstuvwxyz"+--+-- @since 0.7.1 iterateN :: Storable a => Int -> (a -> a) -> a -> Vector a {-# INLINE iterateN #-} iterateN = G.iterateN@@ -541,6 +586,17 @@ {-# INLINE unfoldrN #-} unfoldrN = G.unfoldrN +-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying+-- the generator function to a seed. The generator function yields the+-- next element and the new seed.+--+-- > unfoldrExactN 3 (\n -> (n,n-1)) 10 = <10,9,8>+--+-- @since 0.12.2.0+unfoldrExactN :: (Storable a) => Int -> (b -> (a, b)) -> b -> Vector a+{-# INLINE unfoldrExactN #-}+unfoldrExactN = G.unfoldrExactN+ -- | /O(n)/ Construct a vector by repeatedly applying the monadic -- generator function to a seed. The generator function yields 'Just' -- the next element and the new seed or 'Nothing' if there are no more@@ -557,6 +613,15 @@ {-# INLINE unfoldrNM #-} unfoldrNM = G.unfoldrNM +-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly+-- applying the monadic generator function to a seed. The generator+-- function yields the next element and the new seed.+--+-- @since 0.12.2.0+unfoldrExactNM :: (Monad m, Storable a) => Int -> (b -> m (a, b)) -> b -> m (Vector a)+{-# INLINE unfoldrExactNM #-}+unfoldrExactNM = G.unfoldrExactNM+ -- | /O(n)/ Construct a vector with @n@ elements by repeatedly applying the -- generator function to the already constructed part of the vector. --@@ -650,7 +715,13 @@ {-# INLINE generateM #-} generateM = G.generateM --- | /O(n)/ Apply monadic function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply monadic function \(\max(n - 1, 0)\) times to an initial value, producing a vector+-- of length \(\max(n, 0)\). Zeroth element will contain the initial value, that's why there+-- is one less function application than the number of elements in the produced vector.+--+-- For non-monadic version see `iterateN`+--+-- @since 0.12.0.0 iterateNM :: (Monad m, Storable a) => Int -> (a -> m a) -> a -> m (Vector a) {-# INLINE iterateNM #-} iterateNM = G.iterateNM@@ -731,7 +802,11 @@ -- | /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>+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> VS.accum (+) (VS.fromList [1000.0,2000.0,3000.0]) [(2,4),(1,6),(0,3),(1,10)]+-- [1003.0,2016.0,3004.0] accum :: Storable a => (a -> b -> a) -- ^ accumulating function @f@ -> Vector a -- ^ initial vector (of length @m@)@@ -830,12 +905,29 @@ {-# INLINE mapM #-} mapM = G.mapM +-- | /O(n)/ Apply the monadic action to every element of a vector and its+-- index, yielding a vector of results+--+-- @since 0.12.2.0+imapM :: (Monad m, Storable a, Storable b)+ => (Int -> a -> m b) -> Vector a -> m (Vector b)+{-# INLINE imapM #-}+imapM = G.imapM+ -- | /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 every element of a vector and its+-- index, ignoring the results+--+-- @since 0.12.2.0+imapM_ :: (Monad m, Storable a) => (Int -> a -> m b) -> Vector a -> m ()+{-# INLINE imapM_ #-}+imapM_ = G.imapM_+ -- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a -- vector of results. Equivalent to @flip 'mapM'@. forM :: (Monad m, Storable a, Storable b) => Vector a -> (a -> m b) -> m (Vector b)@@ -848,6 +940,22 @@ {-# INLINE forM_ #-} forM_ = G.forM_ +-- | /O(n)/ Apply the monadic action to all elements of the vector and their indices, yielding a+-- vector of results. Equivalent to 'flip' 'imapM'.+--+-- @since 0.12.2.0+iforM :: (Monad m, Storable a, Storable b) => Vector a -> (Int -> a -> m b) -> m (Vector b)+{-# INLINE iforM #-}+iforM = G.iforM++-- | /O(n)/ Apply the monadic action to all elements of the vector and their indices and ignore the+-- results. Equivalent to 'flip' 'imapM_'.+--+-- @since 0.12.2.0+iforM_ :: (Monad m, Storable a) => Vector a -> (Int -> a -> m b) -> m ()+{-# INLINE iforM_ #-}+iforM_ = G.iforM_+ -- Zipping -- ------- @@ -921,6 +1029,16 @@ {-# INLINE izipWith6 #-} izipWith6 = G.izipWith6 +-- | Checks whether two values are same vector: they have same length+-- and share same buffer.+--+-- >>> let xs = fromList [0/0::Double] in isSameVector xs xs+-- True+isSameVector :: (Storable a) => Vector a -> Vector a -> Bool+{-# INLINE isSameVector #-}+isSameVector (Vector n1 ptr1) (Vector n2 ptr2) = n1 == n2 && ptr1 == ptr2++ -- Monadic zipping -- --------------- @@ -931,6 +1049,15 @@ {-# INLINE zipWithM #-} zipWithM = G.zipWithM +-- | /O(min(m,n))/ Zip the two vectors with a monadic action that also takes+-- the element index and yield a vector of results+--+-- @since 0.12.2.0+izipWithM :: (Monad m, Storable a, Storable b, Storable c)+ => (Int -> a -> b -> m c) -> Vector a -> Vector b -> m (Vector c)+{-# INLINE izipWithM #-}+izipWithM = G.izipWithM+ -- | /O(min(m,n))/ Zip the two vectors with the monadic action and ignore the -- results zipWithM_ :: (Monad m, Storable a, Storable b)@@ -938,6 +1065,15 @@ {-# INLINE zipWithM_ #-} zipWithM_ = G.zipWithM_ +-- | /O(min(m,n))/ Zip the two vectors with a monadic action that also takes+-- the element index and ignore the results+--+-- @since 0.12.2.0+izipWithM_ :: (Monad m, Storable a, Storable b)+ => (Int -> a -> b -> m c) -> Vector a -> Vector b -> m ()+{-# INLINE izipWithM_ #-}+izipWithM_ = G.izipWithM_+ -- Filtering -- --------- @@ -967,13 +1103,34 @@ {-# INLINE imapMaybe #-} imapMaybe = G.imapMaybe +-- | /O(n)/ Apply monadic function to each element of vector and+-- discard elements returning Nothing.+--+-- @since 0.12.2.0+mapMaybeM+ :: (Monad m, Storable a, Storable b)+ => (a -> m (Maybe b)) -> Vector a -> m (Vector b)+{-# INLINE mapMaybeM #-}+mapMaybeM = G.mapMaybeM++-- | /O(n)/ Apply monadic function to each element of vector and its index.+-- Discards elements returning Nothing.+--+-- @since 0.12.2.0+imapMaybeM+ :: (Monad m, Storable a, Storable b)+ => (Int -> a -> m (Maybe b)) -> Vector a -> m (Vector b)+{-# INLINE imapMaybeM #-}+imapMaybeM = G.imapMaybeM+ -- | /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.+-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate.+-- Current implementation is not copy-free, unless the result vector is+-- fused away. takeWhile :: Storable a => (a -> Bool) -> Vector a -> Vector a {-# INLINE takeWhile #-} takeWhile = G.takeWhile@@ -1003,11 +1160,11 @@ {-# INLINE unstablePartition #-} unstablePartition = G.unstablePartition --- | /O(n)/ Split the vector in two parts, the first one containing the--- @Right@ elements and the second containing the @Left@ elements.--- The relative order of the elements is preserved.+-- | /O(n)/ Split the vector into two parts, the first one containing the+-- @`Left`@ elements and the second containing the @`Right`@ elements.+-- The relative order of the elements is preserved. ----- @since 0.12.1.0+-- @since 0.12.1.0 partitionWith :: (Storable a, Storable b, Storable c) => (a -> Either b c) -> Vector a -> (Vector b, Vector c) {-# INLINE partitionWith #-} partitionWith = G.partitionWith@@ -1135,41 +1292,120 @@ {-# INLINE ifoldr' #-} ifoldr' = G.ifoldr' +-- | /O(n)/ Map each element of the structure to a monoid, and combine+-- the results. It uses same implementation as corresponding method of+-- 'Foldable' type cless. Note it's implemented in terms of 'foldr'+-- and won't fuse with functions that traverse vector from left to+-- right ('map', 'generate', etc.).+--+-- @since 0.12.2.0+foldMap :: (Monoid m, Storable a) => (a -> m) -> Vector a -> m+{-# INLINE foldMap #-}+foldMap = G.foldMap++-- | /O(n)/ 'foldMap' which is strict in accumulator. It uses same+-- implementation as corresponding method of 'Foldable' type class.+-- Note it's implemented in terms of 'foldl'' so it fuses in most+-- contexts.+--+-- @since 0.12.2.0+foldMap' :: (Monoid m, Storable a) => (a -> m) -> Vector a -> m+{-# INLINE foldMap' #-}+foldMap' = G.foldMap'+ -- Specialised folds -- ----------------- -- | /O(n)/ Check if all elements satisfy the predicate.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> VS.all even $ VS.fromList [2, 4, 12 :: Int]+-- True+-- >>> VS.all even $ VS.fromList [2, 4, 13 :: Int]+-- False+-- >>> VS.all even (VS.empty :: VS.Vector Int)+-- True all :: Storable a => (a -> Bool) -> Vector a -> Bool {-# INLINE all #-} all = G.all -- | /O(n)/ Check if any element satisfies the predicate.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> VS.any even $ VS.fromList [1, 3, 7 :: Int]+-- False+-- >>> VS.any even $ VS.fromList [3, 2, 13 :: Int]+-- True+-- >>> VS.any even (VS.empty :: VS.Vector Int)+-- False any :: Storable a => (a -> Bool) -> Vector a -> Bool {-# INLINE any #-} any = G.any -- | /O(n)/ Check if all elements are 'True'+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> VS.and $ VS.fromList [True, False]+-- False+-- >>> VS.and VS.empty+-- True and :: Vector Bool -> Bool {-# INLINE and #-} and = G.and -- | /O(n)/ Check if any element is 'True'+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> VS.or $ VS.fromList [True, False]+-- True+-- >>> VS.or VS.empty+-- False or :: Vector Bool -> Bool {-# INLINE or #-} or = G.or -- | /O(n)/ Compute the sum of the elements+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> VS.sum $ VS.fromList [300,20,1 :: Int]+-- 321+-- >>> VS.sum (VS.empty :: VS.Vector Int)+-- 0 sum :: (Storable a, Num a) => Vector a -> a {-# INLINE sum #-} sum = G.sum -- | /O(n)/ Compute the produce of the elements+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> VS.product $ VS.fromList [1,2,3,4 :: Int]+-- 24+-- >>> VS.product (VS.empty :: VS.Vector Int)+-- 1 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.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> VS.maximum $ VS.fromList [2.0, 1.0]+-- 2.0 maximum :: (Storable a, Ord a) => Vector a -> a {-# INLINE maximum #-} maximum = G.maximum@@ -1182,6 +1418,12 @@ -- | /O(n)/ Yield the minimum element of the vector. The vector may not be -- empty.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> VS.minimum $ VS.fromList [2.0, 1.0]+-- 1.0 minimum :: (Storable a, Ord a) => Vector a -> a {-# INLINE minimum #-} minimum = G.minimum@@ -1224,6 +1466,13 @@ {-# INLINE foldM #-} foldM = G.foldM +-- | /O(n)/ Monadic fold (action applied to each element and its index)+--+-- @since 0.12.2.0+ifoldM :: (Monad m, Storable b) => (a -> Int -> b -> m a) -> a -> Vector b -> m a+{-# INLINE ifoldM #-}+ifoldM = G.ifoldM+ -- | /O(n)/ Monadic fold over non-empty vectors fold1M :: (Monad m, Storable a) => (a -> a -> m a) -> Vector a -> m a {-# INLINE fold1M #-}@@ -1234,6 +1483,14 @@ {-# INLINE foldM' #-} foldM' = G.foldM' +-- | /O(n)/ Monadic fold with strict accumulator (action applied to each+-- element and its index)+--+-- @since 0.12.2.0+ifoldM' :: (Monad m, Storable b) => (a -> Int -> b -> m a) -> a -> Vector b -> m a+{-# INLINE ifoldM' #-}+ifoldM' = G.ifoldM'+ -- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator fold1M' :: (Monad m, Storable a) => (a -> a -> m a) -> Vector a -> m a {-# INLINE fold1M' #-}@@ -1244,6 +1501,14 @@ {-# INLINE foldM_ #-} foldM_ = G.foldM_ +-- | /O(n)/ Monadic fold that discards the result (action applied to each+-- element and its index)+--+-- @since 0.12.2.0+ifoldM_ :: (Monad m, Storable b) => (a -> Int -> b -> m a) -> a -> Vector b -> m ()+{-# INLINE ifoldM_ #-}+ifoldM_ = G.ifoldM_+ -- | /O(n)/ Monadic fold over non-empty vectors that discards the result fold1M_ :: (Monad m, Storable a) => (a -> a -> m a) -> Vector a -> m () {-# INLINE fold1M_ #-}@@ -1254,6 +1519,15 @@ {-# INLINE foldM'_ #-} foldM'_ = G.foldM'_ +-- | /O(n)/ Monadic fold with strict accumulator that discards the result+-- (action applied to each element and its index)+--+-- @since 0.12.2.0+ifoldM'_ :: (Monad m, Storable b)+ => (a -> Int -> b -> m a) -> a -> Vector b -> m ()+{-# INLINE ifoldM'_ #-}+ifoldM'_ = G.ifoldM'_+ -- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator -- that discards the result fold1M'_ :: (Monad m, Storable a) => (a -> a -> m a) -> Vector a -> m ()@@ -1314,6 +1588,20 @@ {-# INLINE scanl' #-} scanl' = G.scanl' +-- | /O(n)/ Scan over a vector with its index+--+-- @since 0.12.2.0+iscanl :: (Storable a, Storable b) => (Int -> a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE iscanl #-}+iscanl = G.iscanl++-- | /O(n)/ Scan over a vector (strictly) with its index+--+-- @since 0.12.2.0+iscanl' :: (Storable a, Storable b) => (Int -> a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE iscanl' #-}+iscanl' = G.iscanl'+ -- | /O(n)/ Scan over a non-empty vector -- -- > scanl f <x1,...,xn> = <y1,...,yn>@@ -1364,6 +1652,20 @@ {-# INLINE scanr' #-} scanr' = G.scanr' +-- | /O(n)/ Right-to-left scan over a vector with its index+--+-- @since 0.12.2.0+iscanr :: (Storable a, Storable b) => (Int -> a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE iscanr #-}+iscanr = G.iscanr++-- | /O(n)/ Right-to-left scan over a vector (strictly) with its index+--+-- @since 0.12.2.0+iscanr' :: (Storable a, Storable b) => (Int -> a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE iscanr' #-}+iscanr' = G.iscanr'+ -- | /O(n)/ Right-to-left scan over a non-empty vector scanr1 :: Storable a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanr1 #-}@@ -1375,6 +1677,26 @@ {-# INLINE scanr1' #-} scanr1' = G.scanr1' +-- Comparisons+-- ------------------------++-- | /O(n)/ Check if two vectors are equal using supplied equality+-- predicate.+--+-- @since 0.12.2.0+eqBy :: (Storable a, Storable b) => (a -> b -> Bool) -> Vector a -> Vector b -> Bool+{-# INLINE eqBy #-}+eqBy = G.eqBy++-- | /O(n)/ Compare two vectors using supplied comparison function for+-- vector elements. Comparison works same as for lists.+--+-- > cmpBy compare == compare+--+-- @since 0.12.2.0+cmpBy :: (Storable a, Storable b) => (a -> b -> Ordering) -> Vector a -> Vector b -> Ordering+cmpBy = G.cmpBy+ -- Conversions - Lists -- ------------------------ @@ -1393,6 +1715,14 @@ -- @ -- fromListN n xs = 'fromList' ('take' n xs) -- @+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> VS.fromListN 3 [1,2,3,4,5::Int]+-- [1,2,3]+-- >>> VS.fromListN 3 [1::Int]+-- [1] fromListN :: Storable a => Int -> [a] -> Vector a {-# INLINE fromListN #-} fromListN = G.fromListN
Data/Vector/Storable/Mutable.hs view
@@ -354,7 +354,11 @@ {-# INLINE new #-} new = G.new --- | Create a mutable vector of the given length. The memory is not initialized.+-- | Create a mutable vector of the given length. The vector content+-- is uninitialized, which means it is filled with whatever underlying memory+-- buffer happens to contain.+--+-- @since 0.5 unsafeNew :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a) {-# INLINE unsafeNew #-} unsafeNew = G.unsafeNew@@ -380,15 +384,50 @@ -- Growing -- ------- --- | Grow a vector by the given number of elements. The number must be--- positive.+-- | Grow a storable vector by the given number of elements. The number must be+-- non-negative. Same semantics as in `G.grow` for generic vector.+--+-- ====__Examples__+--+-- >>> import qualified Data.Vector.Storable as VS+-- >>> import qualified Data.Vector.Storable.Mutable as MVS+-- >>> mv <- VS.thaw $ VS.fromList ([10, 20, 30] :: [Int])+-- >>> mv' <- MVS.grow mv 2+--+-- Extra memory at the end of the newly allocated vector is initialized to 0+-- bytes, which for `Storable` instance will usually correspond to some default+-- value for a particular type, eg. @0@ for @Int@, @False@ for @Bool@,+-- etc. However, if `unsafeGrow` was used instead this would not have been+-- guaranteed and some garbage would be there instead:+--+-- >>> VS.unsafeFreeze mv'+-- [10,20,30,0,0]+--+-- Having the extra space we can write new values in there:+--+-- >>> MVS.write mv' 3 999+-- >>> VS.unsafeFreeze mv'+-- [10,20,30,999,0]+--+-- It is important to note that the source mutable vector is not affected when+-- the newly allocated one is mutated.+--+-- >>> MVS.write mv' 2 888+-- >>> VS.unsafeFreeze mv'+-- [10,20,888,999,0]+-- >>> VS.unsafeFreeze mv+-- [10,20,30]+--+-- @since 0.5 grow :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a) {-# INLINE grow #-} grow = G.grow --- | Grow a vector by the given number of elements. The number must be--- positive but this is not checked.+-- | Grow a vector by the given number of elements. The number must be non-negative but+-- this is not checked. Same semantics as in `G.unsafeGrow` for generic vector.+--+-- @since 0.5 unsafeGrow :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a) {-# INLINE unsafeGrow #-}@@ -583,4 +622,3 @@ unsafeWith :: Storable a => IOVector a -> (Ptr a -> IO b) -> IO b {-# INLINE unsafeWith #-} unsafeWith (MVector _ fp) = withForeignPtr fp-
Data/Vector/Unboxed.hs view
@@ -53,7 +53,7 @@ unsafeIndexM, unsafeHeadM, unsafeLastM, -- ** Extracting subvectors (slicing)- slice, init, tail, take, drop, splitAt,+ slice, init, tail, take, drop, splitAt, uncons, unsnoc, unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, -- * Construction@@ -65,8 +65,8 @@ replicateM, generateM, iterateNM, create, createT, -- ** Unfolding- unfoldr, unfoldrN,- unfoldrM, unfoldrNM,+ unfoldr, unfoldrN, unfoldrExactN,+ unfoldrM, unfoldrNM, unfoldrExactNM, constructN, constructrN, -- ** Enumeration@@ -104,6 +104,7 @@ -- ** Monadic mapping mapM, imapM, mapM_, imapM_, forM, forM_,+ iforM, iforM_, -- ** Zipping zipWith, zipWith3, zipWith4, zipWith5, zipWith6,@@ -119,9 +120,9 @@ -- * Working with predicates -- ** Filtering- filter, ifilter, uniq,+ filter, ifilter, filterM, uniq, mapMaybe, imapMaybe,- filterM,+ mapMaybeM, imapMaybeM, takeWhile, dropWhile, -- ** Partitioning@@ -133,6 +134,7 @@ -- * Folding foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1', ifoldl, ifoldl', ifoldr, ifoldr',+ foldMap, foldMap', -- ** Specialised folds all, any, and, or,@@ -149,10 +151,15 @@ prescanl, prescanl', postscanl, postscanl', scanl, scanl', scanl1, scanl1',+ iscanl, iscanl', prescanr, prescanr', postscanr, postscanr', scanr, scanr', scanr1, scanr1',+ iscanr, iscanr', + -- ** Comparisons+ eqBy, cmpBy,+ -- * Conversions -- ** Lists@@ -182,6 +189,9 @@ filter, takeWhile, dropWhile, span, break, elem, notElem, foldl, foldl1, foldr, foldr1,+#if __GLASGOW_HASKELL__ >= 706+ foldMap,+#endif all, any, and, or, sum, product, minimum, maximum, scanl, scanl1, scanr, scanr1, enumFromTo, enumFromThenTo,@@ -408,10 +418,26 @@ -- -- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@ -- but slightly more efficient.-{-# INLINE splitAt #-}+--+-- @since 0.7.1 splitAt :: Unbox a => Int -> Vector a -> (Vector a, Vector a)+{-# INLINE splitAt #-} splitAt = G.splitAt +-- | /O(1)/ Yield the 'head' and 'tail' of the vector, or 'Nothing' if empty.+--+-- @since 0.12.2.0+uncons :: Unbox a => Vector a -> Maybe (a, Vector a)+{-# INLINE uncons #-}+uncons = G.uncons++-- | /O(1)/ Yield the 'last' and 'init' of the vector, or 'Nothing' if empty.+--+-- @since 0.12.2.0+unsnoc :: Unbox a => Vector a -> Maybe (Vector a, a)+{-# INLINE unsnoc #-}+unsnoc = G.unsnoc+ -- | /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@@ -469,7 +495,21 @@ {-# INLINE generate #-} generate = G.generate --- | /O(n)/ Apply function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply function \(\max(n - 1, 0)\) times to an initial value, producing a vector+-- of length \(\max(n, 0)\). Zeroth element will contain the initial value, that's why there+-- is one less function application than the number of elements in the produced vector.+--+-- \( \underbrace{x, f (x), f (f (x)), \ldots}_{\max(0,n)\rm{~elements}} \)+--+-- ===__Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.iterateN 0 undefined undefined :: VU.Vector Int+-- []+-- >>> VU.iterateN 3 (\(i, c) -> (pred i, succ c)) (0 :: Int, 'a')+-- [(0,'a'),(-1,'b'),(-2,'c')]+--+-- @since 0.7.1 iterateN :: Unbox a => Int -> (a -> a) -> a -> Vector a {-# INLINE iterateN #-} iterateN = G.iterateN@@ -496,6 +536,17 @@ {-# INLINE unfoldrN #-} unfoldrN = G.unfoldrN +-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying+-- the generator function to a seed. The generator function yields the+-- next element and the new seed.+--+-- > unfoldrExactN 3 (\n -> (n,n-1)) 10 = <10,9,8>+--+-- @since 0.12.2.0+unfoldrExactN :: Unbox a => Int -> (b -> (a, b)) -> b -> Vector a+{-# INLINE unfoldrExactN #-}+unfoldrExactN = G.unfoldrExactN+ -- | /O(n)/ Construct a vector by repeatedly applying the monadic -- generator function to a seed. The generator function yields 'Just' -- the next element and the new seed or 'Nothing' if there are no more@@ -512,6 +563,15 @@ {-# INLINE unfoldrNM #-} unfoldrNM = G.unfoldrNM +-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly+-- applying the monadic generator function to a seed. The generator+-- function yields the next element and the new seed.+--+-- @since 0.12.2.0+unfoldrExactNM :: (Monad m, Unbox a) => Int -> (b -> m (a, b)) -> b -> m (Vector a)+{-# INLINE unfoldrExactNM #-}+unfoldrExactNM = G.unfoldrExactNM+ -- | /O(n)/ Construct a vector with @n@ elements by repeatedly applying the -- generator function to the already constructed part of the vector. --@@ -605,7 +665,13 @@ {-# INLINE generateM #-} generateM = G.generateM --- | /O(n)/ Apply monadic function n times to value. Zeroth element is original value.+-- | /O(n)/ Apply monadic function \(\max(n - 1, 0)\) times to an initial value, producing a vector+-- of length \(\max(n, 0)\). Zeroth element will contain the initial value, that's why there+-- is one less function application than the number of elements in the produced vector.+--+-- For non-monadic version see `iterateN`+--+-- @since 0.12.0.0 iterateNM :: (Monad m, Unbox a) => Int -> (a -> m a) -> a -> m (Vector a) {-# INLINE iterateNM #-} iterateNM = G.iterateNM@@ -709,7 +775,11 @@ -- | /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>+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.accum (+) (VU.fromList [1000.0,2000.0,3000.0]) [(2,4),(1,6),(0,3),(1,10)]+-- [1003.0,2016.0,3004.0] accum :: Unbox a => (a -> b -> a) -- ^ accumulating function @f@ -> Vector a -- ^ initial vector (of length @m@)@@ -721,7 +791,11 @@ -- | /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>+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.accumulate (+) (VU.fromList [1000.0,2000.0,3000.0]) (VU.fromList [(2,4),(1,6),(0,3),(1,10)])+-- [1003.0,2016.0,3004.0] accumulate :: (Unbox a, Unbox b) => (a -> b -> a) -- ^ accumulating function @f@ -> Vector a -- ^ initial vector (of length @m@)@@ -871,6 +945,22 @@ {-# INLINE forM_ #-} forM_ = G.forM_ +-- | /O(n)/ Apply the monadic action to all elements of the vector and their indices, yielding a+-- vector of results. Equivalent to 'flip' 'imapM'.+--+-- @since 0.12.2.0+iforM :: (Monad m, Unbox a, Unbox b) => Vector a -> (Int -> a -> m b) -> m (Vector b)+{-# INLINE iforM #-}+iforM = G.iforM++-- | /O(n)/ Apply the monadic action to all elements of the vector and their indices and ignore the+-- results. Equivalent to 'flip' 'imapM_'.+--+-- @since 0.12.2.0+iforM_ :: (Monad m, Unbox a) => Vector a -> (Int -> a -> m b) -> m ()+{-# INLINE iforM_ #-}+iforM_ = G.iforM_+ -- Zipping -- ------- @@ -953,7 +1043,7 @@ -- | /O(min(m,n))/ Zip the two vectors with a monadic action that also takes -- the element index and yield a vector of results izipWithM :: (Monad m, Unbox a, Unbox b, Unbox c)- => (Int -> a -> b -> m c) -> Vector a -> Vector b -> m (Vector c)+ => (Int -> a -> b -> m c) -> Vector a -> Vector b -> m (Vector c) {-# INLINE izipWithM #-} izipWithM = G.izipWithM @@ -967,7 +1057,7 @@ -- | /O(min(m,n))/ Zip the two vectors with a monadic action that also takes -- the element index and ignore the results izipWithM_ :: (Monad m, Unbox a, Unbox b)- => (Int -> a -> b -> m c) -> Vector a -> Vector b -> m ()+ => (Int -> a -> b -> m c) -> Vector a -> Vector b -> m () {-# INLINE izipWithM_ #-} izipWithM_ = G.izipWithM_ @@ -1000,13 +1090,30 @@ {-# INLINE imapMaybe #-} imapMaybe = G.imapMaybe +-- | /O(n)/ Apply monadic function to each element of vector and+-- discard elements returning Nothing.+--+-- @since 0.12.2.0+mapMaybeM :: (Monad m, Unbox a, Unbox b) => (a -> m (Maybe b)) -> Vector a -> m (Vector b)+{-# INLINE mapMaybeM #-}+mapMaybeM = G.mapMaybeM++-- | /O(n)/ Apply monadic function to each element of vector and its index.+-- Discards elements returning Nothing.+--+-- @since 0.12.2.0+imapMaybeM :: (Monad m, Unbox a, Unbox b) => (Int -> a -> m (Maybe b)) -> Vector a -> m (Vector b)+{-# INLINE imapMaybeM #-}+imapMaybeM = G.imapMaybeM+ -- | /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.+-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate.+-- Current implementation is not copy-free, unless the result vector is+-- fused away. takeWhile :: Unbox a => (a -> Bool) -> Vector a -> Vector a {-# INLINE takeWhile #-} takeWhile = G.takeWhile@@ -1036,11 +1143,11 @@ {-# INLINE unstablePartition #-} unstablePartition = G.unstablePartition --- | /O(n)/ Split the vector in two parts, the first one containing the--- @Right@ elements and the second containing the @Left@ elements.--- The relative order of the elements is preserved.+-- | /O(n)/ Split the vector into two parts, the first one containing the+-- @`Left`@ elements and the second containing the @`Right`@ elements.+-- The relative order of the elements is preserved. ----- @since 0.12.1.0+-- @since 0.12.1.0 partitionWith :: (Unbox a, Unbox b, Unbox c) => (a -> Either b c) -> Vector a -> (Vector b, Vector c) {-# INLINE partitionWith #-} partitionWith = G.partitionWith@@ -1168,41 +1275,120 @@ {-# INLINE ifoldr' #-} ifoldr' = G.ifoldr' +-- | /O(n)/ Map each element of the structure to a monoid, and combine+-- the results. It uses same implementation as corresponding method of+-- 'Foldable' type cless. Note it's implemented in terms of 'foldr'+-- and won't fuse with functions that traverse vector from left to+-- right ('map', 'generate', etc.).+--+-- @since 0.12.2.0+foldMap :: (Monoid m, Unbox a) => (a -> m) -> Vector a -> m+{-# INLINE foldMap #-}+foldMap = G.foldMap++-- | /O(n)/ 'foldMap' which is strict in accumulator. It uses same+-- implementation as corresponding method of 'Foldable' type class.+-- Note it's implemented in terms of 'foldl'' so it fuses in most+-- contexts.+--+-- @since 0.12.2.0+foldMap' :: (Monoid m, Unbox a) => (a -> m) -> Vector a -> m+{-# INLINE foldMap' #-}+foldMap' = G.foldMap'+ -- Specialised folds -- ----------------- -- | /O(n)/ Check if all elements satisfy the predicate.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.all even $ VU.fromList [2, 4, 12 :: Int]+-- True+-- >>> VU.all even $ VU.fromList [2, 4, 13 :: Int]+-- False+-- >>> VU.all even (VU.empty :: VU.Vector Int)+-- True all :: Unbox a => (a -> Bool) -> Vector a -> Bool {-# INLINE all #-} all = G.all -- | /O(n)/ Check if any element satisfies the predicate.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.any even $ VU.fromList [1, 3, 7 :: Int]+-- False+-- >>> VU.any even $ VU.fromList [3, 2, 13 :: Int]+-- True+-- >>> VU.any even (VU.empty :: VU.Vector Int)+-- False any :: Unbox a => (a -> Bool) -> Vector a -> Bool {-# INLINE any #-} any = G.any -- | /O(n)/ Check if all elements are 'True'+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.and $ VU.fromList [True, False]+-- False+-- >>> VU.and VU.empty+-- True and :: Vector Bool -> Bool {-# INLINE and #-} and = G.and -- | /O(n)/ Check if any element is 'True'+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.or $ VU.fromList [True, False]+-- True+-- >>> VU.or VU.empty+-- False or :: Vector Bool -> Bool {-# INLINE or #-} or = G.or -- | /O(n)/ Compute the sum of the elements+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.sum $ VU.fromList [300,20,1 :: Int]+-- 321+-- >>> VU.sum (VU.empty :: VU.Vector Int)+-- 0 sum :: (Unbox a, Num a) => Vector a -> a {-# INLINE sum #-} sum = G.sum -- | /O(n)/ Compute the produce of the elements+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.product $ VU.fromList [1,2,3,4 :: Int]+-- 24+-- >>> VU.product (VU.empty :: VU.Vector Int)+-- 1 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.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.maximum $ VU.fromList [2.0, 1.0]+-- 2.0 maximum :: (Unbox a, Ord a) => Vector a -> a {-# INLINE maximum #-} maximum = G.maximum@@ -1215,6 +1401,12 @@ -- | /O(n)/ Yield the minimum element of the vector. The vector may not be -- empty.+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.minimum $ VU.fromList [2.0, 1.0]+-- 1.0 minimum :: (Unbox a, Ord a) => Vector a -> a {-# INLINE minimum #-} minimum = G.minimum@@ -1371,6 +1563,20 @@ {-# INLINE scanl' #-} scanl' = G.scanl' +-- | /O(n)/ Scan over a vector with its index+--+-- @since 0.12.2.0+iscanl :: (Unbox a, Unbox b) => (Int -> a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE iscanl #-}+iscanl = G.iscanl++-- | /O(n)/ Scan over a vector (strictly) with its index+--+-- @since 0.12.2.0+iscanl' :: (Unbox a, Unbox b) => (Int -> a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE iscanl' #-}+iscanl' = G.iscanl'+ -- | /O(n)/ Scan over a non-empty vector -- -- > scanl f <x1,...,xn> = <y1,...,yn>@@ -1421,6 +1627,20 @@ {-# INLINE scanr' #-} scanr' = G.scanr' +-- | /O(n)/ Right-to-left scan over a vector with its index+--+-- @since 0.12.2.0+iscanr :: (Unbox a, Unbox b) => (Int -> a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE iscanr #-}+iscanr = G.iscanr++-- | /O(n)/ Right-to-left scan over a vector (strictly) with its index+--+-- @sinqce 0.12.2.0+iscanr' :: (Unbox a, Unbox b) => (Int -> a -> b -> b) -> b -> Vector a -> Vector b+{-# INLINE iscanr' #-}+iscanr' = G.iscanr'+ -- | /O(n)/ Right-to-left scan over a non-empty vector scanr1 :: Unbox a => (a -> a -> a) -> Vector a -> Vector a {-# INLINE scanr1 #-}@@ -1432,6 +1652,26 @@ {-# INLINE scanr1' #-} scanr1' = G.scanr1' +-- Comparisons+-- ------------------------++-- | /O(n)/ Check if two vectors are equal using supplied equality+-- predicate.+--+-- @since 0.12.2.0+eqBy :: (Unbox a, Unbox b) => (a -> b -> Bool) -> Vector a -> Vector b -> Bool+{-# INLINE eqBy #-}+eqBy = G.eqBy++-- | /O(n)/ Compare two vectors using supplied comparison function for+-- vector elements. Comparison works same as for lists.+--+-- > cmpBy compare == compare+--+-- @since 0.12.2.0+cmpBy :: (Unbox a, Unbox b) => (a -> b -> Ordering) -> Vector a -> Vector b -> Ordering+cmpBy = G.cmpBy+ -- Conversions - Lists -- ------------------------ @@ -1450,6 +1690,14 @@ -- @ -- fromListN n xs = 'fromList' ('take' n xs) -- @+--+-- ==== __Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> VU.fromListN 3 [1,2,3,4,5::Int]+-- [1,2,3]+-- >>> VU.fromListN 3 [1::Int]+-- [1] fromListN :: Unbox a => Int -> [a] -> Vector a {-# INLINE fromListN #-} fromListN = G.fromListN
Data/Vector/Unboxed/Mutable.hs view
@@ -155,7 +155,11 @@ {-# INLINE new #-} new = G.new --- | Create a mutable vector of the given length. The memory is not initialized.+-- | Create a mutable vector of the given length. The vector content+-- is uninitialized, which means it is filled with whatever underlying memory+-- buffer happens to contain.+--+-- @since 0.5 unsafeNew :: (PrimMonad m, Unbox a) => Int -> m (MVector (PrimState m) a) {-# INLINE unsafeNew #-} unsafeNew = G.unsafeNew@@ -181,15 +185,50 @@ -- Growing -- ------- --- | Grow a vector by the given number of elements. The number must be--- positive.+-- | Grow an unboxed vector by the given number of elements. The number must be+-- non-negative. Same semantics as in `G.grow` for generic vector.+--+-- ====__Examples__+--+-- >>> import qualified Data.Vector.Unboxed as VU+-- >>> import qualified Data.Vector.Unboxed.Mutable as MVU+-- >>> mv <- VU.thaw $ VU.fromList ([('a', 10), ('b', 20), ('c', 30)] :: [(Char, Int)])+-- >>> mv' <- MVU.grow mv 2+--+-- Extra memory at the end of the newly allocated vector is initialized to 0+-- bytes, which for `Unbox` instance will usually correspond to some default+-- value for a particular type, eg. @0@ for @Int@, @False@ for @Bool@,+-- etc. However, if `unsafeGrow` was used instead this would not have been+-- guaranteed and some garbage would be there instead:+--+-- >>> VU.unsafeFreeze mv'+-- [('a',10),('b',20),('c',30),('\NUL',0),('\NUL',0)]+--+-- Having the extra space we can write new values in there:+--+-- >>> MVU.write mv' 3 ('d', 999)+-- >>> VU.unsafeFreeze mv'+-- [('a',10),('b',20),('c',30),('d',999),('\NUL',0)]+--+-- It is important to note that the source mutable vector is not affected when+-- the newly allocated one is mutated.+--+-- >>> MVU.write mv' 2 ('X', 888)+-- >>> VU.unsafeFreeze mv'+-- [('a',10),('b',20),('X',888),('d',999),('\NUL',0)]+-- >>> VU.unsafeFreeze mv+-- [('a',10),('b',20),('c',30)]+--+-- @since 0.5 grow :: (PrimMonad m, Unbox a) => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a) {-# INLINE grow #-} grow = G.grow --- | Grow a vector by the given number of elements. The number must be--- positive but this is not checked.+-- | Grow a vector by the given number of elements. The number must be non-negative but+-- this is not checked. Same semantics as in `G.unsafeGrow` for generic vector.+--+-- @since 0.5 unsafeGrow :: (PrimMonad m, Unbox a) => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a) {-# INLINE unsafeGrow #-}
changelog.md view
@@ -1,3 +1,22 @@+# Changes in version 0.12.2.0++ * Add `MINIMAL` pragma to `Vector` & `MVector` type classes: [#11](https://github.com/haskell/vector/issues/11)+ * Export `unstreamM` from`from Data.Vector.Generic`: [#70](https://github.com/haskell/vector/issues/70)+ * New functions: `unfoldrExactN` and `unfoldrExactNM`: [#140](https://github.com/haskell/vector/issues/140)+ * Added `iforM` and `iforM_`: [#262](https://github.com/haskell/vector/issues/262)+ * Added `MonadFix` instance for boxed vectors: [#178](https://github.com/haskell/vector/issues/178)+ * Added `uncons` and `unsnoc`: [#212](https://github.com/haskell/vector/issues/212)+ * Added `foldMap` and `foldMap'`: [#263](https://github.com/haskell/vector/issues/263)+ * Added `isSameVector` for storable vectors+ * Added `toArray`, `fromArray`, `toMutableArray` and `fromMutableArray`+ * Added `iscanl`, `iscanl'`, `iscanr`, `iscanr'` to `Primitive`, `Storable` and `Unboxed`+ * Added `izipWithM`, `izipWithM_`, `imapM` and `imapM_` to `Primitive` and `Storable`+ * Added `ifoldM`, `ifoldM'`, `ifoldM_` and `ifoldM'_` to `Primitive` and `Storable`+ * Added `eqBy` and `cmpBy`+ * Added `findIndexR` to `Generic`: [#172](https://github.com/haskell/vector/issues/172)+ * Added `catMaybes`: [#329](https://github.com/haskell/vector/issues/329)+ * Added `mapMaybeM` and `imapMaybeM`: [#183](https://github.com/haskell/vector/issues/183)+ # Changes in version 0.12.1.2 * Fix for lost function `Data.Vector.Generic.mkType`: [#287](https://github.com/haskell/vector/issues/287)
tests/Tests/Vector/Boxed.hs view
@@ -21,6 +21,7 @@ , testMonadFunctions , testApplicativeFunctions , testAlternativeFunctions+ , testSequenceFunctions , testDataFunctions ]
tests/Tests/Vector/Property.hs view
@@ -13,6 +13,7 @@ , testMonadFunctions , testApplicativeFunctions , testAlternativeFunctions+ , testSequenceFunctions , testBoolFunctions , testNumFunctions , testNestedVectorFunctions@@ -20,12 +21,13 @@ -- re-exports , Data , Random- ,Test+ , Test ) where import Boilerplater import Utilities as Util hiding (limitUnfolds) +import Control.Monad import Data.Functor.Identity import qualified Data.Traversable as T (Traversable(..)) import Data.Foldable (Foldable(foldMap))@@ -67,37 +69,12 @@ type Test = TestTree -- TODO: implement Vector equivalents of list functions for some of the commented out properties --- TODO: test and implement some of these other Prelude functions:--- mapM *--- mapM_ *--- sequence--- sequence_--- sum *--- product *--- scanl *--- scanl1 *--- scanr *--- scanr1 *--- lookup *--- lines--- words--- unlines--- unwords--- NB: this is an exhaustive list of all Prelude list functions that make sense for vectors.--- Ones with *s are the most plausible candidates.- -- TODO: add tests for the other extra functions -- IVector exports still needing tests: -- copy,--- slice,--- (//), update, bpermute,--- prescanl, prescanl', -- new, -- unsafeSlice, unsafeIndex,--- vlength, vnew --- TODO: test non-IVector stuff?- testSanity :: forall a v. (CommonContext a v) => v a -> [Test] {-# INLINE testSanity #-} testSanity _ = [@@ -121,7 +98,7 @@ -- Length information 'prop_length, 'prop_null, - -- Indexing (FIXME)+ -- Indexing 'prop_index, 'prop_safeIndex, 'prop_head, 'prop_last, 'prop_unsafeIndex, 'prop_unsafeHead, 'prop_unsafeLast, @@ -138,17 +115,16 @@ -- Initialisation (FIXME) 'prop_empty, 'prop_singleton, 'prop_replicate, 'prop_generate, 'prop_iterateN, 'prop_iterateNM,+ 'prop_generateM, 'prop_replicateM, -- Monadic initialisation (FIXME)- 'prop_createT,- {- 'prop_replicateM, 'prop_generateM, 'prop_create, -}+ 'prop_create, 'prop_createT, -- Unfolding- 'prop_unfoldr, 'prop_unfoldrN, 'prop_unfoldrM, 'prop_unfoldrNM,+ 'prop_unfoldr, 'prop_unfoldrN, 'prop_unfoldrExactN,+ 'prop_unfoldrM, 'prop_unfoldrNM, 'prop_unfoldrExactNM, 'prop_constructN, 'prop_constructrN, - -- Enumeration? (FIXME?)- -- Concatenation (FIXME) 'prop_cons, 'prop_snoc, 'prop_append, 'prop_concat,@@ -159,7 +135,7 @@ -- Bulk updates (FIXME) 'prop_upd,- {- 'prop_update, 'prop_update_,+ {- 'prop_update_, 'prop_unsafeUpd, 'prop_unsafeUpdate, 'prop_unsafeUpdate_, -} -- Accumulations (FIXME)@@ -171,30 +147,23 @@ 'prop_reverse, 'prop_backpermute, {- 'prop_unsafeBackpermute, -} - -- Elementwise indexing- {- 'prop_indexed, -}- -- Mapping 'prop_map, 'prop_imap, 'prop_concatMap, -- Monadic mapping- {- 'prop_mapM, 'prop_mapM_, 'prop_forM, 'prop_forM_, -}+ 'prop_mapM, 'prop_mapM_, 'prop_forM, 'prop_forM_, 'prop_imapM, 'prop_imapM_, -- Zipping- 'prop_zipWith, 'prop_zipWith3, {- ... -}- 'prop_izipWith, 'prop_izipWith3, {- ... -}+ 'prop_zipWith, 'prop_zipWith3,+ 'prop_izipWith, 'prop_izipWith3, 'prop_izipWithM, 'prop_izipWithM_,- {- 'prop_zip, ... -} -- Monadic zipping- {- 'prop_zipWithM, 'prop_zipWithM_, -}-- -- Unzipping- {- 'prop_unzip, ... -}+ 'prop_zipWithM, 'prop_zipWithM_, -- Filtering- 'prop_filter, 'prop_ifilter, {- prop_filterM, -}+ 'prop_filter, 'prop_ifilter, 'prop_filterM, 'prop_uniq, 'prop_mapMaybe, 'prop_imapMaybe, 'prop_takeWhile, 'prop_dropWhile,@@ -206,7 +175,7 @@ -- Searching 'prop_elem, 'prop_notElem,- 'prop_find, 'prop_findIndex, 'prop_findIndices,+ 'prop_find, 'prop_findIndex, 'prop_findIndexR, 'prop_findIndices, 'prop_elemIndex, 'prop_elemIndices, -- Folding@@ -217,15 +186,7 @@ -- Specialised folds 'prop_all, 'prop_any,- {- 'prop_maximumBy, 'prop_minimumBy,- 'prop_maxIndexBy, 'prop_minIndexBy, -} - -- Monadic folds- {- ... -}-- -- Monadic sequencing- {- ... -}- -- Scans 'prop_prescanl, 'prop_prescanl', 'prop_postscanl, 'prop_postscanl',@@ -245,9 +206,11 @@ prop_null :: P (v a -> Bool) = V.null `eq` null prop_empty :: P (v a) = V.empty `eq` []- prop_singleton :: P (a -> v a) = V.singleton `eq` singleton+ prop_singleton :: P (a -> v a) = V.singleton `eq` Util.singleton prop_replicate :: P (Int -> a -> v a) = (\n _ -> n < 1000) ===> V.replicate `eq` replicate+ prop_replicateM :: P (Int -> Writer [a] a -> Writer [a] (v a))+ = (\n _ -> n < 1000) ===> V.replicateM `eq` replicateM prop_cons :: P (a -> v a -> v a) = V.cons `eq` (:) prop_snoc :: P (v a -> a -> v a) = V.snoc `eq` snoc prop_append :: P (v a -> v a -> v a) = (V.++) `eq` (++)@@ -255,10 +218,14 @@ prop_force :: P (v a -> v a) = V.force `eq` id prop_generate :: P (Int -> (Int -> a) -> v a) = (\n _ -> n < 1000) ===> V.generate `eq` Util.generate+ prop_generateM :: P (Int -> (Int -> Writer [a] a) -> Writer [a] (v a))+ = (\n _ -> n < 1000) ===> V.generateM `eq` Util.generateM prop_iterateN :: P (Int -> (a -> a) -> a -> v a) = (\n _ _ -> n < 1000) ===> V.iterateN `eq` (\n f -> take n . iterate f) prop_iterateNM :: P (Int -> (a -> Writer [Int] a) -> a -> Writer [Int] (v a)) = (\n _ _ -> n < 1000) ===> V.iterateNM `eq` Util.iterateNM+ prop_create :: P (v a -> v a)+ prop_create = (\v -> V.create (V.thaw v)) `eq` id prop_createT :: P ((a, v a) -> (a, v a)) prop_createT = (\v -> V.createT (T.mapM V.thaw v)) `eq` id @@ -319,6 +286,14 @@ prop_reverse :: P (v a -> v a) = V.reverse `eq` reverse prop_map :: P ((a -> a) -> v a -> v a) = V.map `eq` map+ prop_mapM :: P ((a -> Identity a) -> v a -> Identity (v a))+ = V.mapM `eq` mapM+ prop_mapM_ :: P ((a -> Writer [a] ()) -> v a -> Writer [a] ())+ = V.mapM_ `eq` mapM_+ prop_forM :: P (v a -> (a -> Identity a) -> Identity (v a))+ = V.forM `eq` forM+ prop_forM_ :: P (v a -> (a -> Writer [a] ()) -> Writer [a] ())+ = V.forM_ `eq` forM_ prop_zipWith :: P ((a -> a -> a) -> v a -> v a -> v a) = V.zipWith `eq` zipWith prop_zipWith3 :: P ((a -> a -> a -> a) -> v a -> v a -> v a -> v a) = V.zipWith3 `eq` zipWith3@@ -328,6 +303,10 @@ prop_imapM_ :: P ((Int -> a -> Writer [a] ()) -> v a -> Writer [a] ()) = V.imapM_ `eq` imapM_ prop_izipWith :: P ((Int -> a -> a -> a) -> v a -> v a -> v a) = V.izipWith `eq` izipWith+ prop_zipWithM :: P ((a -> a -> Identity a) -> v a -> v a -> Identity (v a))+ = V.zipWithM `eq` zipWithM+ prop_zipWithM_ :: P ((a -> a -> Writer [a] ()) -> v a -> v a -> Writer [a] ())+ = V.zipWithM_ `eq` zipWithM_ prop_izipWithM :: P ((Int -> a -> a -> Identity a) -> v a -> v a -> Identity (v a)) = V.izipWithM `eq` izipWithM prop_izipWithM_ :: P ((Int -> a -> a -> Writer [a] ()) -> v a -> v a -> Writer [a] ())@@ -337,6 +316,7 @@ prop_filter :: P ((a -> Bool) -> v a -> v a) = V.filter `eq` filter prop_ifilter :: P ((Int -> a -> Bool) -> v a -> v a) = V.ifilter `eq` ifilter+ prop_filterM :: P ((a -> Writer [a] Bool) -> v a -> Writer [a] (v a)) = V.filterM `eq` filterM prop_mapMaybe :: P ((a -> Maybe a) -> v a -> v a) = V.mapMaybe `eq` mapMaybe prop_imapMaybe :: P ((Int -> a -> Maybe a) -> v a -> v a) = V.imapMaybe `eq` imapMaybe prop_takeWhile :: P ((a -> Bool) -> v a -> v a) = V.takeWhile `eq` takeWhile@@ -353,6 +333,10 @@ prop_find :: P ((a -> Bool) -> v a -> Maybe a) = V.find `eq` find prop_findIndex :: P ((a -> Bool) -> v a -> Maybe Int) = V.findIndex `eq` findIndex+ prop_findIndexR :: P ((a -> Bool) -> v a -> Maybe Int)+ = V.findIndexR `eq` \p l -> case filter (p . snd) . reverse $ zip [0..] l of+ (i,_):_ -> Just i+ [] -> Nothing prop_findIndices :: P ((a -> Bool) -> v a -> v Int) = V.findIndices `eq` findIndices prop_elemIndex :: P (a -> v a -> Maybe Int) = V.elemIndex `eq` elemIndex@@ -439,18 +423,8 @@ prop_uniq :: P (v a -> v a) = V.uniq `eq` (map head . group)- --prop_span = (V.span :: (a -> Bool) -> v a -> (v a, v a)) `eq2` span- --prop_break = (V.break :: (a -> Bool) -> v a -> (v a, v a)) `eq2` break- --prop_splitAt = (V.splitAt :: Int -> v a -> (v a, v a)) `eq2` splitAt- --prop_all = (V.all :: (a -> Bool) -> v a -> Bool) `eq2` all- --prop_any = (V.any :: (a -> Bool) -> v a -> Bool) `eq2` any -- Data.List- --prop_findIndices = V.findIndices `eq2` (findIndices :: (a -> Bool) -> v a -> v Int)- --prop_isPrefixOf = V.isPrefixOf `eq2` (isPrefixOf :: v a -> v a -> Bool)- --prop_elemIndex = V.elemIndex `eq2` (elemIndex :: a -> v a -> Maybe Int)- --prop_elemIndices = V.elemIndices `eq2` (elemIndices :: a -> v a -> v Int)- -- --prop_mapAccumL = eq3 -- (V.mapAccumL :: (X -> W -> (X,W)) -> X -> B -> (X, B)) -- ( mapAccumL :: (X -> W -> (X,W)) -> X -> [W] -> (X, [W]))@@ -476,11 +450,15 @@ `eq` (\n f a -> unfoldr (limitUnfolds f) (a, n)) prop_unfoldrN :: P (Int -> (Int -> Maybe (a,Int)) -> Int -> v a) = V.unfoldrN `eq` (\n f a -> unfoldr (limitUnfolds f) (a, n))+ prop_unfoldrExactN :: P (Int -> (Int -> (a,Int)) -> Int -> v a)+ = V.unfoldrExactN `eq` (\n f a -> unfoldr (limitUnfolds (Just . f)) (a, n)) prop_unfoldrM :: P (Int -> (Int -> Writer [Int] (Maybe (a,Int))) -> Int -> Writer [Int] (v a)) = (\n f a -> V.unfoldrM (limitUnfoldsM f) (a,n)) `eq` (\n f a -> Util.unfoldrM (limitUnfoldsM f) (a, n)) prop_unfoldrNM :: P (Int -> (Int -> Writer [Int] (Maybe (a,Int))) -> Int -> Writer [Int] (v a)) = V.unfoldrNM `eq` (\n f a -> Util.unfoldrM (limitUnfoldsM f) (a, n))+ prop_unfoldrExactNM :: P (Int -> (Int -> Writer [Int] (a,Int)) -> Int -> Writer [Int] (v a))+ = V.unfoldrExactNM `eq` (\n f a -> Util.unfoldrM (limitUnfoldsM (liftM Just . f)) (a, n)) prop_constructN = \f -> forAll (choose (0,20)) $ \n -> unP prop n f where@@ -504,16 +482,30 @@ Right c -> (bs, c:cs) where (bs,cs) = partitionWith f xs -testTuplyFunctions :: forall a v. (CommonContext a v, VectorContext (a, a) v, VectorContext (a, a, a) v) => v a -> [Test]+testTuplyFunctions+ :: forall a v. ( CommonContext a v+ , VectorContext (a, a) v+ , VectorContext (a, a, a) v+ , VectorContext (Int, a) v+ )+ => v a -> [Test] {-# INLINE testTuplyFunctions #-} testTuplyFunctions _ = $(testProperties [ 'prop_zip, 'prop_zip3 , 'prop_unzip, 'prop_unzip3+ , 'prop_indexed+ , 'prop_update ]) where- prop_zip :: P (v a -> v a -> v (a, a)) = V.zip `eq` zip- prop_zip3 :: P (v a -> v a -> v a -> v (a, a, a)) = V.zip3 `eq` zip3- prop_unzip :: P (v (a, a) -> (v a, v a)) = V.unzip `eq` unzip- prop_unzip3 :: P (v (a, a, a) -> (v a, v a, v a)) = V.unzip3 `eq` unzip3+ prop_zip :: P (v a -> v a -> v (a, a)) = V.zip `eq` zip+ prop_zip3 :: P (v a -> v a -> v a -> v (a, a, a)) = V.zip3 `eq` zip3+ prop_unzip :: P (v (a, a) -> (v a, v a)) = V.unzip `eq` unzip+ prop_unzip3 :: P (v (a, a, a) -> (v a, v a, v a)) = V.unzip3 `eq` unzip3+ prop_indexed :: P (v a -> v (Int, a)) = V.indexed `eq` (\xs -> [0..] `zip` xs)+ prop_update = \xs ->+ forAll (index_value_pairs (V.length xs)) $ \ps ->+ unP prop xs ps+ where+ prop :: P (v a -> [(Int,a)] -> v a) = (V.//) `eq` (//) testOrdFunctions :: forall a v. (CommonContext a v, Ord a, Ord (v a)) => v a -> [Test] {-# INLINE testOrdFunctions #-}@@ -617,13 +609,31 @@ testMonadFunctions :: forall a v. (CommonContext a v, VectorContext (a, a) v, MonadZip v) => v a -> [Test] {-# INLINE testMonadFunctions #-} testMonadFunctions _ = $(testProperties [ 'prop_return, 'prop_bind- , 'prop_mzip, 'prop_munzip])+ , 'prop_mzip, 'prop_munzip+ ]) where prop_return :: P (a -> v a) = return `eq` return prop_bind :: P (v a -> (a -> v a) -> v a) = (>>=) `eq` (>>=) prop_mzip :: P (v a -> v a -> v (a, a)) = mzip `eq` zip prop_munzip :: P (v (a, a) -> (v a, v a)) = munzip `eq` unzip +testSequenceFunctions+ :: forall a v. ( CommonContext a v+ , Model (v (Writer [a] a)) ~ [Writer [a] a]+ , V.Vector v (Writer [a] a)+ , Arbitrary (v (Writer [a] a))+ , Show (v (Writer [a] a))+ , TestData (v (Writer [a] a))+ )+ => v a -> [Test]+testSequenceFunctions _ = $(testProperties [ 'prop_sequence, 'prop_sequence_+ ])+ where+ prop_sequence :: P (v (Writer [a] a) -> Writer [a] (v a))+ = V.sequence `eq` sequence+ prop_sequence_ :: P (v (Writer [a] a) -> Writer [a] ())+ = V.sequence_ `eq` sequence_+ testApplicativeFunctions :: forall a v. (CommonContext a v, V.Vector v (a -> a), Applicative.Applicative v) => v a -> [Test] {-# INLINE testApplicativeFunctions #-} testApplicativeFunctions _ = $(testProperties@@ -659,16 +669,11 @@ testNestedVectorFunctions :: forall a v. (CommonContext a v) => v a -> [Test] {-# INLINE testNestedVectorFunctions #-}-testNestedVectorFunctions _ = $(testProperties [])+testNestedVectorFunctions _ = $(testProperties+ [ 'prop_concat+ ]) where- -- Prelude- --prop_concat = (V.concat :: [v a] -> v a) `eq1` concat-- -- Data.List- --prop_transpose = V.transpose `eq1` (transpose :: [v a] -> [v a])- --prop_group = V.group `eq1` (group :: v a -> [v a])- --prop_inits = V.inits `eq1` (inits :: v a -> [v a])- --prop_tails = V.tails `eq1` (tails :: v a -> [v a])+ prop_concat :: P ([v a] -> v a) = V.concat `eq` concat testDataFunctions :: forall a v. (CommonContext a v, Data a, Data (v a)) => v a -> [Test] {-# INLINE testDataFunctions #-}
tests/Tests/Vector/Unboxed.hs view
@@ -13,6 +13,7 @@ testSanity , testPolymorphicFunctions , testOrdFunctions+ , testTuplyFunctions , testMonoidFunctions , testDataFunctions ]
tests/Tests/Vector/UnitTests.hs view
@@ -6,24 +6,25 @@ import Control.Applicative as Applicative import Control.Exception import Control.Monad.Primitive+import Control.Monad.Fix (mfix) import Data.Int import Data.Word import Data.Typeable import qualified Data.List as List import qualified Data.Vector.Generic as Generic import qualified Data.Vector as Boxed+import qualified Data.Vector.Mutable as MBoxed import qualified Data.Vector.Primitive as Primitive import qualified Data.Vector.Storable as Storable import qualified Data.Vector.Unboxed as Unboxed-import qualified Data.Vector as Vector import Foreign.Ptr import Foreign.Storable import Text.Printf import Test.Tasty-import Test.Tasty.HUnit (testCase,Assertion, assertBool, (@=?), assertFailure)--- import Test.HUnit ()+import Test.Tasty.HUnit (testCase, Assertion, assertBool, assertEqual, (@=?), assertFailure) + newtype Aligned a = Aligned { getAligned :: a } instance (Storable a) => Storable (Aligned a) where@@ -80,6 +81,11 @@ , testCase "Unboxed" $ testTakeOutOfMemory Unboxed.take ] ]+ , testGroup "Data.Vector"+ [ testCase "MonadFix" checkMonadFix+ , testCase "toFromArray" toFromArray+ , testCase "toFromMutableArray" toFromMutableArray+ ] ] testsSliceOutOfBounds ::@@ -141,7 +147,7 @@ :: forall proxy a. (Typeable a, Enum a, Bounded a, Eq a, Show a) => proxy a -> TestTree regression188 _ = testCase (show (typeOf (undefined :: a)))- $ Vector.fromList [maxBound::a] @=? Vector.enumFromTo maxBound maxBound+ $ Boxed.fromList [maxBound::a] @=? Boxed.enumFromTo maxBound maxBound {-# INLINE regression188 #-} alignedDoubleVec :: Storable.Vector (Aligned Double)@@ -157,3 +163,45 @@ => Generic.Mutable v (PrimState f) a -> f (w a) _f v = Generic.convert `fmap` Generic.unsafeFreeze v #endif++checkMonadFix :: Assertion+checkMonadFix = assertBool "checkMonadFix" $+ Boxed.toList fewV == fewL &&+ Boxed.toList none == []+ where+ facty _ 0 = 1; facty f n = n * f (n - 1)+ fewV :: Boxed.Vector Int+ fewV = fmap ($ 12) $ mfix (\i -> Boxed.fromList [facty i, facty (+1), facty (+2)])+ fewL :: [Int]+ fewL = fmap ($ 12) $ mfix (\i -> [facty i, facty (+1), facty (+2)])+ none :: Boxed.Vector Int+ none = mfix (const Boxed.empty)++mkArrayRoundtrip :: (String -> Boxed.Vector Integer -> Assertion) -> Assertion+mkArrayRoundtrip mkAssertion =+ sequence_+ [ mkAssertion name v+ | (name, v) <-+ [ ("full", vec)+ , ("slicedTail", Boxed.slice 0 (n - 3) vec)+ , ("slicedHead", Boxed.slice 2 (n - 2) vec)+ , ("slicedBoth", Boxed.slice 2 (n - 4) vec)+ ]+ ]+ where+ vec = Boxed.fromList [0 .. 10]+ n = Boxed.length vec++toFromArray :: Assertion+toFromArray =+ mkArrayRoundtrip $ \name v ->+ assertEqual name v $ Boxed.fromArray (Boxed.toArray v)++toFromMutableArray :: Assertion+toFromMutableArray = mkArrayRoundtrip assetRoundtrip+ where+ assetRoundtrip assertionName vec = do+ mvec <- Boxed.unsafeThaw vec+ mvec' <- MBoxed.fromMutableArray =<< MBoxed.toMutableArray mvec+ vec' <- Boxed.unsafeFreeze mvec'+ assertEqual assertionName vec vec'
tests/Utilities.hs view
@@ -68,42 +68,42 @@ type EqTest a equal :: a -> a -> EqTest a -instance Eq a => TestData (S.Bundle v a) where- type Model (S.Bundle v a) = [a]- model = S.toList- unmodel = S.fromList+instance (Eq a, TestData a) => TestData (S.Bundle v a) where+ type Model (S.Bundle v a) = [Model a]+ model = map model . S.toList+ unmodel = S.fromList . map unmodel type EqTest (S.Bundle v a) = Property equal x y = property (x == y) -instance Eq a => TestData (DV.Vector a) where- type Model (DV.Vector a) = [a]- model = DV.toList- unmodel = DV.fromList+instance (Eq a, TestData a) => TestData (DV.Vector a) where+ type Model (DV.Vector a) = [Model a]+ model = map model . DV.toList+ unmodel = DV.fromList . map unmodel type EqTest (DV.Vector a) = Property equal x y = property (x == y) -instance (Eq a, DVP.Prim a) => TestData (DVP.Vector a) where- type Model (DVP.Vector a) = [a]- model = DVP.toList- unmodel = DVP.fromList+instance (Eq a, DVP.Prim a, TestData a) => TestData (DVP.Vector a) where+ type Model (DVP.Vector a) = [Model a]+ model = map model . DVP.toList+ unmodel = DVP.fromList . map unmodel type EqTest (DVP.Vector a) = Property equal x y = property (x == y) -instance (Eq a, DVS.Storable a) => TestData (DVS.Vector a) where- type Model (DVS.Vector a) = [a]- model = DVS.toList- unmodel = DVS.fromList+instance (Eq a, DVS.Storable a, TestData a) => TestData (DVS.Vector a) where+ type Model (DVS.Vector a) = [Model a]+ model = map model . DVS.toList+ unmodel = DVS.fromList . map unmodel type EqTest (DVS.Vector a) = Property equal x y = property (x == y) -instance (Eq a, DVU.Unbox a) => TestData (DVU.Vector a) where- type Model (DVU.Vector a) = [a]- model = DVU.toList- unmodel = DVU.fromList+instance (Eq a, DVU.Unbox a, TestData a) => TestData (DVU.Vector a) where+ type Model (DVU.Vector a) = [Model a]+ model = map model . DVU.toList+ unmodel = DVU.fromList . map unmodel type EqTest (DVU.Vector a) = Property equal x y = property (x == y)@@ -247,6 +247,7 @@ singleton x = [x] snoc xs x = xs ++ [x] generate n f = [f i | i <- [0 .. n-1]]+generateM n f = sequence [f i | i <- [0 .. n-1]] slice i n xs = take n (drop i xs) backpermute xs is = map (xs!!) is prescanl f z = init . scanl f z
+ tests/doctests.hs view
@@ -0,0 +1,4 @@+import Test.DocTest (doctest)++main :: IO ()+main = doctest ["-Iinclude", "-Iinternal", "Data"]
vector.cabal view
@@ -1,5 +1,5 @@ Name: vector-Version: 0.12.1.2+Version: 0.12.2.0 -- don't forget to update the changelog file! License: BSD3 License-File: LICENSE@@ -152,9 +152,9 @@ Install-Includes: vector.h - Build-Depends: base >= 4.5 && < 4.15- , primitive >= 0.5.0.1 && < 0.8- , ghc-prim >= 0.2 && < 0.7+ Build-Depends: base >= 4.5 && < 4.16+ , primitive >= 0.6.4.0 && < 0.8+ , ghc-prim >= 0.2 && < 0.8 , deepseq >= 1.1 && < 1.5 if !impl(ghc > 8.0) Build-Depends: fail == 4.9.*@@ -203,9 +203,11 @@ hs-source-dirs: tests Build-Depends: base >= 4.5 && < 5, template-haskell, base-orphans >= 0.6, vector, primitive, random,- QuickCheck >= 2.9 && < 2.14 , HUnit, tasty,+ QuickCheck >= 2.9 && < 2.15, HUnit, tasty, tasty-hunit, tasty-quickcheck,- transformers >= 0.2.0.0,semigroups+ transformers >= 0.2.0.0+ if !impl(ghc > 8.0)+ Build-Depends: semigroups default-extensions: CPP, ScopedTypeVariables,@@ -246,9 +248,11 @@ hs-source-dirs: tests Build-Depends: base >= 4.5 && < 5, template-haskell, base-orphans >= 0.6, vector, primitive, random,- QuickCheck >= 2.9 && < 2.14 , HUnit, tasty,+ QuickCheck >= 2.9 && < 2.15, HUnit, tasty, tasty-hunit, tasty-quickcheck,- transformers >= 0.2.0.0,semigroups+ transformers >= 0.2.0.0+ if !impl(ghc > 8.0)+ Build-Depends: semigroups default-extensions: CPP, ScopedTypeVariables,@@ -268,3 +272,19 @@ if impl(ghc >= 8.0) && impl(ghc < 8.1) Ghc-Options: -Wno-redundant-constraints +test-suite vector-doctest+ type: exitcode-stdio-1.0+ main-is: doctests.hs+ hs-source-dirs: tests+ default-language: Haskell2010+ -- Older GHC choke on {-# UNPACK #-} pragma for some reason+ if impl(ghc < 8.6)+ buildable: False+ -- GHC 8.10 fails to run doctests for some reason+ if impl(ghc >= 8.10) && impl(ghc < 8.11)+ buildable: False+ build-depends:+ base -any+ , doctest >=0.15 && <0.18+ , primitive >= 0.6.4.0 && < 0.8+ , vector -any