vector-sized 1.2.0.1 → 1.6.1
raw patch · 16 files changed
Files
- changelog.md +55/−0
- default.nix +10/−26
- shell.nix +0/−5
- src/Data/Vector/Generic/Mutable/Sized.hs +0/−5
- src/Data/Vector/Generic/Mutable/Sized/Internal.hs +1/−3
- src/Data/Vector/Generic/Sized.hs +180/−45
- src/Data/Vector/Generic/Sized/Internal.hs +1/−3
- src/Data/Vector/Mutable/Sized.hs +0/−5
- src/Data/Vector/Primitive/Mutable/Sized.hs +466/−0
- src/Data/Vector/Primitive/Sized.hs +1508/−0
- src/Data/Vector/Sized.hs +49/−19
- src/Data/Vector/Storable/Mutable/Sized.hs +0/−5
- src/Data/Vector/Storable/Sized.hs +47/−19
- src/Data/Vector/Unboxed/Mutable/Sized.hs +89/−14
- src/Data/Vector/Unboxed/Sized.hs +48/−20
- vector-sized.cabal +21/−26
changelog.md view
@@ -1,5 +1,60 @@ # Change Log +## WIP++## [1.6.1]++- Fix build against Stackage nightly for GHC 9.4.5+- Future-proof against future Prelude `foldl'` (thanks Bodigrim!)++## [1.6.0] - 2022-01-22++- Add instances of `FunctorWithIndex`, `FoldableWithIndex` and+ `TraversableWithIndex` for `Vector n a`.+- Drop support for GHC older than 8.10+- Safe construction of vectors from linked lists (https://github.com/expipiplus1/vector-sized/pull/88)++Thanks to @sheaf and @kozross++## [1.5.0] - 2021-08-25++- Change indexes used by `accum` from `Int` to `Finite`.++## [1.4.4] - 2021-06-26++- Add `ix'`++## [1.4.3.1] - 2020-12-13++- Fix Bits instance, shiftl and shiftr were incorrect++## [1.4.3] - 2020-12-08++- Add Primitive flavour of sized vectors+- Add `instance Bits (v a) => Bits (Vector v n a)`++Thanks to @Bodigrim and @mstksg++## [1.4.2] - 2020-08-20++- Add `instance Unbox a, KnownNat n) => Unbox (Vector n a)`+- Add `zipVectorsUnsafe`++## [1.4.1.0] - 2020-05-04++- GHC 8.10 compatibility++## [1.4.0.0] - 2019-09-12++- Remove Generic instance, see+ https://github.com/expipiplus1/vector-sized/issues/79+- Add Binary instance+- Loosen bounds on dependencies++## [1.3.0.0] - 2019-05-28++- Correct type of accumulating fold functions+ ## [1.2.0.1] - 2019-05-22 - Loosen upper bounds on dependencies
default.nix view
@@ -1,28 +1,12 @@-{ pkgs ? import <nixpkgs> {}-, compiler ? "ghc864"-}:--let src = pkgs.nix-gitignore.gitignoreSource [] ./.;-- # Any overrides we require to the specified haskell package set- haskellPackages = with pkgs.haskell.lib;- pkgs.haskell.packages.${compiler}.override {- overrides = self: super: {- };- };-- # Any packages to appear in the environment provisioned by nix-shell- extraEnvPackages = with haskellPackages; [- ];-- # Generate a haskell derivation using the cabal2nix tool on `package.yaml`- drv = haskellPackages.callCabal2nix "" src {};+{ nixpkgsSrc ? <nixpkgs>, pkgs ? import nixpkgsSrc { }, compiler ? null }: - # Insert the extra environment packages into the environment generated by- # cabal2nix- envWithExtras = pkgs.lib.overrideDerivation drv.env (attrs: {- buildInputs = attrs.buildInputs ++ extraEnvPackages;- });+let+ haskellPackages = if compiler == null then+ pkgs.haskellPackages+ else+ pkgs.haskell.packages.${compiler}; -in- drv // { env = envWithExtras; }+in haskellPackages.developPackage {+ name = "";+ root = pkgs.nix-gitignore.gitignoreSource [ ] ./.;+}
− shell.nix
@@ -1,5 +0,0 @@-{ pkgs ? import <nixpkgs> {}-, compiler ? "ghc864"-}:--(import ./default.nix { inherit pkgs compiler; }).env
src/Data/Vector/Generic/Mutable/Sized.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}@@ -68,10 +67,8 @@ , unsafeModify , unsafeSwap , unsafeExchange-#if MIN_VERSION_vector(0,12,0) -- * Modifying vectors , nextPermutation-#endif -- ** Filling and copying , set , copy@@ -386,7 +383,6 @@ unsafeExchange (MVector v) = VGM.unsafeExchange v {-# inline unsafeExchange #-} -#if MIN_VERSION_vector(0,12,0) -- * Modifying vectors -- | Compute the next permutation (in lexicographic order) of a given vector@@ -395,7 +391,6 @@ => MVector v n (PrimState m) e -> m Bool nextPermutation (MVector v) = VGM.nextPermutation v {-# inline nextPermutation #-}-#endif -- ** Filling and copying
src/Data/Vector/Generic/Mutable/Sized/Internal.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE KindSignatures #-} {-# OPTIONS_HADDOCK not-home #-}@@ -10,7 +9,6 @@ ) where -import GHC.Generics ( Generic ) import GHC.TypeLits import Control.DeepSeq ( NFData ) import Data.Data@@ -21,4 +19,4 @@ -- Be careful when using the constructor here to not construct sized vectors -- which have a different length than that specified in the type parameter! newtype MVector v (n :: Nat) s a = MVector (v s a)- deriving ( Generic, Typeable, Data, Storable, NFData )+ deriving ( Typeable, Data, Storable, NFData )
src/Data/Vector/Generic/Sized.hs view
@@ -1,11 +1,7 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE KindSignatures #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE RankNTypes #-}@@ -13,11 +9,12 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE CPP #-}--#if MIN_VERSION_base(4,12,0)+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoStarIsType #-}-#endif {-# OPTIONS_GHC -Wno-orphans #-} {-|@@ -68,6 +65,8 @@ , empty , singleton , fromTuple+ , BuildVector(..)+ , pattern Build , replicate , replicate' , generate@@ -114,6 +113,7 @@ , unsafeBackpermute -- * Lenses , ix+ , ix' , _head , _last -- * Elementwise operations@@ -245,21 +245,29 @@ , withSized , fromSized , withVectorUnsafe+ , zipVectorsUnsafe ) where import Data.Vector.Generic.Sized.Internal import qualified Data.Vector.Generic as VG+import qualified Data.Vector.Generic.Mutable as VGM import qualified Data.Vector as Boxed import qualified Data.Vector.Storable as Storable import qualified Data.Vector.Unboxed as Unboxed import qualified Data.Vector.Generic.Mutable.Sized as SVGM import Data.Vector.Generic.Mutable.Sized.Internal-import GHC.TypeLits+import Data.Binary+import Data.Bits import Data.Bifunctor-import Data.Finite+import Data.Foldable (for_)+import Data.Coerce+import Data.Finite hiding (shift) import Data.Finite.Internal import Data.Proxy+import qualified Control.Exception as Exception+import Control.Monad (mzero) import Control.Monad.Primitive+import Control.Monad.ST import Foreign.Storable import Data.Data import Control.Comonad@@ -268,21 +276,23 @@ import Text.Read.Lex import Text.ParserCombinators.ReadPrec import GHC.Read+import GHC.TypeLits import Unsafe.Coerce import qualified Data.Functor.Rep as Rep import Data.Distributive import Prelude- hiding (length, replicate, (++), head, last, init, tail, take,+ hiding (Foldable(..), replicate, (++), head, last, init, tail, take, drop, splitAt, reverse, map, concatMap, zipWith, zipWith3, zip,- zip3, unzip, unzip3, elem, notElem, foldl, foldl1, foldr, foldr1,- all, any, and, or, sum, product, maximum, minimum, scanl, scanl1,+ zip3, unzip, unzip3, notElem,+ all, any, and, or, scanl, scanl1, scanr, scanr1, mapM, mapM_, sequence, sequence_)-- import Data.IndexedListLiterals hiding (toList, fromList) import Data.Hashable (Hashable(..)) import qualified Data.IndexedListLiterals as ILL import Data.Vector.Unboxed (Unbox)+import qualified Data.Traversable.WithIndex as ITraversable+import qualified Data.Foldable.WithIndex as IFoldable+import qualified Data.Functor.WithIndex as IFunctor instance (KnownNat n, VG.Vector v a, Read (v a)) => Read (Vector v n a) where readPrec = parens $ prec 10 $ do@@ -316,9 +326,7 @@ -- @'join' :: Vector n (Vector n a) -> Vector n a@ gets the /diagonal/ from -- a square "matrix". instance KnownNat n => Monad (Vector Boxed.Vector n) where- return = replicate xs >>= f = imap (\i x -> f x `index` i) xs- (>>) = seq -- | Non-empty sized vectors are lawful comonads. --@@ -361,11 +369,6 @@ -- 'Monoid' will dodge the 'KnownNat' constraint. instance (Monoid m, VG.Vector v m, KnownNat n) => Monoid (Vector v n m) where mempty = replicate mempty-#if MIN_VERSION_base(4,11,0)- -- begone, non-canonical mappend!-#else- mappend = zipWith mappend-#endif mconcat vs = generate $ mconcat . flip fmap vs . flip index instance KnownNat n => Distributive (Vector Boxed.Vector n) where@@ -462,6 +465,14 @@ ix n f vector = (\x -> vector // [(n, x)]) <$> f (index vector n) {-# inline ix #-} +-- | Type-safe lens to access (/O(1)/) and update (/O(n)/) an arbitrary element by its index+-- which should be supplied via TypeApplications.+ix' :: forall i v n a f. (VG.Vector v a, Functor f,+ KnownNat i, KnownNat n, i+1 <= n)+ => (a -> f a) -> Vector v n a -> f (Vector v n a)+ix' = ix (natToFinite (Proxy::Proxy i))+{-# inline ix' #-}+ -- | Lens to access (/O(1)/) and update (/O(n)/) the first element of a non-empty vector. _head :: forall v n a f. (VG.Vector v a, Functor f) => (a -> f a) -> Vector v (1+n) a -> f (Vector v (1+n) a)@@ -474,7 +485,7 @@ _last f vector = snoc (init vector) <$> f (last vector) {-# inline _last #-} --- | /O(1)/ Safe indexing in a monad. +-- | /O(1)/ Safe indexing in a monad. -- -- The monad allows operations to be strict in the vector when necessary. -- Suppose vector copying is implemented like this:@@ -637,16 +648,43 @@ singleton a = Vector (VG.singleton a) {-# inline singleton #-} --- | /O(n)/ Construct a vector in a type-safe manner.+-- | /O(n)/ Construct a vector in a type-safe manner using a tuple. -- @ -- fromTuple (1,2) :: Vector v 2 Int -- fromTuple ("hey", "what's", "going", "on") :: Vector v 4 String -- @+--+-- @since 1.6.0 fromTuple :: forall v a input length. (VG.Vector v a, IndexedListLiterals input length a, KnownNat length) => input -> Vector v length a fromTuple = Vector . VG.fromListN (fromIntegral $ natVal $ Proxy @length) . ILL.toList +infixr 5 :<++-- | @since 1.6.0+data BuildVector (n :: Nat) a where+ -- | @since 1.6.0+ Nil :: BuildVector 0 a+ -- | @since 1.6.0+ (:<) :: a -> BuildVector n a -> BuildVector (1 + n) a++-- | @since 1.6.0+deriving instance Show a => Show (BuildVector n a)++-- | /O(n)/ Construct a vector in a type-safe manner using a sized linked list.+-- @+-- Build (1 :< 2 :< 3 :< Nil) :: Vector v 3 Int+-- Build ("not" :< "much" :< Nil) :: Vector v 2 String+-- @+-- Can also be used as a pattern.+--+-- @since 1.6.0+pattern Build :: VG.Vector v a => BuildVector n a -> Vector v n a+pattern Build build <- ( ( \ ( Vector v ) -> unsafeCoerce $ VG.toList v ) -> build )+ where+ Build vec = Vector . VG.fromList . unsafeCoerce $ vec+ -- | /O(n)/ Construct a vector with the same element in each position where the -- length is inferred from the type. replicate :: forall v n a. (KnownNat n, VG.Vector v a)@@ -911,9 +949,10 @@ accum :: VG.Vector v a => (a -> b -> a) -- ^ accumulating function @f@ -> Vector v m a -- ^ initial vector (of length @m@)- -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)+ -> [(Finite m,b)] -- ^ list of index/value pairs (of length @n@) -> Vector v m a-accum f (Vector v) us = Vector (VG.accum f v us)+accum f (Vector v) us =+ Vector (VG.accum f v $ (fmap . first) (fromIntegral . getFinite) us) {-# inline accum #-} -- | /O(m+n)/ For each pair @(i,b)@ from the vector of pairs, replace the vector@@ -1039,10 +1078,10 @@ -- | /O(n*m)/ Map a function over a vector and concatenate the results. The -- function is required to always return a vector of the same length.-concatMap :: (VG.Vector v a, VG.Vector v' b) +concatMap :: (VG.Vector v a, VG.Vector v' b) => (a -> Vector v' m b) -> Vector v n a -> Vector v' (n*m) b concatMap f (Vector v) = Vector . VG.concat . fmap (fromSized . f) . VG.toList $ v-{-# inline concatMap #-} +{-# inline concatMap #-} -- -- ** Monadic mapping@@ -1620,23 +1659,23 @@ {-# inline postscanl' #-} -- | /O(n)/ Haskell-style scan.-scanl :: (VG.Vector v a, VG.Vector v b) => (a -> b -> a) -> a -> Vector v n b -> Vector v n a-scanl f z = withVectorUnsafe (VG.scanl f z )+scanl :: (VG.Vector v a, VG.Vector v b) => (a -> b -> a) -> a -> Vector v n b -> Vector v (1+n) a+scanl f z (Vector v) = Vector (VG.scanl f z v) {-# inline scanl #-} -- | /O(n)/ Haskell-style scan with strict accumulator.-scanl' :: (VG.Vector v a, VG.Vector v b) => (a -> b -> a) -> a -> Vector v n b -> Vector v n a-scanl' f z = withVectorUnsafe (VG.scanl' f z )+scanl' :: (VG.Vector v a, VG.Vector v b) => (a -> b -> a) -> a -> Vector v n b -> Vector v (1+n) a+scanl' f z (Vector v) = Vector (VG.scanl' f z v) {-# inline scanl' #-} -- | /O(n)/ Scan over a non-empty vector.-scanl1 :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> Vector v (n+1) a-scanl1 f = withVectorUnsafe (VG.scanl1 f )+scanl1 :: VG.Vector v a => (a -> a -> a) -> Vector v (1+n) a -> Vector v (2+n) a+scanl1 f (Vector v) = Vector (VG.scanl1 f v) {-# inline scanl1 #-} -- | /O(n)/ Scan over a non-empty vector with a strict accumulator.-scanl1' :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> Vector v (n+1) a-scanl1' f = withVectorUnsafe (VG.scanl1' f )+scanl1' :: VG.Vector v a => (a -> a -> a) -> Vector v (1+n) a -> Vector v (2+n) a+scanl1' f (Vector v) = Vector (VG.scanl1' f v) {-# inline scanl1' #-} -- | /O(n)/ Right-to-left prescan.@@ -1660,24 +1699,24 @@ {-# inline postscanr' #-} -- | /O(n)/ Right-to-left Haskell-style scan.-scanr :: (VG.Vector v a, VG.Vector v b) => (a -> b -> b) -> b -> Vector v n a -> Vector v n b-scanr f z = withVectorUnsafe (VG.scanr f z )+scanr :: (VG.Vector v a, VG.Vector v b) => (a -> b -> b) -> b -> Vector v n a -> Vector v (n+1) b+scanr f z (Vector v) = Vector (VG.scanr f z v) {-# inline scanr #-} -- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator.-scanr' :: (VG.Vector v a, VG.Vector v b) => (a -> b -> b) -> b -> Vector v n a -> Vector v n b-scanr' f z = withVectorUnsafe (VG.scanr' f z )+scanr' :: (VG.Vector v a, VG.Vector v b) => (a -> b -> b) -> b -> Vector v n a -> Vector v (n+1) b+scanr' f z (Vector v) = Vector (VG.scanr' f z v) {-# inline scanr' #-} -- | /O(n)/ Right-to-left scan over a non-empty vector.-scanr1 :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> Vector v (n+1) a-scanr1 f = withVectorUnsafe (VG.scanr1 f )+scanr1 :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> Vector v (n+2) a+scanr1 f (Vector v) = Vector (VG.scanr1 f v) {-# inline scanr1 #-} -- | /O(n)/ Right-to-left scan over a non-empty vector with a strict -- accumulator.-scanr1' :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> Vector v (n+1) a-scanr1' f = withVectorUnsafe (VG.scanr1' f )+scanr1' :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> Vector v (n+2) a+scanr1' f (Vector v) = Vector (VG.scanr1' f v) {-# inline scanr1' #-} @@ -1800,6 +1839,12 @@ withVectorUnsafe f (Vector v) = Vector (f v) {-# inline withVectorUnsafe #-} +-- | Apply a function on two unsized vectors to sized vectors. The function must+-- preserve the size of the vectors, this is not checked.+zipVectorsUnsafe :: (u a -> v b -> w c) -> Vector u n a -> Vector v n b -> Vector w n c+zipVectorsUnsafe f (Vector u) (Vector v) = Vector (f u v)+{-# inline zipVectorsUnsafe #-}+ -- | Internal existential wrapper used for implementing 'SomeSized' -- pattern synonym data SV_ v a = forall n. KnownNat n => SV_ (Vector v n a)@@ -1855,7 +1900,7 @@ -- @ -- -- Remember that the final type of the result of the do block ('()', here)--- must not depend on @n@. However, the +-- must not depend on @n@. However, the -- -- Also useful in ghci, where you can pattern match to get sized vectors -- from unsized vectors.@@ -1928,3 +1973,93 @@ asinh = map asinh acosh = map acosh atanh = map atanh++instance (VG.Vector v a, Binary a, KnownNat n) => Binary (Vector v n a) where+ get = replicateM Data.Binary.get+ put = mapM_ put++-- | Only usable if @v a@ is itself an instance of 'Bits', like in the case+-- with the bitvec library @Bit@ type for unboxed vectors.+instance (VG.Vector v a, Bits (v a), Bits a, KnownNat n) => Bits (Vector v n a) where+ (.&.) = coerce ((.&.) @(v a))+ (.|.) = coerce ((.|.) @(v a))+ xor = coerce (xor @(v a))+ complement = coerce (complement @(v a))+ rotate = coerce (rotate @(v a))+ rotateL = coerce (rotateL @(v a))+ rotateR = coerce (rotateR @(v a))+ bitSize x = case bitSizeMaybe x of+ Nothing -> error "Vector v n a: bitSize"+ Just c -> c+ bitSizeMaybe _ = (* fromInteger (natVal (Proxy @n))) <$> bitSizeMaybe @a undefined+ isSigned _ = False+ testBit = coerce (testBit @(v a))+ popCount = coerce (popCount @(v a))+ setBit = coerce (setBit @(v a))+ complementBit = coerce (complementBit @(v a))+ -- need to do special stuff because they return a vector from scratch+ bit n = runST $ do+ v <- SVGM.replicate zeroBits+ for_ (packFinite (fromIntegral n)) $ \i ->+ SVGM.write v i (complement zeroBits)+ freeze v+ zeroBits = replicate zeroBits+ -- need to do special stuff because they have to preserve vector size+ shiftL xs i+ | i < 0 = Exception.throw Exception.Overflow+ | otherwise = unsafeShiftL xs i+ unsafeShiftL (Vector xs) i+ | i == 0 = Vector xs+ | i' == n = replicate zeroBits+ | otherwise = Vector $ runST $ do+ u <- VGM.replicate n zeroBits+ VG.unsafeCopy (VGM.unsafeDrop i' u) (VG.unsafeTake (n - i') xs)+ VG.unsafeFreeze u+ where+ n = fromInteger $ natVal (Proxy @n)+ i' = min n i+ shiftR xs i+ | i < 0 = Exception.throw Exception.Overflow+ | otherwise = unsafeShiftR xs i+ unsafeShiftR (Vector xs) i+ | i == 0 = Vector xs+ | i' == n = replicate zeroBits+ | otherwise = Vector $ runST $ do+ u <- VGM.replicate n zeroBits+ VG.unsafeCopy (VGM.unsafeTake (n - i') u) (VG.unsafeDrop i' xs)+ VG.unsafeFreeze u+ where+ n = fromInteger $ natVal (Proxy @n)+ i' = min n i++-- | Treats a bit vector as n times the size of the stored bits, reflecting+-- the 'Bits' instance; does not necessarily reflect exact in-memory+-- representation. See 'Storable' instance to get information on the+-- actual in-memry representation.+instance (VG.Vector v a, Bits (v a), FiniteBits a, KnownNat n) => FiniteBits (Vector v n a) where+ finiteBitSize _ = finiteBitSize @a undefined * fromIntegral (natVal (Proxy @n))++-- | @since 1.6.0+instance IFunctor.FunctorWithIndex (Finite n) (Vector Boxed.Vector n) where+ {-# INLINEABLE imap #-}+ imap = imap++-- | @since 1.6.0+instance IFoldable.FoldableWithIndex (Finite n) (Vector Boxed.Vector n) where+ {-# INLINEABLE ifoldMap #-}+ ifoldMap f = ifoldl (\acc ix x -> acc `mappend` f ix x) mempty+ {-# INLINEABLE ifoldMap' #-}+ ifoldMap' f = ifoldl' (\acc ix x -> acc `mappend` f ix x) mempty+ {-# INLINEABLE ifoldr #-}+ ifoldr = ifoldr+ {-# INLINEABLE ifoldl #-}+ ifoldl f x = ifoldl (\acc ix -> f ix acc) x+ {-# INLINEABLE ifoldr' #-}+ ifoldr' = ifoldr'+ {-# INLINEABLE ifoldl' #-}+ ifoldl' f x = ifoldl' (\acc ix -> f ix acc) x++-- | @since 1.6.0+instance ITraversable.TraversableWithIndex (Finite n) (Vector Boxed.Vector n) where+ {-# INLINEABLE itraverse #-}+ itraverse f = traverse (uncurry f) . indexed
src/Data/Vector/Generic/Sized/Internal.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}@@ -41,7 +40,6 @@ , unsafeRangeSize ) )-import GHC.Generics ( Generic ) import GHC.TypeLits ( Nat ) -- | A wrapper to tag vectors with a type level length.@@ -49,7 +47,7 @@ -- Be careful when using the constructor here to not construct sized vectors -- which have a different length than that specified in the type parameter! newtype Vector v (n :: Nat) a = Vector (v a)- deriving ( Show, Eq, Ord, Functor, Foldable, Traversable, NFData, Generic+ deriving ( Show, Eq, Ord, Functor, Foldable, Traversable, NFData , Show1, Eq1, Ord1 , Data, Typeable )
src/Data/Vector/Mutable/Sized.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-}@@ -64,10 +63,8 @@ , unsafeModify , unsafeSwap , unsafeExchange-#if MIN_VERSION_vector(0,12,0) -- * Modifying vectors , nextPermutation-#endif -- ** Filling and copying , set , copy@@ -378,7 +375,6 @@ unsafeExchange = VGM.unsafeExchange {-# inline unsafeExchange #-} -#if MIN_VERSION_vector(0,12,0) -- * Modifying vectors -- | Compute the next permutation (lexicographically) of a given vector@@ -387,7 +383,6 @@ => MVector n (PrimState m) e -> m Bool nextPermutation = VGM.nextPermutation {-# inline nextPermutation #-}-#endif -- ** Filling and copying
+ src/Data/Vector/Primitive/Mutable/Sized.hs view
@@ -0,0 +1,466 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeOperators #-}++{-|+This module re-exports the functionality in 'Data.Vector.Generic.Mutable.Sized'+ specialized to 'Data.Vector.Primitive.Mutable'.++Functions returning a vector determine the size from the type context unless+they have a @'@ suffix in which case they take an explicit 'Proxy' argument.++Functions where the resulting vector size is not known until runtime are+not exported.+-}++module Data.Vector.Primitive.Mutable.Sized+ ( MVector+ -- * Accessors+ -- ** Length information+ , length+ , length'+ , null+ -- ** Extracting subvectors+ , slice+ , slice'+ , init+ , tail+ , take+ , take'+ , drop+ , drop'+ , splitAt+ , splitAt'+ -- ** Overlaps+ , overlaps+ -- * Construction+ -- ** Initialisation+ , new+ , unsafeNew+ , replicate+ , replicate'+ , replicateM+ , replicateM'+ , clone+ -- ** Growing+ , grow+ , growFront+ -- ** Restricting memory usage+ , clear+ -- * Accessing individual elements+ , read+ , read'+ , write+ , write'+ , modify+ , modify'+ , swap+ , exchange+ , exchange'+ , unsafeRead+ , unsafeWrite+ , unsafeModify+ , unsafeSwap+ , unsafeExchange+ -- * Modifying vectors+ , nextPermutation+ -- ** Filling and copying+ , set+ , copy+ , move+ , unsafeCopy+ -- * Conversions+ -- ** Unsized Mutable Vectors+ , toSized+ , withSized+ , fromSized+ ) where++import qualified Data.Vector.Generic.Mutable.Sized as VGM+import qualified Data.Vector.Primitive.Mutable as VSM+import GHC.TypeLits+import Data.Finite+import Data.Primitive (Prim)+import Data.Proxy+import Control.Monad.Primitive+import Prelude hiding ( length, null, replicate, init,+ tail, take, drop, splitAt, read )+++-- | 'Data.Vector.Generic.Mutable.Sized.Vector' specialized to use+-- 'Data.Vector.Primitive.Mutable'.+type MVector = VGM.MVector VSM.MVector++-- * Accessors++-- ** Length information++-- | /O(1)/ Yield the length of the mutable vector as an 'Int'.+length :: forall n s a. (KnownNat n)+ => MVector n s a -> Int+length = VGM.length+{-# inline length #-}++-- | /O(1)/ Yield the length of the mutable vector as a 'Proxy'.+length' :: forall n s a. ()+ => MVector n s a -> Proxy n+length' = VGM.length'+{-# inline length' #-}++-- | /O(1)/ Check whether the mutable vector is empty.+null :: forall n s a. (KnownNat n)+ => MVector n s a -> Bool+null = VGM.null+{-# inline null #-}++-- ** Extracting subvectors++-- | /O(1)/ Yield a slice of the mutable vector without copying it with an+-- inferred length argument.+slice :: forall i n k s a p. (KnownNat i, KnownNat n, Prim a)+ => p i -- ^ starting index+ -> MVector (i+n+k) s a+ -> MVector n s a+slice = VGM.slice+{-# inline slice #-}++-- | /O(1)/ Yield a slice of the mutable vector without copying it with an+-- explicit length argument.+slice' :: forall i n k s a p+ . (KnownNat i, KnownNat n, Prim a)+ => p i -- ^ starting index+ -> p n -- ^ length+ -> MVector (i+n+k) s a+ -> MVector n s a+slice' = VGM.slice'+{-# inline slice' #-}++-- | /O(1)/ Yield all but the last element of a non-empty mutable vector+-- without copying.+init :: forall n s a. Prim a+ => MVector (n+1) s a -> MVector n s a+init = VGM.init+{-# inline init #-}++-- | /O(1)/ Yield all but the first element of a non-empty mutable vector+-- without copying.+tail :: forall n s a. Prim a+ => MVector (1+n) s a -> MVector n s a+tail = VGM.tail+{-# inline tail #-}++-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains+-- this many elements. The length of the resulting vector is inferred from the+-- type.+take :: forall n k s a. (KnownNat n, Prim a)+ => MVector (n+k) s a -> MVector n s a+take = VGM.take+{-# inline take #-}++-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains+-- this many elements. The length of the resulting vector is given explicitly+-- as a 'Proxy' argument.+take' :: forall n k s a p. (KnownNat n, Prim a)+ => p n -> MVector (n+k) s a -> MVector n s a+take' = VGM.take'+{-# inline take' #-}++-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must+-- contain at least this many elements. The length of the resulting vector is+-- inferred from the type.+drop :: forall n k s a. (KnownNat n, Prim a)+ => MVector (n+k) s a -> MVector k s a+drop = VGM.drop+{-# inline drop #-}++-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must+-- contain at least this many elements. The length of the resulting vector is+-- givel explicitly as a 'Proxy' argument.+drop' :: forall n k s a p. (KnownNat n, Prim a)+ => p n -> MVector (n+k) s a -> MVector k s a+drop' = VGM.drop'+{-# inline drop' #-}++-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.+-- The lengths of the resulting vectors are inferred from the type.+splitAt :: forall n m s a. (KnownNat n, Prim a)+ => MVector (n+m) s a -> (MVector n s a, MVector m s a)+splitAt = VGM.splitAt+{-# inline splitAt #-}++-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without+-- copying. The length of the first resulting vector is passed explicitly as a+-- 'Proxy' argument.+splitAt' :: forall n m s a p. (KnownNat n, Prim a)+ => p n -> MVector (n+m) s a -> (MVector n s a, MVector m s a)+splitAt' = VGM.splitAt'+{-# inline splitAt' #-}++-- ** Overlaps++-- | /O(1)/ Check if two vectors overlap.+overlaps :: forall n k s a. Prim a+ => MVector n s a+ -> MVector k s a+ -> Bool+overlaps = VGM.overlaps+{-# inline overlaps #-}++-- * Construction++-- ** Initialisation++-- | Create a mutable vector where the length is inferred from the type.+new :: forall n m a. (KnownNat n, PrimMonad m, Prim a)+ => m (MVector n (PrimState m) a)+new = VGM.new+{-# inline new #-}++-- | Create a mutable vector where the length is inferred from the type.+-- The memory is not initialized.+unsafeNew :: forall n m a. (KnownNat n, PrimMonad m, Prim a)+ => m (MVector n (PrimState m) a)+unsafeNew = VGM.unsafeNew+{-# inline unsafeNew #-}++-- | Create a mutable vector where the length is inferred from the type and+-- fill it with an initial value.+replicate :: forall n m a. (KnownNat n, PrimMonad m, Prim a)+ => a -> m (MVector n (PrimState m) a)+replicate = VGM.replicate+{-# inline replicate #-}++-- | Create a mutable vector where the length is given explicitly as+-- a 'Proxy' argument and fill it with an initial value.+replicate' :: forall n m a p. (KnownNat n, PrimMonad m, Prim a)+ => p n -> a -> m (MVector n (PrimState m) a)+replicate' = VGM.replicate'+{-# inline replicate' #-}++-- | Create a mutable vector where the length is inferred from the type and+-- fill it with values produced by repeatedly executing the monadic action.+replicateM :: forall n m a. (KnownNat n, PrimMonad m, Prim a)+ => m a -> m (MVector n (PrimState m) a)+replicateM = VGM.replicateM+{-# inline replicateM #-}++-- | Create a mutable vector where the length is given explicitly as+-- a 'Proxy' argument and fill it with values produced by repeatedly+-- executing the monadic action.+replicateM' :: forall n m a p. (KnownNat n, PrimMonad m, Prim a)+ => p n -> m a -> m (MVector n (PrimState m) a)+replicateM' = VGM.replicateM'+{-# inline replicateM' #-}++-- | Create a copy of a mutable vector.+clone :: forall n m a. (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -> m (MVector n (PrimState m) a)+clone = VGM.clone+{-# inline clone #-}++-- ** Growing++-- | Grow a mutable vector by an amount given explicitly as a 'Proxy'+-- argument.+grow :: forall n k m a p. (KnownNat k, PrimMonad m, Prim a)+ => p k -> MVector n (PrimState m) a -> m (MVector (n + k) (PrimState m) a)+grow = VGM.grow+{-# inline grow #-}++-- | Grow a mutable vector (from the front) by an amount given explicitly+-- as a 'Proxy' argument.+growFront :: forall n k m a p. (KnownNat k, PrimMonad m, Prim a)+ => p k -> MVector n (PrimState m) a -> m (MVector (n + k) (PrimState m) a)+growFront = VGM.growFront+{-# inline growFront #-}++-- ** Restricting memory usage++-- | Reset all elements of the vector to some undefined value, clearing all+-- references to external objects.+clear :: (PrimMonad m, Prim a) => MVector n (PrimState m) a -> m ()+clear = VGM.clear+{-# inline clear #-}++-- * Accessing individual elements++-- | /O(1)/ Yield the element at a given type-safe position using 'Finite'.+read :: forall n m a. (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -> Finite n -> m a+read = VGM.read+{-# inline read #-}++-- | /O(1)/ Yield the element at a given type-safe position using 'Proxy'.+read' :: forall n k a m p. (KnownNat k, PrimMonad m, Prim a)+ => MVector (n+k+1) (PrimState m) a -> p k -> m a+read' = VGM.read'+{-# inline read' #-}++-- | /O(1)/ Yield the element at a given 'Int' position without bounds+-- checking.+unsafeRead :: forall n a m. (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -> Int -> m a+unsafeRead = VGM.unsafeRead+{-# inline unsafeRead #-}++-- | /O(1)/ Replace the element at a given type-safe position using 'Finite'.+write :: forall n m a. (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -> Finite n -> a -> m ()+write = VGM.write+{-# inline write #-}++-- | /O(1)/ Replace the element at a given type-safe position using 'Proxy'.+write' :: forall n k a m p. (KnownNat k, PrimMonad m, Prim a)+ => MVector (n+k+1) (PrimState m) a -> p k -> a -> m ()+write' = VGM.write'+{-# inline write' #-}++-- | /O(1)/ Replace the element at a given 'Int' position without bounds+-- checking.+unsafeWrite :: forall n m a. (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -> Int -> a -> m ()+unsafeWrite = VGM.unsafeWrite+{-# inline unsafeWrite #-}++-- | /O(1)/ Modify the element at a given type-safe position using 'Finite'.+modify :: forall n m a. (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -> (a -> a) -> Finite n -> m ()+modify = VGM.modify+{-# inline modify #-}++-- | /O(1)/ Modify the element at a given type-safe position using 'Proxy'.+modify' :: forall n k a m p. (KnownNat k, PrimMonad m, Prim a)+ => MVector (n+k+1) (PrimState m) a -> (a -> a) -> p k -> m ()+modify' = VGM.modify'+{-# inline modify' #-}++-- | /O(1)/ Modify the element at a given 'Int' position without bounds+-- checking.+unsafeModify :: forall n m a. (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -> (a -> a) -> Int -> m ()+unsafeModify = VGM.unsafeModify+{-# inline unsafeModify #-}++-- | /O(1)/ Swap the elements at the given type-safe positions using 'Finite's.+swap :: forall n m a. (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -> Finite n -> Finite n -> m ()+swap = VGM.swap+{-# inline swap #-}++-- | /O(1)/ Swap the elements at the given 'Int' positions without bounds+-- checking.+unsafeSwap :: forall n m a. (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -> Int -> Int -> m ()+unsafeSwap = VGM.unsafeSwap+{-# inline unsafeSwap #-}++-- | /O(1)/ Replace the element at a given type-safe position and return+-- the old element, using 'Finite'.+exchange :: forall n m a. (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -> Finite n -> a -> m a+exchange = VGM.exchange+{-# inline exchange #-}++-- | /O(1)/ Replace the element at a given type-safe position and return+-- the old element, using 'Finite'.+exchange' :: forall n k a m p. (KnownNat k, PrimMonad m, Prim a)+ => MVector (n+k+1) (PrimState m) a -> p k -> a -> m a+exchange' = VGM.exchange'+{-# inline exchange' #-}++-- | /O(1)/ Replace the element at a given 'Int' position and return+-- the old element. No bounds checks are performed.+unsafeExchange :: forall n m a. (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -> Int -> a -> m a+unsafeExchange = VGM.unsafeExchange+{-# inline unsafeExchange #-}++-- * Modifying vectors++-- | Compute the next permutation (lexicographically) of a given vector+-- in-place. Returns 'False' when the input is the last permutation.+nextPermutation :: forall n e m. (Ord e, PrimMonad m, Prim e)+ => MVector n (PrimState m) e -> m Bool+nextPermutation = VGM.nextPermutation+{-# inline nextPermutation #-}++-- ** Filling and copying++-- | Set all elements of the vector to the given value.+set :: (PrimMonad m, Prim a) => MVector n (PrimState m) a -> a -> m ()+set = VGM.set+{-# inline set #-}++-- | Copy a vector. The two vectors may not overlap.+copy :: (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -- ^ target+ -> MVector n (PrimState m) a -- ^ source+ -> m ()+copy = VGM.copy+{-# inline copy #-}++-- * Conversions++-- ** Unsized Mutable Vectors++-- | Copy a vector. The two vectors may not overlap. This is not checked.+unsafeCopy :: (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -- ^ target+ -> MVector n (PrimState m) a -- ^ source+ -> m ()+unsafeCopy = VGM.unsafeCopy+{-# inline unsafeCopy #-}++-- | Move the contents of a vector. If the two vectors do not overlap,+-- this is equivalent to 'copy'. Otherwise, the copying is performed as if+-- the source vector were copied to a temporary vector and then the+-- temporary vector was copied to the target vector.+move :: (PrimMonad m, Prim a)+ => MVector n (PrimState m) a -- ^ target+ -> MVector n (PrimState m) a -- ^ source+ -> m ()+move = VGM.move+{-# inline move #-}++-- | Convert a 'Data.Vector.Primitive.Mutable.MVector' into+-- a 'Data.Vector.Primitive.Mutable.Sized.MVector' if it has the correct+-- size, otherwise return Nothing.+--+-- Note that this does no copying; the returned 'MVector' is a reference to+-- the exact same vector in memory as the given one, and any modifications+-- to it are also reflected in the given+-- 'Data.Vector.Primitive.Mutable.MVector'.+toSized :: forall n a s. (KnownNat n, Prim a)+ => VSM.MVector s a -> Maybe (MVector n s a)+toSized = VGM.toSized+{-# inline toSized #-}++-- | Takes a 'Data.Vector.Primitive.Mutable.MVector' and returns+-- a continuation providing a 'Data.Vector.Primitive.Mutable.Sized.MVector'+-- with a size parameter @n@ that is determined at runtime based on the+-- length of the input vector.+--+-- Essentially converts a 'Data.Vector.Primitive.Mutable.MVector' into+-- a 'Data.Vector.Primitive.Sized.MVector' with the correct size parameter+-- @n@.+--+-- Note that this does no copying; the returned 'MVector' is a reference to+-- the exact same vector in memory as the given one, and any modifications+-- to it are also reflected in the given+-- 'Data.Vector.Primitive.Mutable.MVector'.+withSized :: forall s a r. Prim a+ => VSM.MVector s a -> (forall n. KnownNat n => MVector n s a -> r) -> r+withSized = VGM.withSized+{-# inline withSized #-}++-- | Convert a 'Data.Vector.Primitive.Mutable.Sized.MVector' into a+-- 'Data.Vector.Primitive.Mutable.MVector'.+--+-- Note that this does no copying; the returned+-- 'Data.Vector.Primitive.Mutable.MVector' is a reference to the exact same+-- vector in memory as the given one, and any modifications to it are also+-- reflected in the given 'MVector'.+fromSized :: MVector n s a -> VSM.MVector s a+fromSized = VGM.fromSized+{-# inline fromSized #-}
+ src/Data/Vector/Primitive/Sized.hs view
@@ -0,0 +1,1508 @@+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE NoStarIsType #-}++{-|+This module re-exports the functionality in 'Data.Vector.Generic.Sized'+ specialized to 'Data.Vector.Primitive'.++Functions returning a vector determine the size from the type context unless+they have a @'@ suffix in which case they take an explicit 'Proxy' argument.++Functions where the resulting vector size is not known until runtime are+not exported.+-}++module Data.Vector.Primitive.Sized+ ( Vector+ , pattern SomeSized+ , VSM.MVector+ -- * Accessors+ -- ** Length information+ , length+ , length'+ , knownLength+ , knownLength'+ -- ** Indexing+ , index+ , index'+ , unsafeIndex+ , head+ , last+ -- ** Monadic indexing+ , indexM+ , indexM'+ , unsafeIndexM+ , headM+ , lastM+ -- ** Extracting subvectors (slicing)+ , slice+ , slice'+ , init+ , tail+ , take+ , take'+ , drop+ , drop'+ , splitAt+ , splitAt'+ -- * Construction+ -- ** Initialization+ , empty+ , singleton+ , fromTuple+ , replicate+ , replicate'+ , generate+ , generate'+ , iterateN+ , iterateN'+ -- ** Monadic initialization+ , replicateM+ , replicateM'+ , generateM+ , generateM'+ -- ** Unfolding+ , unfoldrN+ , unfoldrN'+ -- ** Enumeration+ , enumFromN+ , enumFromN'+ , enumFromStepN+ , enumFromStepN'+ -- ** Concatenation+ , cons+ , snoc+ , (++)+ -- ** Restricting memory usage+ , force+ -- * Modifying vectors+ -- ** Bulk updates+ , (//)+ , update_+ , unsafeUpd+ , unsafeUpdate_+ -- ** Accumulations+ , accum+ , accumulate_+ , unsafeAccum+ , unsafeAccumulate_+ -- ** Permutations+ , reverse+ , backpermute+ , unsafeBackpermute+ -- * Lenses+ , ix+ , _head+ , _last+ -- * Elementwise operations+ -- ** Mapping+ , map+ , imap+ , concatMap+ -- ** Monadic mapping+ , mapM+ , imapM+ , mapM_+ , imapM_+ , forM+ , forM_+ -- ** Zipping+ , zipWith+ , zipWith3+ , zipWith4+ , zipWith5+ , zipWith6+ , izipWith+ , izipWith3+ , izipWith4+ , izipWith5+ , izipWith6+ -- ** Monadic zipping+ , zipWithM+ , izipWithM+ , zipWithM_+ , izipWithM_+ -- * Working with predicates+ -- ** Searching+ , elem+ , notElem+ , find+ , findIndex+ , elemIndex+ -- * Folding+ , foldl+ , foldl1+ , foldl'+ , foldl1'+ , foldr+ , foldr1+ , foldr'+ , foldr1'+ , ifoldl+ , ifoldl'+ , ifoldr+ , ifoldr'+ -- ** Specialised folds+ , all+ , any+ , sum+ , product+ , maximum+ , maximumBy+ , minimum+ , minimumBy+ , maxIndex+ , maxIndexBy+ , minIndex+ , minIndexBy+ -- ** Monadic folds+ , foldM+ , ifoldM+ , fold1M+ , foldM'+ , ifoldM'+ , fold1M'+ , foldM_+ , ifoldM_+ , fold1M_+ , foldM'_+ , ifoldM'_+ , fold1M'_+ -- * Prefix sums (scans)+ , prescanl+ , prescanl'+ , postscanl+ , postscanl'+ , scanl+ , scanl'+ , scanl1+ , scanl1'+ , prescanr+ , prescanr'+ , postscanr+ , postscanr'+ , scanr+ , scanr'+ , scanr1+ , scanr1'+ -- * Conversions+ -- ** Lists+ , toList+ , fromList+ , fromListN+ , fromListN'+ , withSizedList+ -- ** Mutable vectors+ , freeze+ , thaw+ , copy+ , unsafeFreeze+ , unsafeThaw+ -- ** Unsized Vectors+ , toSized+ , withSized+ , fromSized+ , withVectorUnsafe+ ) where++import qualified Data.Vector.Generic.Sized as V+import qualified Data.Vector.Primitive as VS+import Data.IndexedListLiterals (IndexedListLiterals)+import qualified Data.Vector.Primitive.Mutable.Sized as VSM+import GHC.TypeLits+import Data.Finite+import Data.Primitive (Prim)+import Data.Proxy+import Control.Monad.Primitive+import Prelude hiding ( Foldable(..),+ replicate, (++), concat,+ head, last,+ init, tail, take, drop, splitAt, reverse,+ map, concat, concatMap,+ zipWith, zipWith3, zip, zip3, unzip, unzip3,+ filter, takeWhile, dropWhile, span, break,+ notElem,+ all, any, and, or,+ scanl, scanl1, scanr, scanr1,+ enumFromTo, enumFromThenTo,+ mapM, mapM_, sequence, sequence_,+ showsPrec )++-- | 'Data.Vector.Generic.Sized.Vector' specialized to use+-- 'Data.Vector.Primitive'.+type Vector = V.Vector VS.Vector++-- | /O(1)/ Yield the length of the vector as an 'Int'. This is more like+-- 'natVal' than 'Data.Vector.length', extracting the value from the 'KnownNat'+-- instance and not looking at the vector itself.+length :: forall n a. KnownNat n+ => Vector n a -> Int+length = V.length+{-# inline length #-}++-- | /O(1)/ Yield the length of the vector as a 'Proxy'. This function+-- doesn't /do/ anything; it merely allows the size parameter of the vector+-- to be passed around as a 'Proxy'.+length' :: forall n a.+ Vector n a -> Proxy n+length' = V.length'+{-# inline length' #-}++-- | /O(1)/ Reveal a 'KnownNat' instance for a vector's length, determined+-- at runtime.+knownLength :: forall n a r. Prim a+ => Vector n a -- ^ a vector of some (potentially unknown) length+ -> (KnownNat n => r) -- ^ a value that depends on knowing the vector's length+ -> r -- ^ the value computed with the length+knownLength = V.knownLength++-- | /O(1)/ Reveal a 'KnownNat' instance and 'Proxy' for a vector's length,+-- determined at runtime.+knownLength' :: forall n a r. Prim a+ => Vector n a -- ^ a vector of some (potentially unknown) length+ -> (KnownNat n => Proxy n -> r) -- ^ a value that depends on knowing the vector's length, which is given as a 'Proxy'+ -> r -- ^ the value computed with the length+knownLength' = V.knownLength'++-- | /O(1)/ Safe indexing using a 'Finite'.+index :: forall n a. Prim a+ => Vector n a -> Finite n -> a+index = V.index+{-# inline index #-}++-- | /O(1)/ Safe indexing using a 'Proxy'.+index' :: forall n m a p. (KnownNat n, Prim a)+ => Vector (n+m+1) a -> p n -> a+index' = V.index'+{-# inline index' #-}++-- | /O(1)/ Indexing using an 'Int' without bounds checking.+unsafeIndex :: forall n a. Prim a+ => Vector n a -> Int -> a+unsafeIndex = V.unsafeIndex+{-# inline unsafeIndex #-}++-- | /O(1)/ Yield the first element of a non-empty vector.+head :: forall n a. (Prim a)+ => Vector (1+n) a -> a+head = V.head+{-# inline head #-}++-- | /O(1)/ Yield the last element of a non-empty vector.+last :: forall n a. (Prim a)+ => Vector (n+1) a -> a+last = V.last+{-# inline last #-}++-- | Lens to access (/O(1)/) and update (/O(n)/) an arbitrary element by its index.+ix :: forall n a f. (Prim a, Functor f)+ => Finite n -> (a -> f a) -> Vector n a -> f (Vector n a)+ix = V.ix+{-# inline ix #-}++-- | Lens to access (/O(1)/) and update (/O(n)/) the first element of a non-empty vector.+_head :: forall n a f. (Prim a, Functor f)+ => (a -> f a) -> Vector (1+n) a -> f (Vector (1+n) a)+_head = V._head+{-# inline _head #-}++-- | Lens to access (/O(1)/) and update (/O(n)/) the last element of a non-empty vector.+_last :: forall n a f. (Prim a, Functor f)+ => (a -> f a) -> Vector (n+1) a -> f (Vector (n+1) a)+_last = V._last+{-# inline _last #-}+++-- | /O(1)/ Safe indexing in a monad. See the documentation for 'Data.Vector.Generic.Sized.indexM' for+-- an explanation of why this is useful.+indexM :: forall n a m. (Prim a, Monad m)+ => Vector n a -> Finite n -> m a+indexM = V.indexM+{-# inline indexM #-}++-- | /O(1)/ Safe indexing in a monad using a 'Proxy'. See the documentation for+-- 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.+indexM' :: forall n k a m p. (KnownNat n, Prim a, Monad m)+ => Vector (n+k) a -> p n -> m a+indexM' = V.indexM'+{-# inline indexM' #-}++-- | /O(1)/ Indexing using an 'Int' without bounds checking. See the+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.+unsafeIndexM :: forall n a m. (Prim a, Monad m)+ => Vector n a -> Int -> m a+unsafeIndexM = V.unsafeIndexM+{-# inline unsafeIndexM #-}++-- | /O(1)/ Yield the first element of a non-empty vector in a monad. See the+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.+headM :: forall n a m. (Prim a, Monad m)+ => Vector (1+n) a -> m a+headM = V.headM+{-# inline headM #-}++-- | /O(1)/ Yield the last element of a non-empty vector in a monad. See the+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.+lastM :: forall n a m. (Prim a, Monad m)+ => Vector (n+1) a -> m a+lastM = V.lastM+{-# inline lastM #-}++-- | /O(1)/ Yield a slice of the vector without copying it with an inferred+-- length argument.+slice :: forall i n m a p. (KnownNat i, KnownNat n, Prim a)+ => p i -- ^ starting index+ -> Vector (i+n+m) a+ -> Vector n a+slice = V.slice+{-# inline slice #-}++-- | /O(1)/ Yield a slice of the vector without copying it with an explicit+-- length argument.+slice' :: forall i n m a p. (KnownNat i, KnownNat n, Prim a)+ => p i -- ^ starting index+ -> p n -- ^ length+ -> Vector (i+n+m) a+ -> Vector n a+slice' = V.slice'+{-# inline slice' #-}++-- | /O(1)/ Yield all but the last element of a non-empty vector without+-- copying.+init :: forall n a. (Prim a)+ => Vector (n+1) a -> Vector n a+init = V.init+{-# inline init #-}++-- | /O(1)/ Yield all but the first element of a non-empty vector without+-- copying.+tail :: forall n a. (Prim a)+ => Vector (1+n) a -> Vector n a+tail = V.tail+{-# inline tail #-}++-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains+-- this many elements. The length of the resulting vector is inferred from the+-- type.+take :: forall n m a. (KnownNat n, Prim a)+ => Vector (n+m) a -> Vector n a+take = V.take+{-# inline take #-}++-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains+-- this many elements. The length of the resulting vector is given explicitly+-- as a 'Proxy' argument.+take' :: forall n m a p. (KnownNat n, Prim a)+ => p n -> Vector (n+m) a -> Vector n a+take' = V.take'+{-# inline take' #-}++-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must+-- contain at least this many elements. The length of the resulting vector is+-- inferred from the type.+drop :: forall n m a. (KnownNat n, Prim a)+ => Vector (n+m) a -> Vector m a+drop = V.drop+{-# inline drop #-}++-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must+-- contain at least this many elements. The length of the resulting vector is+-- givel explicitly as a 'Proxy' argument.+drop' :: forall n m a p. (KnownNat n, Prim a)+ => p n -> Vector (n+m) a -> Vector m a+drop' = V.drop'+{-# inline drop' #-}++-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.+-- The lengths of the resulting vectors are inferred from the type.+splitAt :: forall n m a. (KnownNat n, Prim a)+ => Vector (n+m) a -> (Vector n a, Vector m a)+splitAt = V.splitAt+{-# inline splitAt #-}++-- | /O(1)/ Yield the first @n@ elements paired with the remainder without+-- copying. The length of the first resulting vector is passed explicitly as a+-- 'Proxy' argument.+splitAt' :: forall n m a p. (KnownNat n, Prim a)+ => p n -> Vector (n+m) a -> (Vector n a, Vector m a)+splitAt' = V.splitAt'+{-# inline splitAt' #-}++--------------------------------------------------------------------------------+-- * Construction+--------------------------------------------------------------------------------++--+-- ** Initialization+--++-- | /O(1)/ Empty vector.+empty :: forall a. (Prim a)+ => Vector 0 a+empty = V.empty+{-# inline empty #-}++-- | /O(1)/ Vector with exactly one element.+singleton :: forall a. (Prim a)+ => a -> Vector 1 a+singleton = V.singleton+{-# inline singleton #-}++-- | /O(n)/ Construct a vector in a type safe manner+-- @+-- fromTuple (1,2) :: Vector 2 Int+-- fromTuple ("hey", "what's", "going", "on") :: Vector 4 String+-- @+fromTuple :: forall a input length.+ (Prim a, IndexedListLiterals input length a, KnownNat length)+ => input -> Vector length a+fromTuple = V.fromTuple+{-# inline fromTuple #-}++-- | /O(n)/ Construct a vector with the same element in each position where the+-- length is inferred from the type.+replicate :: forall n a. (KnownNat n, Prim a)+ => a -> Vector n a+replicate = V.replicate+{-# inline replicate #-}++-- | /O(n)/ Construct a vector with the same element in each position where the+-- length is given explicitly as a 'Proxy' argument.+replicate' :: forall n a p. (KnownNat n, Prim a)+ => p n -> a -> Vector n a+replicate' = V.replicate'+{-# inline replicate' #-}++-- | /O(n)/ construct a vector of the given length by applying the function to+-- each index where the length is inferred from the type.+generate :: forall n a. (KnownNat n, Prim a)+ => (Finite n -> a) -> Vector n a+generate = V.generate+{-# inline generate #-}++-- | /O(n)/ construct a vector of the given length by applying the function to+-- each index where the length is given explicitly as a 'Proxy' argument.+generate' :: forall n a p. (KnownNat n, Prim a)+ => p n -> (Finite n -> a) -> Vector n a+generate' = V.generate'+{-# inline generate' #-}++-- | /O(n)/ Apply function @n@ times to value. Zeroth element is original value.+-- The length is inferred from the type.+iterateN :: forall n a. (KnownNat n, Prim a)+ => (a -> a) -> a -> Vector n a+iterateN = V.iterateN+{-# inline iterateN #-}++-- | /O(n)/ Apply function @n@ times to value. Zeroth element is original value.+-- The length is given explicitly as a 'Proxy' argument.+iterateN' :: forall n a p. (KnownNat n, Prim a)+ => p n -> (a -> a) -> a -> Vector n a+iterateN' = V.iterateN'+{-# inline iterateN' #-}++--+-- ** Monadic initialisation+--++-- | /O(n)/ Execute the monadic action @n@ times and store the results in a+-- vector where @n@ is inferred from the type.+replicateM :: forall n m a. (KnownNat n, Prim a, Monad m)+ => m a -> m (Vector n a)+replicateM = V.replicateM+{-# inline replicateM #-}++-- | /O(n)/ Execute the monadic action @n@ times and store the results in a+-- vector where @n@ is given explicitly as a 'Proxy' argument.+replicateM' :: forall n m a p. (KnownNat n, Prim a, Monad m)+ => p n -> m a -> m (Vector n a)+replicateM' = V.replicateM'+{-# inline replicateM' #-}++-- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to+-- each index where @n@ is inferred from the type.+generateM :: forall n m a. (KnownNat n, Prim a, Monad m)+ => (Finite n -> m a) -> m (Vector n a)+generateM = V.generateM+{-# inline generateM #-}++-- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to+-- each index where @n@ is given explicitly as a 'Proxy' argument.+generateM' :: forall n m a p. (KnownNat n, Prim a, Monad m)+ => p n -> (Finite n -> m a) -> m (Vector n a)+generateM' = V.generateM'+{-# inline generateM' #-}++--+-- ** Unfolding+--++-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying+-- the generator function to the a seed. The length is inferred from the+-- type.+unfoldrN :: forall n a b. (KnownNat n, Prim a)+ => (b -> (a, b)) -> b -> Vector n a+unfoldrN = V.unfoldrN+{-# inline unfoldrN #-}++-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying+-- the generator function to the a seed. The length is given explicitly+-- as a 'Proxy' argument.+unfoldrN' :: forall n a b p. (KnownNat n, Prim a)+ => p n -> (b -> (a, b)) -> b -> Vector n a+unfoldrN' = V.unfoldrN'+{-# inline unfoldrN' #-}++--+-- ** Enumeration+--++-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@, ...,+-- @x + (n - 1)@. The length is inferred from the type.+enumFromN :: forall n a. (KnownNat n, Prim a, Num a)+ => a -> Vector n a+enumFromN = V.enumFromN+{-# inline enumFromN #-}++-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@, ...,+-- @x + (n - 1)@. The length is given explicitly as a 'Proxy' argument.+enumFromN' :: forall n a p. (KnownNat n, Prim a, Num a)+ => a -> p n -> Vector n a+enumFromN' = V.enumFromN'+{-# inline enumFromN' #-}++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,+-- @x+2y@, ..., @x + (n - 1)y@. The length is inferred from the type.+enumFromStepN :: forall n a. (KnownNat n, Prim a, Num a)+ => a -> a -> Vector n a+enumFromStepN = V.enumFromStepN+{-# inline enumFromStepN #-}++-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,+-- @x+2y@, ..., @x + (n - 1)y@. The length is given explicitly as a 'Proxy' argument.+enumFromStepN' :: forall n a p. (KnownNat n, Prim a, Num a)+ => a -> a -> p n -> Vector n a+enumFromStepN' = V.enumFromStepN'+{-# inline enumFromStepN' #-}++--+-- ** Concatenation+--++-- | /O(n)/ Prepend an element.+cons :: forall n a. Prim a+ => a -> Vector n a -> Vector (1+n) a+cons = V.cons+{-# inline cons #-}++-- | /O(n)/ Append an element.+snoc :: forall n a. Prim a+ => Vector n a -> a -> Vector (n+1) a+snoc = V.snoc+{-# inline snoc #-}++-- | /O(m+n)/ Concatenate two vectors.+(++) :: forall n m a. Prim a+ => Vector n a -> Vector m a -> Vector (n+m) a+(++) = (V.++)+{-# inline (++) #-}++--+-- ** Restricting memory usage+--++-- | /O(n)/ Yield the argument but force it not to retain any extra memory,+-- possibly by copying it.+--+-- This is especially useful when dealing with slices. For example:+--+-- > force (slice 0 2 <huge vector>)+--+-- Here, the slice retains a reference to the huge vector. Forcing it creates+-- a copy of just the elements that belong to the slice and allows the huge+-- vector to be garbage collected.+force :: Prim a => Vector n a -> Vector n a+force = V.force+{-# inline force #-}+++--------------------------------------------------------------------------------+-- * Modifying vectors+--------------------------------------------------------------------------------++--+-- ** Bulk updates+--++-- | /O(m+n)/ For each pair @(i,a)@ from the list, replace the vector+-- element at position @i@ by @a@.+--+-- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7>+--+(//) :: (Prim a)+ => Vector m a -- ^ initial vector (of length @m@)+ -> [(Finite m, a)] -- ^ list of index/value pairs (of length @n@)+ -> Vector m a+(//) = (V.//)+{-# inline (//) #-}++-- | /O(m+n)/ For each index @i@ from the index vector and the+-- corresponding value @a@ from the value vector, replace the element of the+-- initial vector at position @i@ by @a@.+--+-- > update_ <5,9,2,7> <2,0,2> <1,3,8> = <3,9,8,7>+--+-- This function is useful for instances of 'Vector' that cannot store pairs.+-- Otherwise, 'update' is probably more convenient.+--+-- @+-- update_ xs is ys = 'update' xs ('zip' is ys)+-- @+update_ :: Prim a+ => Vector m a -- ^ initial vector (of length @m@)+ -> Vector n Int -- ^ index vector (of length @n@)+ -> Vector n a -- ^ value vector (of length @n@)+ -> Vector m a+update_ = V.update_+{-# inline update_ #-}++-- | Same as ('//') but without bounds checking.+unsafeUpd :: (Prim a)+ => Vector m a -- ^ initial vector (of length @m@)+ -> [(Int, a)] -- ^ list of index/value pairs (of length @n@)+ -> Vector m a+unsafeUpd = V.unsafeUpd+{-# inline unsafeUpd #-}++-- | Same as 'update_' but without bounds checking.+unsafeUpdate_ :: Prim a+ => Vector m a -- ^ initial vector (of length @m@)+ -> Vector n Int -- ^ index vector (of length @n@)+ -> Vector n a -- ^ value vector (of length @n@)+ -> Vector m a+unsafeUpdate_ = V.unsafeUpdate_+{-# inline unsafeUpdate_ #-}++--+-- ** Accumulations+--++-- | /O(m+n)/ For each pair @(i,b)@ from the list, replace the vector element+-- @a@ at position @i@ by @f a b@.+--+-- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4>+accum :: Prim a+ => (a -> b -> a) -- ^ accumulating function @f@+ -> Vector m a -- ^ initial vector (of length @m@)+ -> [(Finite m,b)] -- ^ list of index/value pairs (of length @n@)+ -> Vector m a+accum = V.accum+{-# inline accum #-}++-- | /O(m+n)/ For each index @i@ from the index vector and the+-- corresponding value @b@ from the the value vector,+-- replace the element of the initial vector at+-- position @i@ by @f a b@.+--+-- > accumulate_ (+) <5,9,2> <2,1,0,1> <4,6,3,7> = <5+3, 9+6+7, 2+4>+--+-- This function is useful for instances of 'Vector' that cannot store pairs.+-- Otherwise, 'accumulate' is probably more convenient:+--+-- @+-- accumulate_ f as is bs = 'accumulate' f as ('zip' is bs)+-- @+accumulate_ :: (Prim a, Prim b)+ => (a -> b -> a) -- ^ accumulating function @f@+ -> Vector m a -- ^ initial vector (of length @m@)+ -> Vector n Int -- ^ index vector (of length @n@)+ -> Vector n b -- ^ value vector (of length @n@)+ -> Vector m a+accumulate_ = V.accumulate_+{-# inline accumulate_ #-}++-- | Same as 'accum' but without bounds checking.+unsafeAccum :: Prim a+ => (a -> b -> a) -- ^ accumulating function @f@+ -> Vector m a -- ^ initial vector (of length @m@)+ -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)+ -> Vector m a+unsafeAccum = V.unsafeAccum+{-# inline unsafeAccum #-}++-- | Same as 'accumulate_' but without bounds checking.+unsafeAccumulate_ :: (Prim a, Prim b)+ => (a -> b -> a) -- ^ accumulating function @f@+ -> Vector m a -- ^ initial vector (of length @m@)+ -> Vector n Int -- ^ index vector (of length @n@)+ -> Vector n b -- ^ value vector (of length @n@)+ -> Vector m a+unsafeAccumulate_ = V.unsafeAccumulate_+{-# inline unsafeAccumulate_ #-}++--+-- ** Permutations+--++-- | /O(n)/ Reverse a vector.+reverse :: (Prim a) => Vector n a -> Vector n a+reverse = V.reverse+{-# inline reverse #-}++-- | /O(n)/ Yield the vector obtained by replacing each element @i@ of the+-- index vector by @xs'!'i@. This is equivalent to @'map' (xs'!') is@ but is+-- often much more efficient.+--+-- > backpermute <a,b,c,d> <0,3,2,3,1,0> = <a,d,c,d,b,a>+backpermute :: Prim a+ => Vector m a -- ^ @xs@ value vector+ -> Vector n Int -- ^ @is@ index vector (of length @n@)+ -> Vector n a+backpermute = V.backpermute+{-# inline backpermute #-}++-- | Same as 'backpermute' but without bounds checking.+unsafeBackpermute :: Prim a+ => Vector m a -- ^ @xs@ value vector+ -> Vector n Int -- ^ @is@ index vector (of length @n@)+ -> Vector n a+unsafeBackpermute = V.unsafeBackpermute+{-# inline unsafeBackpermute #-}++--------------------------------------------------------------------------------+-- * Elementwise Operations+--------------------------------------------------------------------------------++--+-- ** Mapping+--++-- | /O(n)/ Map a function over a vector.+map :: (Prim a, Prim b)+ => (a -> b) -> Vector n a -> Vector n b+map = V.map+{-# inline map #-}++-- | /O(n)/ Apply a function to every element of a vector and its index.+imap :: (Prim a, Prim b)+ => (Finite n -> a -> b) -> Vector n a -> Vector n b+imap = V.imap+{-# inline imap #-}++-- | /O(n*m)/ Map a function over a vector and concatenate the results. The+-- function is required to always return the same length vector.+concatMap :: (Prim a, Prim b)+ => (a -> Vector m b) -> Vector n a -> Vector (n*m) b+concatMap = V.concatMap+{-# inline concatMap #-}++--+-- ** Monadic mapping+--++-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a+-- vector of results.+mapM :: (Monad m, Prim a, Prim b)+ => (a -> m b) -> Vector n a -> m (Vector n b)+mapM = V.mapM+{-# inline mapM #-}++-- | /O(n)/ Apply the monadic action to every element of a vector and its+-- index, yielding a vector of results.+imapM :: (Monad m, Prim a, Prim b)+ => (Finite n -> a -> m b) -> Vector n a -> m (Vector n b)+imapM = V.imapM+{-# inline 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 n a -> m ()+mapM_ = V.mapM_+{-# inline mapM_ #-}++-- | /O(n)/ Apply the monadic action to every element of a vector and its+-- index, ignoring the results.+imapM_ :: (Monad m, Prim a) => (Finite n -> a -> m b) -> Vector n a -> m ()+imapM_ = V.imapM_+{-# inline imapM_ #-}++-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a+-- vector of results. Equvalent to @flip 'mapM'@.+forM :: (Monad m, Prim a, Prim b)+ => Vector n a -> (a -> m b) -> m (Vector n b)+forM = V.forM+{-# inline forM #-}++-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the+-- results. Equivalent to @flip 'mapM_'@.+forM_ :: (Monad m, Prim a) => Vector n a -> (a -> m b) -> m ()+forM_ = V.forM_+{-# inline forM_ #-}++--+-- ** Zipping+--++-- | /O(n)/ Zip two vectors of the same length with the given function.+zipWith :: (Prim a, Prim b, Prim c)+ => (a -> b -> c) -> Vector n a -> Vector n b -> Vector n c+zipWith = V.zipWith+{-# inline zipWith #-}++-- | Zip three vectors with the given function.+zipWith3 :: (Prim a, Prim b, Prim c, Prim d)+ => (a -> b -> c -> d) -> Vector n a -> Vector n b -> Vector n c -> Vector n d+zipWith3 = V.zipWith3+{-# inline zipWith3 #-}++zipWith4 :: (Prim a,Prim b,Prim c,Prim d,Prim e)+ => (a -> b -> c -> d -> e)+ -> Vector n a+ -> Vector n b+ -> Vector n c+ -> Vector n d+ -> Vector n e+zipWith4 = V.zipWith4+{-# inline zipWith4 #-}++zipWith5 :: (Prim a,Prim b,Prim c,Prim d,Prim e,Prim f)+ => (a -> b -> c -> d -> e -> f)+ -> Vector n a+ -> Vector n b+ -> Vector n c+ -> Vector n d+ -> Vector n e+ -> Vector n f+zipWith5 = V.zipWith5+{-# inline zipWith5 #-}++zipWith6 :: (Prim a,Prim b,Prim c,Prim d,Prim e,Prim f,Prim g)+ => (a -> b -> c -> d -> e -> f -> g)+ -> Vector n a+ -> Vector n b+ -> Vector n c+ -> Vector n d+ -> Vector n e+ -> Vector n f+ -> Vector n g+zipWith6 = V.zipWith6+{-# inline zipWith6 #-}++-- | /O(n)/ Zip two vectors of the same length with a function that also takes+-- the elements' indices).+izipWith :: (Prim a,Prim b,Prim c)+ => (Finite n -> a -> b -> c)+ -> Vector n a+ -> Vector n b+ -> Vector n c+izipWith = V.izipWith+{-# inline izipWith #-}++izipWith3 :: (Prim a,Prim b,Prim c,Prim d)+ => (Finite n -> a -> b -> c -> d)+ -> Vector n a+ -> Vector n b+ -> Vector n c+ -> Vector n d+izipWith3 = V.izipWith3+{-# inline izipWith3 #-}++izipWith4 :: (Prim a,Prim b,Prim c,Prim d,Prim e)+ => (Finite n -> a -> b -> c -> d -> e)+ -> Vector n a+ -> Vector n b+ -> Vector n c+ -> Vector n d+ -> Vector n e+izipWith4 = V.izipWith4+{-# inline izipWith4 #-}++izipWith5 :: (Prim a,Prim b,Prim c,Prim d,Prim e,Prim f)+ => (Finite n -> a -> b -> c -> d -> e -> f)+ -> Vector n a+ -> Vector n b+ -> Vector n c+ -> Vector n d+ -> Vector n e+ -> Vector n f+izipWith5 = V.izipWith5+{-# inline izipWith5 #-}++izipWith6 :: (Prim a,Prim b,Prim c,Prim d,Prim e,Prim f,Prim g)+ => (Finite n -> a -> b -> c -> d -> e -> f -> g)+ -> Vector n a+ -> Vector n b+ -> Vector n c+ -> Vector n d+ -> Vector n e+ -> Vector n f+ -> Vector n g+izipWith6 = V.izipWith6+{-# inline izipWith6 #-}++--+-- ** Monadic zipping+--++-- | /O(n)/ Zip the two vectors of the same length with the monadic action and+-- yield a vector of results.+zipWithM :: (Monad m, Prim a, Prim b, Prim c)+ => (a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)+zipWithM = V.zipWithM+{-# inline zipWithM #-}++-- | /O(n)/ Zip the two vectors with a monadic action that also takes the+-- element index and yield a vector of results.+izipWithM :: (Monad m, Prim a, Prim b, Prim c)+ => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)+izipWithM = V.izipWithM+{-# inline izipWithM #-}++-- | /O(n)/ Zip the two vectors with the monadic action and ignore the results.+zipWithM_ :: (Monad m, Prim a, Prim b)+ => (a -> b -> m c) -> Vector n a -> Vector n b -> m ()+zipWithM_ = V.zipWithM_+{-# inline zipWithM_ #-}++-- | /O(n)/ Zip the two vectors with a monadic action that also takes+-- the element index and ignore the results.+izipWithM_ :: (Monad m, Prim a, Prim b)+ => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m ()+izipWithM_ = V.izipWithM_+{-# inline izipWithM_ #-}++--------------------------------------------------------------------------------+-- * Working with predicates+--------------------------------------------------------------------------------++--+-- ** Searching+--+++infix 4 `elem`+-- | /O(n)/ Check if the vector contains an element.+elem :: (Prim a, Eq a) => a -> Vector n a -> Bool+elem = V.elem+{-# inline elem #-}++infix 4 `notElem`+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem').+notElem :: (Prim a, Eq a) => a -> Vector n a -> Bool+notElem = V.notElem+{-# inline notElem #-}++-- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing'+-- if no such element exists.+find :: Prim a => (a -> Bool) -> Vector n a -> Maybe a+find = V.find+{-# inline find #-}++-- | /O(n)/ Yield 'Just' the index of the first element matching the predicate+-- or 'Nothing' if no such element exists.+findIndex :: Prim a => (a -> Bool) -> Vector n a -> Maybe (Finite n)+findIndex = V.findIndex+{-# inline findIndex #-}++-- | /O(n)/ Yield 'Just' the index of the first occurence of the given element or+-- 'Nothing' if the vector does not contain the element. This is a specialised+-- version of 'findIndex'.+elemIndex :: (Prim a, Eq a) => a -> Vector n a -> Maybe (Finite n)+elemIndex = V.elemIndex+{-# inline elemIndex #-}++--------------------------------------------------------------------------------+-- * Folding+--------------------------------------------------------------------------------++-- | /O(n)/ Left fold.+foldl :: Prim b => (a -> b -> a) -> a -> Vector n b -> a+foldl = V.foldl+{-# inline foldl #-}++-- | /O(n)/ Left fold on non-empty vectors.+foldl1 :: Prim a => (a -> a -> a) -> Vector (1+n) a -> a+foldl1 = V.foldl1+{-# inline foldl1 #-}++-- | /O(n)/ Left fold with strict accumulator.+foldl' :: Prim b => (a -> b -> a) -> a -> Vector n b -> a+foldl' = V.foldl'+{-# inline foldl' #-}++-- | /O(n)/ Left fold on non-empty vectors with strict accumulator.+foldl1' :: Prim a => (a -> a -> a) -> Vector (1+n) a -> a+foldl1' = V.foldl1'+{-# inline foldl1' #-}++-- | /O(n)/ Right fold.+foldr :: Prim a => (a -> b -> b) -> b -> Vector n a -> b+foldr = V.foldr+{-# inline foldr #-}++-- | /O(n)/ Right fold on non-empty vectors.+foldr1 :: Prim a => (a -> a -> a) -> Vector (n+1) a -> a+foldr1 = V.foldr1+{-# inline foldr1 #-}++-- | /O(n)/ Right fold with a strict accumulator.+foldr' :: Prim a => (a -> b -> b) -> b -> Vector n a -> b+foldr' = V.foldr'+{-# inline foldr' #-}++-- | /O(n)/ Right fold on non-empty vectors with strict accumulator.+foldr1' :: Prim a => (a -> a -> a) -> Vector (n+1) a -> a+foldr1' = V.foldr1'+{-# inline foldr1' #-}++-- | /O(n)/ Left fold (function applied to each element and its index).+ifoldl :: Prim b => (a -> Finite n -> b -> a) -> a -> Vector n b -> a+ifoldl = V.ifoldl+{-# inline ifoldl #-}++-- | /O(n)/ Left fold with strict accumulator (function applied to each element+-- and its index).+ifoldl' :: Prim b => (a -> Finite n -> b -> a) -> a -> Vector n b -> a+ifoldl' = V.ifoldl'+{-# inline ifoldl' #-}++-- | /O(n)/ Right fold (function applied to each element and its index).+ifoldr :: Prim a => (Finite n -> a -> b -> b) -> b -> Vector n a -> b+ifoldr = V.ifoldr+{-# inline ifoldr #-}++-- | /O(n)/ Right fold with strict accumulator (function applied to each+-- element and its index).+ifoldr' :: Prim a => (Finite n -> a -> b -> b) -> b -> Vector n a -> b+ifoldr' = V.ifoldr'+{-# inline ifoldr' #-}++-- ** Specialised folds++-- | /O(n)/ Check if all elements satisfy the predicate.+all :: Prim a => (a -> Bool) -> Vector n a -> Bool+all = V.all+{-# inline all #-}++-- | /O(n)/ Check if any element satisfies the predicate.+any :: Prim a => (a -> Bool) -> Vector n a -> Bool+any = V.any+{-# inline any #-}++-- | /O(n)/ Compute the sum of the elements.+sum :: (Prim a, Num a) => Vector n a -> a+sum = V.sum+{-# inline sum #-}++-- | /O(n)/ Compute the product of the elements.+product :: (Prim a, Num a) => Vector n a -> a+product = V.product+{-# inline product #-}++-- | /O(n)/ Yield the maximum element of the non-empty vector.+maximum :: (Prim a, Ord a) => Vector (n+1) a -> a+maximum = V.maximum+{-# inline maximum #-}++-- | /O(n)/ Yield the maximum element of the non-empty vector according to the+-- given comparison function.+maximumBy :: Prim a+ => (a -> a -> Ordering) -> Vector (n+1) a -> a+maximumBy = V.maximumBy+{-# inline maximumBy #-}++-- | /O(n)/ Yield the minimum element of the non-empty vector.+minimum :: (Prim a, Ord a) => Vector (n+1) a -> a+minimum = V.minimum+{-# inline minimum #-}++-- | /O(n)/ Yield the minimum element of the non-empty vector according to the+-- given comparison function.+minimumBy :: Prim a+ => (a -> a -> Ordering) -> Vector (n+1) a -> a+minimumBy = V.minimumBy+{-# inline minimumBy #-}++-- | /O(n)/ Yield the index of the maximum element of the non-empty vector.+maxIndex :: (Prim a, Ord a) => Vector (n+1) a -> Finite (n + 1)+maxIndex = V.maxIndex+{-# inline maxIndex #-}++-- | /O(n)/ Yield the index of the maximum element of the non-empty vector+-- according to the given comparison function.+maxIndexBy :: Prim a+ => (a -> a -> Ordering) -> Vector (n+1) a -> Finite (n + 1)+maxIndexBy = V.maxIndexBy+{-# inline maxIndexBy #-}++-- | /O(n)/ Yield the index of the minimum element of the non-empty vector.+minIndex :: (Prim a, Ord a) => Vector (n+1) a -> Finite (n + 1)+minIndex = V.minIndex+{-# inline minIndex #-}++-- | /O(n)/ Yield the index of the minimum element of the non-empty vector+-- according to the given comparison function.+minIndexBy :: Prim a+ => (a -> a -> Ordering) -> Vector (n+1) a -> Finite (n + 1)+minIndexBy = V.minIndexBy+{-# inline minIndexBy #-}++-- ** Monadic folds++-- | /O(n)/ Monadic fold.+foldM :: (Monad m, Prim b) => (a -> b -> m a) -> a -> Vector n b -> m a+foldM = V.foldM+{-# inline foldM #-}++-- | /O(n)/ Monadic fold (action applied to each element and its index).+ifoldM :: (Monad m, Prim b) => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a+ifoldM = V.ifoldM+{-# inline ifoldM #-}++-- | /O(n)/ Monadic fold over non-empty vectors.+fold1M :: (Monad m, Prim a)+ => (a -> a -> m a) -> Vector (1+n) a -> m a+fold1M = V.fold1M+{-# inline fold1M #-}++-- | /O(n)/ Monadic fold with strict accumulator.+foldM' :: (Monad m, Prim b) => (a -> b -> m a) -> a -> Vector n b -> m a+foldM' = V.foldM'+{-# inline foldM' #-}++-- | /O(n)/ Monadic fold with strict accumulator (action applied to each+-- element and its index).+ifoldM' :: (Monad m, Prim b)+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a+ifoldM' = V.ifoldM'+{-# inline ifoldM' #-}++-- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator.+fold1M' :: (Monad m, Prim a)+ => (a -> a -> m a) -> Vector (n+1) a -> m a+fold1M' = V.fold1M'+{-# inline fold1M' #-}++-- | /O(n)/ Monadic fold that discards the result.+foldM_ :: (Monad m, Prim b)+ => (a -> b -> m a) -> a -> Vector n b -> m ()+foldM_ = V.foldM_+{-# inline foldM_ #-}++-- | /O(n)/ Monadic fold that discards the result (action applied to+-- each element and its index).+ifoldM_ :: (Monad m, Prim b)+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()+ifoldM_ = V.ifoldM_+{-# inline ifoldM_ #-}++-- | /O(n)/ Monadic fold over non-empty vectors that discards the result.+fold1M_ :: (Monad m, Prim a)+ => (a -> a -> m a) -> Vector (n+1) a -> m ()+fold1M_ = V.fold1M_+{-# inline fold1M_ #-}++-- | /O(n)/ Monadic fold with strict accumulator that discards the result.+foldM'_ :: (Monad m, Prim b)+ => (a -> b -> m a) -> a -> Vector n b -> m ()+foldM'_ = V.foldM'_+{-# inline foldM'_ #-}++-- | /O(n)/ Monadic fold with strict accumulator that discards the result+-- (action applied to each element and its index).+ifoldM'_ :: (Monad m, Prim b)+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()+ifoldM'_ = V.ifoldM'_+{-# inline ifoldM'_ #-}++-- | /O(n)/ Monad fold over non-empty vectors with strict accumulator+-- that discards the result.+fold1M'_ :: (Monad m, Prim a)+ => (a -> a -> m a) -> Vector (n+1) a -> m ()+fold1M'_ = V.fold1M'_+{-# inline fold1M'_ #-}++--------------------------------------------------------------------------------+-- * Prefix sums (scans)+--------------------------------------------------------------------------------++-- | /O(n)/ Prescan.+--+-- @+-- prescanl f z = 'init' . 'scanl' f z+-- @+--+-- Example: @prescanl (+) 0 \<1,2,3,4\> = \<0,1,3,6\>@+--+prescanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector n a+prescanl = V.prescanl+{-# inline prescanl #-}++-- | /O(n)/ Prescan with strict accumulator.+prescanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector n a+prescanl' = V.prescanl'+{-# inline prescanl' #-}++-- | /O(n)/ Scan.+postscanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector n a+postscanl = V.postscanl+{-# inline postscanl #-}++-- | /O(n)/ Scan with strict accumulator.+postscanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector n a+postscanl' = V.postscanl'+{-# inline postscanl' #-}++-- | /O(n)/ Haskell-style scan.+scanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector (1+n) a+scanl = V.scanl+{-# inline scanl #-}++-- | /O(n)/ Haskell-style scan with strict accumulator.+scanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector (1+n) a+scanl' = V.scanl'+{-# inline scanl' #-}++-- | /O(n)/ Scan over a non-empty vector.+scanl1 :: Prim a => (a -> a -> a) -> Vector (1+n) a -> Vector (2+n) a+scanl1 = V.scanl1+{-# inline scanl1 #-}++-- | /O(n)/ Scan over a non-empty vector with a strict accumulator.+scanl1' :: Prim a => (a -> a -> a) -> Vector (1+n) a -> Vector (2+n) a+scanl1' = V.scanl1'+{-# inline scanl1' #-}++-- | /O(n)/ Right-to-left prescan.+prescanr :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector n b+prescanr = V.prescanr+{-# inline prescanr #-}++-- | /O(n)/ Right-to-left prescan with strict accumulator.+prescanr' :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector n b+prescanr' = V.prescanr'+{-# inline prescanr' #-}++-- | /O(n)/ Right-to-left scan.+postscanr :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector n b+postscanr = V.postscanr+{-# inline postscanr #-}++-- | /O(n)/ Right-to-left scan with strict accumulator.+postscanr' :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector n b+postscanr' = V.postscanr'+{-# inline postscanr' #-}++-- | /O(n)/ Right-to-left Haskell-style scan.+scanr :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector (n+1) b+scanr = V.scanr+{-# inline scanr #-}++-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator.+scanr' :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector (n+1) b+scanr' = V.scanr'+{-# inline scanr' #-}++-- | /O(n)/ Right-to-left scan over a non-empty vector.+scanr1 :: Prim a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+2) a+scanr1 = V.scanr1+{-# inline scanr1 #-}++-- | /O(n)/ Right-to-left scan over a non-empty vector with a strict+-- accumulator.+scanr1' :: Prim a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+2) a+scanr1' = V.scanr1'+{-# inline scanr1' #-}+++-- * Conversions++-- ** Lists++-- | /O(n)/ Convert a vector to a list.+toList :: Prim a => Vector n a -> [a]+toList = V.toList+{-# inline toList #-}++-- | /O(n)/ Convert a list to a vector.+fromList :: (Prim a, KnownNat n) => [a] -> Maybe (Vector n a)+fromList = V.fromList+{-# inline fromList #-}++-- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of+-- the resulting vector is inferred from the type.+fromListN :: forall n a. (Prim a, KnownNat n)+ => [a] -> Maybe (Vector n a)+fromListN = V.fromListN+{-# inline fromListN #-}++-- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of+-- the resulting vector is given explicitly as a 'Proxy' argument.+fromListN' :: forall n a p. (Prim a, KnownNat n)+ => p n -> [a] -> Maybe (Vector n a)+fromListN' = V.fromListN'+{-# inline fromListN' #-}++-- | /O(n)/ Takes a list and returns a continuation providing a vector with+-- a size parameter corresponding to the length of the list.+--+-- Essentially converts a list into a vector with the proper size+-- parameter, determined at runtime.+--+-- See 'withSized'+withSizedList :: forall a r. Prim a+ => [a] -> (forall n. KnownNat n => Vector n a -> r) -> r+withSizedList xs = withSized (VS.fromList xs)+{-# inline withSizedList #-}++-- ** Mutable vectors++-- | /O(n)/ Yield an immutable copy of the mutable vector.+freeze :: (PrimMonad m, Prim a)+ => VSM.MVector n (PrimState m) a+ -> m (Vector n a)+freeze = V.freeze++-- | /O(1)/ Unsafely convert a mutable vector to an immutable one withouy+-- copying. The mutable vector may not be used after this operation.+unsafeFreeze :: (PrimMonad m, Prim a)+ => VSM.MVector n (PrimState m) a+ -> m (Vector n a)+unsafeFreeze = V.unsafeFreeze++-- | /O(n)/ Yield a mutable copy of the immutable vector.+thaw :: (PrimMonad m, Prim a)+ => Vector n a+ -> m (VSM.MVector n (PrimState m) a)+thaw = V.thaw++-- | /O(n)/ Unsafely convert an immutable vector to a mutable one without+-- copying. The immutable vector may not be used after this operation.+unsafeThaw :: (PrimMonad m, Prim a)+ => Vector n a+ -> m (VSM.MVector n (PrimState m) a)+unsafeThaw = V.unsafeThaw++-- | /O(n)/ Copy an immutable vector into a mutable one.+copy :: (PrimMonad m, Prim a)+ => VSM.MVector n (PrimState m) a+ -> Vector n a+ -> m ()+copy = V.copy++-- ** Unsized vectors++-- | Convert a 'Data.Vector.Generic.Vector' into a+-- 'Data.Vector.Generic.Sized.Vector' if it has the correct size, otherwise+-- return 'Nothing'.+toSized :: forall n a. (Prim a, KnownNat n)+ => VS.Vector a -> Maybe (Vector n a)+toSized = V.toSized+{-# inline toSized #-}++-- | Takes a 'Data.Vector.Primitive.Vector' and returns a continuation+-- providing a 'Data.Vector.Primitive.Sized.Vector' with a size parameter+-- @n@ that is determined at runtime based on the length of the input+-- vector.+--+-- Essentially converts a 'Data.Vector.Primitive.Vector' into+-- a 'Data.Vector.Primitive.Sized.Vector' with the correct size parameter+-- @n@.+withSized :: forall a r. Prim a+ => VS.Vector a -> (forall n. KnownNat n => Vector n a -> r) -> r+withSized = V.withSized+{-# inline withSized #-}++fromSized :: Vector n a -> VS.Vector a+fromSized = V.fromSized+{-# inline fromSized #-}++-- | Apply a function on unsized vectors to a sized vector. The function must+-- preserve the size of the vector, this is not checked.+withVectorUnsafe :: forall a b (n :: Nat). ()+ => (VS.Vector a -> VS.Vector b) -> Vector n a -> Vector n b+withVectorUnsafe = V.withVectorUnsafe+{-# inline withVectorUnsafe #-}++-- | Pattern synonym that lets you treat an unsized vector as if it+-- "contained" a sized vector. If you pattern match on an unsized vector,+-- its contents will be the /sized/ vector counterpart.+--+-- @+-- testFunc :: Unsized.Vector Int -> Int+-- testFunc ('SomeSized' v) =+-- 'sum' ('zipWith' (+) v ('replicate' 1))+-- -- ^ here, v is `Sized.Vector n Int`, and we have+-- `'KnownNat' n`+-- @+--+-- The @n@ type variable will be properly instantiated to whatever the+-- length of the vector is, and you will also have a @'KnownNat' n@+-- instance available. You can get @n@ in scope by turning on+-- ScopedTypeVariables and matching on @'SomeSized' (v :: Sized.Vector+-- n Int)@.+--+-- Without this, you would otherwise have to use 'withSized' to do the same+-- thing:+--+-- @+-- testFunc :: Unsized.Vector Int -> Int+-- testFunc u = 'withSized' u $ \\v ->+-- 'sum' ('zipWith' (+) v ('replicate' 1))+-- @+--+-- Remember that the type of final result of your function (the @Int@,+-- here) must /not/ depend on @n@. However, the types of the intermediate+-- values are allowed to depend on @n@.+--+-- This is /especially/ useful in do blocks, where you can pattern match on+-- the unsized results of actions, to use the sized vector in the rest of+-- the do block. You also get a @'KnownNat' n@ constraint for the+-- remainder of the do block.+--+-- @+-- -- If you had:+-- getAVector :: IO (Unsized.Vector Int)+--+-- main :: IO ()+-- main = do+-- SomeSized v <- getAVector -- v is `Sized.Vector n Int`+-- -- get n in scope+-- SomeSized (v :: Sized.Vector n Int) <- getAVector+-- print v+-- @+--+-- Remember that the final type of the result of the do block ('()', here)+-- must not depend on @n@. However, the+--+-- Also useful in ghci, where you can pattern match to get sized vectors+-- from unsized vectors.+--+-- @+-- ghci> SomeSized v <- pure (myUnsizedVector :: Unsized.Vector Int)+-- -- ^ v is `Sized.Vector n Int`+-- @+--+-- This enables interactive exploration with sized vectors in ghci, and is+-- useful for using with other libraries and functions that expect sized+-- vectors in an interactive setting.+--+-- (Note that as of GHC 8.6, you cannot get the @n@ in scope in your ghci+-- session using ScopedTypeVariables, like you can with do blocks)+--+-- You can also use this as a constructor, to take a sized vector and+-- "hide" the size, to produce an unsized vector:+--+-- @+-- SomeSized :: Sized.Vector n a -> Unsized.Vector a+-- @+pattern SomeSized :: Prim a => KnownNat n => Vector n a -> VS.Vector a+pattern SomeSized v = V.SomeSized v+{-# complete SomeSized #-}
src/Data/Vector/Sized.hs view
@@ -5,11 +5,10 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE CPP #-}--#if MIN_VERSION_base(4,12,0)+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE NoStarIsType #-}-#endif {-| This module re-exports the functionality in 'Data.Vector.Generic.Sized'@@ -60,6 +59,8 @@ , empty , singleton , fromTuple+ , BuildVector(..)+ , pattern Build , replicate , replicate' , generate@@ -106,6 +107,7 @@ , unsafeBackpermute -- * Lenses , ix+ , ix' , _head , _last -- * Elementwise operations@@ -235,9 +237,11 @@ , withSized , fromSized , withVectorUnsafe+ , zipVectorsUnsafe ) where import qualified Data.Vector.Generic.Sized as V+import Data.Vector.Generic.Sized ( BuildVector(..) ) import qualified Data.Vector as VU import qualified Data.Vector.Mutable.Sized as VM import GHC.TypeLits@@ -245,16 +249,15 @@ import Data.Proxy import Data.IndexedListLiterals hiding (toList, fromList) import Control.Monad.Primitive-import Prelude hiding ( length, null,+import Prelude hiding ( Foldable(..), replicate, (++), concat, head, last, init, tail, take, drop, splitAt, reverse, map, concat, concatMap, zipWith, zipWith3, zip, zip3, unzip, unzip3, filter, takeWhile, dropWhile, span, break,- elem, notElem,- foldl, foldl1, foldr, foldr1,- all, any, and, or, sum, product, maximum, minimum,+ notElem,+ all, any, and, or, scanl, scanl1, scanr, scanr1, enumFromTo, enumFromThenTo, mapM, mapM_, sequence, sequence_,@@ -330,6 +333,14 @@ ix = V.ix {-# inline ix #-} +-- | Type-safe lens to access (/O(1)/) and update (/O(n)/) an arbitrary element by its index+-- which should be supplied via TypeApplications.+ix' :: forall i n a f. (Functor f,+ KnownNat i, KnownNat n, i+1 <= n)+ => (a -> f a) -> Vector n a -> f (Vector n a)+ix' = V.ix' @i+{-# inline ix' #-}+ -- | Lens to access (/O(1)/) and update (/O(n)/) the first element of a non-empty vector. _head :: forall n a f. Functor f => (a -> f a) -> Vector (1+n) a -> f (Vector (1+n) a)@@ -473,16 +484,29 @@ singleton = V.singleton {-# inline singleton #-} --- | /O(n)/ Construct a vector in a type safe manner.+-- | /O(n)/ Construct a vector in a type safe manner using a tuple. -- @ -- fromTuple (1,2) :: Vector 2 Int -- fromTuple ("hey", "what's", "going", "on") :: Vector 4 String -- @+--+-- @since 1.6.0 fromTuple :: forall input length ty. (IndexedListLiterals input length ty, KnownNat length) => input -> Vector length ty fromTuple = V.fromTuple +-- | /O(n)/ Construct a vector in a type-safe manner using a sized linked list.+-- @+-- Build (1 :< 2 :< 3 :< Nil) :: Vector 3 Int+-- Build ("not" :< "much" :< Nil) :: Vector 2 String+-- @+-- Can also be used as a pattern.+--+-- @since 1.6.0+pattern Build :: V.BuildVector n a -> Vector n a+pattern Build build = V.Build build+ -- | /O(n)/ Construct a vector with the same element in each position where the -- length is inferred from the type. replicate :: forall n a. KnownNat n@@ -728,7 +752,7 @@ -- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4> accum :: (a -> b -> a) -- ^ accumulating function @f@ -> Vector m a -- ^ initial vector (of length @m@)- -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)+ -> [(Finite m,b)] -- ^ list of index/value pairs (of length @n@) -> Vector m a accum = V.accum {-# inline accum #-}@@ -1364,22 +1388,22 @@ {-# inline postscanl' #-} -- | /O(n)/ Haskell-style scan.-scanl :: (a -> b -> a) -> a -> Vector n b -> Vector n a+scanl :: (a -> b -> a) -> a -> Vector n b -> Vector (1+n) a scanl = V.scanl {-# inline scanl #-} -- | /O(n)/ Haskell-style scan with strict accumulator.-scanl' :: (a -> b -> a) -> a -> Vector n b -> Vector n a+scanl' :: (a -> b -> a) -> a -> Vector n b -> Vector (1+n) a scanl' = V.scanl' {-# inline scanl' #-} -- | /O(n)/ Scan over a non-empty vector.-scanl1 :: (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanl1 :: (a -> a -> a) -> Vector (1+n) a -> Vector (2+n) a scanl1 = V.scanl1 {-# inline scanl1 #-} -- | /O(n)/ Scan over a non-empty vector with a strict accumulator.-scanl1' :: (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanl1' :: (a -> a -> a) -> Vector (1+n) a -> Vector (2+n) a scanl1' = V.scanl1' {-# inline scanl1' #-} @@ -1404,23 +1428,23 @@ {-# inline postscanr' #-} -- | /O(n)/ Right-to-left Haskell-style scan.-scanr :: (a -> b -> b) -> b -> Vector n a -> Vector n b+scanr :: (a -> b -> b) -> b -> Vector n a -> Vector (n+1) b scanr = V.scanr {-# inline scanr #-} -- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator.-scanr' :: (a -> b -> b) -> b -> Vector n a -> Vector n b+scanr' :: (a -> b -> b) -> b -> Vector n a -> Vector (n+1) b scanr' = V.scanr' {-# inline scanr' #-} -- | /O(n)/ Right-to-left scan over a non-empty vector.-scanr1 :: (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanr1 :: (a -> a -> a) -> Vector (n+1) a -> Vector (n+2) a scanr1 = V.scanr1 {-# inline scanr1 #-} -- | /O(n)/ Right-to-left scan over a non-empty vector with a strict -- accumulator.-scanr1' :: (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanr1' :: (a -> a -> a) -> Vector (n+1) a -> Vector (n+2) a scanr1' = V.scanr1' {-# inline scanr1' #-} @@ -1530,6 +1554,12 @@ withVectorUnsafe = V.withVectorUnsafe {-# inline withVectorUnsafe #-} +-- | Apply a function on two unsized vectors to sized vectors. The function must+-- preserve the size of the vectors, this is not checked.+zipVectorsUnsafe :: (VU.Vector a -> VU.Vector b -> VU.Vector c) -> Vector n a -> Vector n b -> Vector n c+zipVectorsUnsafe = V.zipVectorsUnsafe+{-# inline zipVectorsUnsafe #-}+ -- | Pattern synonym that lets you treat an unsized vector as if it -- "contained" a sized vector. If you pattern match on an unsized vector, -- its contents will be the /sized/ vector counterpart.@@ -1579,7 +1609,7 @@ -- @ -- -- Remember that the final type of the result of the do block ('()', here)--- must not depend on @n@. However, the +-- must not depend on @n@. However, the -- -- Also useful in ghci, where you can pattern match to get sized vectors -- from unsized vectors.
src/Data/Vector/Storable/Mutable/Sized.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-}@@ -64,10 +63,8 @@ , unsafeModify , unsafeSwap , unsafeExchange-#if MIN_VERSION_vector(0,12,0) -- * Modifying vectors , nextPermutation-#endif -- ** Filling and copying , set , copy@@ -379,7 +376,6 @@ unsafeExchange = VGM.unsafeExchange {-# inline unsafeExchange #-} -#if MIN_VERSION_vector(0,12,0) -- * Modifying vectors -- | Compute the next permutation (lexicographically) of a given vector@@ -388,7 +384,6 @@ => MVector n (PrimState m) e -> m Bool nextPermutation = VGM.nextPermutation {-# inline nextPermutation #-}-#endif -- ** Filling and copying
src/Data/Vector/Storable/Sized.hs view
@@ -6,11 +6,10 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE CPP #-}--#if MIN_VERSION_base(4,12,0)+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE NoStarIsType #-}-#endif {-| This module re-exports the functionality in 'Data.Vector.Generic.Sized'@@ -61,6 +60,7 @@ , empty , singleton , fromTuple+ , pattern Build , replicate , replicate' , generate@@ -107,6 +107,7 @@ , unsafeBackpermute -- * Lenses , ix+ , ix' , _head , _last -- * Elementwise operations@@ -236,6 +237,7 @@ , withSized , fromSized , withVectorUnsafe+ , zipVectorsUnsafe ) where import qualified Data.Vector.Generic.Sized as V@@ -247,16 +249,15 @@ import Data.Proxy import Control.Monad.Primitive import Foreign.Storable-import Prelude hiding ( length, null,+import Prelude hiding ( Foldable(..), replicate, (++), concat, head, last, init, tail, take, drop, splitAt, reverse, map, concat, concatMap, zipWith, zipWith3, zip, zip3, unzip, unzip3, filter, takeWhile, dropWhile, span, break,- elem, notElem,- foldl, foldl1, foldr, foldr1,- all, any, and, or, sum, product, maximum, minimum,+ notElem,+ all, any, and, or, scanl, scanl1, scanr, scanr1, enumFromTo, enumFromThenTo, mapM, mapM_, sequence, sequence_,@@ -334,6 +335,14 @@ ix = V.ix {-# inline ix #-} +-- | Type-safe lens to access (/O(1)/) and update (/O(n)/) an arbitrary element by its index+-- which should be supplied via TypeApplications.+ix' :: forall i n a f. (Storable a, Functor f,+ KnownNat i, KnownNat n, i+1 <= n)+ => (a -> f a) -> Vector n a -> f (Vector n a)+ix' = V.ix' @i+{-# inline ix' #-}+ -- | Lens to access (/O(1)/) and update (/O(n)/) the first element of a non-empty vector. _head :: forall n a f. (Storable a, Functor f) => (a -> f a) -> Vector (1+n) a -> f (Vector (1+n) a)@@ -482,17 +491,30 @@ singleton = V.singleton {-# inline singleton #-} --- | /O(n)/ Construct a vector in a type safe manner+-- | /O(n)/ Construct a vector in a type safe manner using a tuple. -- @ -- fromTuple (1,2) :: Vector 2 Int -- fromTuple ("hey", "what's", "going", "on") :: Vector 4 String -- @+--+-- @since 1.6.0 fromTuple :: forall a input length. (Storable a, IndexedListLiterals input length a, KnownNat length) => input -> Vector length a fromTuple = V.fromTuple {-# inline fromTuple #-} +-- | /O(n)/ Construct a vector in a type-safe manner using a sized linked list.+-- @+-- Build (1 :< 2 :< 3 :< Nil) :: Vector 3 Int+-- Build ("not" :< "much" :< Nil) :: Vector 2 String+-- @+-- Can also be used as a pattern.+--+-- @since 1.6.0+pattern Build :: Storable a => V.BuildVector n a -> Vector n a+pattern Build vec = V.Build vec+ -- | /O(n)/ Construct a vector with the same element in each position where the -- length is inferred from the type. replicate :: forall n a. (KnownNat n, Storable a)@@ -748,7 +770,7 @@ accum :: Storable a => (a -> b -> a) -- ^ accumulating function @f@ -> Vector m a -- ^ initial vector (of length @m@)- -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)+ -> [(Finite m,b)] -- ^ list of index/value pairs (of length @n@) -> Vector m a accum = V.accum {-# inline accum #-}@@ -1435,22 +1457,22 @@ {-# inline postscanl' #-} -- | /O(n)/ Haskell-style scan.-scanl :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector n b -> Vector n a+scanl :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector n b -> Vector (1+n) a scanl = V.scanl {-# inline scanl #-} -- | /O(n)/ Haskell-style scan with strict accumulator.-scanl' :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector n b -> Vector n a+scanl' :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector n b -> Vector (1+n) a scanl' = V.scanl' {-# inline scanl' #-} -- | /O(n)/ Scan over a non-empty vector.-scanl1 :: Storable a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanl1 :: Storable a => (a -> a -> a) -> Vector (1+n) a -> Vector (2+n) a scanl1 = V.scanl1 {-# inline scanl1 #-} -- | /O(n)/ Scan over a non-empty vector with a strict accumulator.-scanl1' :: Storable a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanl1' :: Storable a => (a -> a -> a) -> Vector (1+n) a -> Vector (2+n) a scanl1' = V.scanl1' {-# inline scanl1' #-} @@ -1475,23 +1497,23 @@ {-# inline postscanr' #-} -- | /O(n)/ Right-to-left Haskell-style scan.-scanr :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector n a -> Vector n b+scanr :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector n a -> Vector (n+1) b scanr = V.scanr {-# inline scanr #-} -- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator.-scanr' :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector n a -> Vector n b+scanr' :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector n a -> Vector (n+1) b scanr' = V.scanr' {-# inline scanr' #-} -- | /O(n)/ Right-to-left scan over a non-empty vector.-scanr1 :: Storable a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanr1 :: Storable a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+2) a scanr1 = V.scanr1 {-# inline scanr1 #-} -- | /O(n)/ Right-to-left scan over a non-empty vector with a strict -- accumulator.-scanr1' :: Storable a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanr1' :: Storable a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+2) a scanr1' = V.scanr1' {-# inline scanr1' #-} @@ -1605,6 +1627,12 @@ withVectorUnsafe = V.withVectorUnsafe {-# inline withVectorUnsafe #-} +-- | Apply a function on two unsized vectors to sized vectors. The function must+-- preserve the size of the vectors, this is not checked.+zipVectorsUnsafe :: (VS.Vector a -> VS.Vector b -> VS.Vector c) -> Vector n a -> Vector n b -> Vector n c+zipVectorsUnsafe = V.zipVectorsUnsafe+{-# inline zipVectorsUnsafe #-}+ -- | Pattern synonym that lets you treat an unsized vector as if it -- "contained" a sized vector. If you pattern match on an unsized vector, -- its contents will be the /sized/ vector counterpart.@@ -1654,7 +1682,7 @@ -- @ -- -- Remember that the final type of the result of the do block ('()', here)--- must not depend on @n@. However, the +-- must not depend on @n@. However, the -- -- Also useful in ghci, where you can pattern match to get sized vectors -- from unsized vectors.
src/Data/Vector/Unboxed/Mutable/Sized.hs view
@@ -1,8 +1,12 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} {-| This module re-exports the functionality in 'Data.Vector.Generic.Mutable.Sized'@@ -64,10 +68,8 @@ , unsafeModify , unsafeSwap , unsafeExchange-#if MIN_VERSION_vector(0,12,0) -- * Modifying vectors , nextPermutation-#endif -- ** Filling and copying , set , copy@@ -82,8 +84,13 @@ , Unbox ) where +import Data.Vector.Generic.Sized.Internal (Vector(..))+import qualified Data.Vector.Generic as V+import qualified Data.Vector.Generic.Mutable as VM+import qualified Data.Vector.Generic.Sized as VG import qualified Data.Vector.Generic.Mutable.Sized as VGM-import qualified Data.Vector.Unboxed.Mutable as VSM+import qualified Data.Vector.Unboxed as VU+import qualified Data.Vector.Unboxed.Mutable as VUM import Data.Vector.Unboxed (Unbox) import GHC.TypeLits import Data.Finite@@ -95,7 +102,7 @@ -- | 'Data.Vector.Generic.Mutable.Sized.Vector' specialized to use -- 'Data.Vector.Unbox.Mutable'.-type MVector = VGM.MVector VSM.MVector+type MVector = VGM.MVector VUM.MVector -- * Accessors @@ -381,7 +388,6 @@ unsafeExchange = VGM.unsafeExchange {-# inline unsafeExchange #-} -#if MIN_VERSION_vector(0,12,0) -- * Modifying vectors -- | Compute the next permutation (lexicographically) of a given vector@@ -390,7 +396,6 @@ => MVector n (PrimState m) e -> m Bool nextPermutation = VGM.nextPermutation {-# inline nextPermutation #-}-#endif -- ** Filling and copying @@ -439,7 +444,7 @@ -- to it are also reflected in the given -- 'Data.Vector.Unbox.Mutable.MVector'. toSized :: forall n a s. (KnownNat n, Unbox a)- => VSM.MVector s a -> Maybe (MVector n s a)+ => VUM.MVector s a -> Maybe (MVector n s a) toSized = VGM.toSized {-# inline toSized #-} @@ -457,7 +462,7 @@ -- to it are also reflected in the given -- 'Data.Vector.Unbox.Mutable.MVector'. withSized :: forall s a r. Unbox a- => VSM.MVector s a -> (forall n. KnownNat n => MVector n s a -> r) -> r+ => VUM.MVector s a -> (forall n. KnownNat n => MVector n s a -> r) -> r withSized = VGM.withSized {-# inline withSized #-} @@ -468,8 +473,78 @@ -- 'Data.Vector.Unbox.Mutable.MVector' is a reference to the exact same -- vector in memory as the given one, and any modifications to it are also -- reflected in the given 'MVector'.-fromSized :: MVector n s a -> VSM.MVector s a+fromSized :: MVector n s a -> VUM.MVector s a fromSized = VGM.fromSized {-# inline fromSized #-} +-- | This instance allows to define sized matrices and tensors+-- backed by continuous memory segments, which reduces memory allocations+-- and relaxes pressure on garbage collector.+instance (Unbox a, KnownNat n) => Unbox (VG.Vector VU.Vector n a)++newtype instance VUM.MVector s (VG.Vector VU.Vector n a) = MV_Sized (VUM.MVector s a)+newtype instance VU.Vector (VG.Vector VU.Vector n a) = V_Sized (VU.Vector a)++instance (Unbox a, KnownNat n) => VM.MVector VUM.MVector (VG.Vector VU.Vector n a) where+ basicLength vs@(MV_Sized v) = VM.basicLength v `quot` intLenM vs+ {-# inline basicLength #-}++ basicUnsafeSlice i n vs@(MV_Sized v) = MV_Sized (VM.basicUnsafeSlice (i * intLenM vs) (n * intLenM vs) v)+ {-# inline basicUnsafeSlice #-}++ basicOverlaps (MV_Sized v1) (MV_Sized v2) = VM.basicOverlaps v1 v2+ {-# inline basicOverlaps #-}++ basicUnsafeNew n = MV_Sized <$> VM.basicUnsafeNew (n * fromIntegral (natVal (Proxy :: Proxy n)))+ {-# inline basicUnsafeNew #-}++ basicInitialize (MV_Sized v) = VM.basicInitialize v+ {-# inline basicInitialize #-}++ basicClear (MV_Sized v) = VM.basicClear v+ {-# inline basicClear #-}++ basicUnsafeCopy (MV_Sized v1) (MV_Sized v2) = VM.basicUnsafeCopy v1 v2+ {-# inline basicUnsafeCopy #-}++ basicUnsafeMove (MV_Sized v1) (MV_Sized v2) = VM.basicUnsafeMove v1 v2+ {-# inline basicUnsafeMove #-}++ basicUnsafeGrow vs@(MV_Sized v) n = MV_Sized <$> VM.basicUnsafeGrow v (n * intLenM vs)+ {-# inline basicUnsafeGrow #-}++ basicUnsafeRead vs@(MV_Sized v) i = Vector <$> V.freeze (VM.basicUnsafeSlice (i * intLenM vs) (intLenM vs) v)+ {-# inline basicUnsafeRead #-}++ basicUnsafeWrite vs@(MV_Sized v) i (Vector x) = V.basicUnsafeCopy (VM.basicUnsafeSlice (i * intLenM vs) (intLenM vs) v) x+ {-# inline basicUnsafeWrite #-}+++intLenM :: forall s n a. KnownNat n => VUM.MVector s (VG.Vector VU.Vector n a) -> Int+intLenM _ = fromIntegral (natVal (Proxy :: Proxy n))++instance (Unbox a, KnownNat n) => V.Vector VU.Vector (VG.Vector VU.Vector n a) where+ basicUnsafeFreeze (MV_Sized v) = V_Sized <$> V.basicUnsafeFreeze v+ {-# inline basicUnsafeFreeze #-}++ basicUnsafeThaw (V_Sized v) = MV_Sized <$> V.basicUnsafeThaw v+ {-# inline basicUnsafeThaw #-}++ basicLength vs@(V_Sized v) = V.basicLength v `quot` intLen vs+ {-# inline basicLength #-}++ basicUnsafeSlice i n vs@(V_Sized v) = V_Sized (V.basicUnsafeSlice (i * intLen vs) (n * intLen vs) v)+ {-# inline basicUnsafeSlice #-}++ basicUnsafeCopy (MV_Sized mv) (V_Sized v) = V.basicUnsafeCopy mv v+ {-# inline basicUnsafeCopy #-}++ elemseq _ = seq+ {-# inline elemseq #-}++ basicUnsafeIndexM vs@(V_Sized v) i = pure $! Vector (V.basicUnsafeSlice (i * intLen vs) (intLen vs) v)+ {-# inline basicUnsafeIndexM #-}++intLen :: forall n a. KnownNat n => VU.Vector (VG.Vector VU.Vector n a) -> Int+intLen _ = fromIntegral (natVal (Proxy :: Proxy n))
src/Data/Vector/Unboxed/Sized.hs view
@@ -5,12 +5,11 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-}-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE CPP #-}--#if MIN_VERSION_base(4,12,0)+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE NoStarIsType #-}-#endif {-| This module re-exports the functionality in 'Data.Vector.Generic.Sized'@@ -61,6 +60,7 @@ , empty , singleton , fromTuple+ , pattern Build , replicate , replicate' , generate@@ -107,6 +107,7 @@ , unsafeBackpermute -- * Lenses , ix+ , ix' , _head , _last -- * Elementwise operations@@ -236,6 +237,7 @@ , withSized , fromSized , withVectorUnsafe+ , zipVectorsUnsafe -- ** Unbox , Unbox ) where@@ -249,16 +251,15 @@ import Data.Proxy import Control.Monad.Primitive import Data.Vector.Unboxed (Unbox)-import Prelude hiding ( length, null,+import Prelude hiding ( Foldable(..), replicate, (++), concat, head, last, init, tail, take, drop, splitAt, reverse, map, concat, concatMap, zipWith, zipWith3, zip, zip3, unzip, unzip3, filter, takeWhile, dropWhile, span, break,- elem, notElem,- foldl, foldl1, foldr, foldr1,- all, any, and, or, sum, product, maximum, minimum,+ notElem,+ all, any, and, or, scanl, scanl1, scanr, scanr1, enumFromTo, enumFromThenTo, mapM, mapM_, sequence, sequence_,@@ -336,6 +337,14 @@ ix = V.ix {-# inline ix #-} +-- | Type-safe lens to access (/O(1)/) and update (/O(n)/) an arbitrary element by its index+-- which should be supplied via TypeApplications.+ix' :: forall i n a f. (Unbox a, Functor f,+ KnownNat i, KnownNat n, i+1 <= n)+ => (a -> f a) -> Vector n a -> f (Vector n a)+ix' = V.ix' @i+{-# inline ix' #-}+ -- | Lens to access (/O(1)/) and update (/O(n)/) the first element of a non-empty vector. _head :: forall n a f. (Unbox a, Functor f) => (a -> f a) -> Vector (1+n) a -> f (Vector (1+n) a)@@ -483,17 +492,30 @@ singleton = V.singleton {-# inline singleton #-} --- | /O(n)/ Construct a vector in a type safe manner+-- | /O(n)/ Construct a vector in a type safe manner using a tuple. -- @ -- fromTuple (1,2) :: Vector 2 Int -- fromTuple ("hey", "what's", "going", "on") :: Vector 4 String -- @+--+-- @since 1.6.0 fromTuple :: forall a input length. (Unbox a, IndexedListLiterals input length a, KnownNat length) => input -> Vector length a fromTuple = V.fromTuple {-# inline fromTuple #-} +-- | /O(n)/ Construct a vector in a type-safe manner using a sized linked list.+-- @+-- Build (1 :< 2 :< 3 :< Nil) :: Vector 3 Int+-- Build ("not" :< "much" :< Nil) :: Vector 2 String+-- @+-- Can also be used as a pattern.+--+-- @since 1.6.0+pattern Build :: Unbox a => V.BuildVector n a -> Vector n a+pattern Build vec = V.Build vec+ -- | /O(n)/ Construct a vector with the same element in each position where the -- length is inferred from the type. replicate :: forall n a. (KnownNat n, Unbox a)@@ -749,7 +771,7 @@ accum :: Unbox a => (a -> b -> a) -- ^ accumulating function @f@ -> Vector m a -- ^ initial vector (of length @m@)- -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)+ -> [(Finite m,b)] -- ^ list of index/value pairs (of length @n@) -> Vector m a accum = V.accum {-# inline accum #-}@@ -1433,22 +1455,22 @@ {-# inline postscanl' #-} -- | /O(n)/ Haskell-style scan.-scanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a+scanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector (1+n) a scanl = V.scanl {-# inline scanl #-} -- | /O(n)/ Haskell-style scan with strict accumulator.-scanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a+scanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector (1+n) a scanl' = V.scanl' {-# inline scanl' #-} -- | /O(n)/ Scan over a non-empty vector.-scanl1 :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanl1 :: Unbox a => (a -> a -> a) -> Vector (1+n) a -> Vector (2+n) a scanl1 = V.scanl1 {-# inline scanl1 #-} -- | /O(n)/ Scan over a non-empty vector with a strict accumulator.-scanl1' :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanl1' :: Unbox a => (a -> a -> a) -> Vector (1+n) a -> Vector (2+n) a scanl1' = V.scanl1' {-# inline scanl1' #-} @@ -1473,23 +1495,23 @@ {-# inline postscanr' #-} -- | /O(n)/ Right-to-left Haskell-style scan.-scanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b+scanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector (n+1) b scanr = V.scanr {-# inline scanr #-} -- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator.-scanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b+scanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector (n+1) b scanr' = V.scanr' {-# inline scanr' #-} -- | /O(n)/ Right-to-left scan over a non-empty vector.-scanr1 :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanr1 :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+2) a scanr1 = V.scanr1 {-# inline scanr1 #-} -- | /O(n)/ Right-to-left scan over a non-empty vector with a strict -- accumulator.-scanr1' :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a+scanr1' :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+2) a scanr1' = V.scanr1' {-# inline scanr1' #-} @@ -1603,6 +1625,12 @@ withVectorUnsafe = V.withVectorUnsafe {-# inline withVectorUnsafe #-} +-- | Apply a function on two unsized vectors to sized vectors. The function must+-- preserve the size of the vectors, this is not checked.+zipVectorsUnsafe :: (VU.Vector a -> VU.Vector b -> VU.Vector c) -> Vector n a -> Vector n b -> Vector n c+zipVectorsUnsafe = V.zipVectorsUnsafe+{-# inline zipVectorsUnsafe #-}+ -- | Pattern synonym that lets you treat an unsized vector as if it -- "contained" a sized vector. If you pattern match on an unsized vector, -- its contents will be the /sized/ vector counterpart.@@ -1652,7 +1680,7 @@ -- @ -- -- Remember that the final type of the result of the do block ('()', here)--- must not depend on @n@. However, the +-- must not depend on @n@. However, the -- -- Also useful in ghci, where you can pattern match to get sized vectors -- from unsized vectors.
vector-sized.cabal view
@@ -1,29 +1,22 @@--- This file has been generated from package.yaml by hpack version 0.27.0.------ see: https://github.com/sol/hpack------ hash: 9e10d73204f28676f1b2ea3f9f268f3bc030536ef316caacf208ba554a7d0e14-+cabal-version: 3.0 name: vector-sized-version: 1.2.0.1+version: 1.6.1 synopsis: Size tagged vectors description: Please see README.md category: Data homepage: https://github.com/expipiplus1/vector-sized#readme bug-reports: https://github.com/expipiplus1/vector-sized/issues-author: Joe Hermaszewski+author: Ellie Hermaszewska maintainer: whats.our.vector.victor@monoid.al-copyright: 2016 Joe Hermaszewski-license: BSD3+copyright: 2016 Ellie Hermaszewska+license: BSD-3-Clause license-file: LICENSE build-type: Simple-cabal-version: >= 1.10-+tested-with: GHC ==8.10.7 || ==9.0.1 || ==9.2.1 extra-source-files:+ readme.md changelog.md default.nix- readme.md- shell.nix source-repository head type: git@@ -31,29 +24,31 @@ library exposed-modules:- Data.Vector.Sized+ Data.Vector.Generic.Mutable.Sized+ Data.Vector.Generic.Mutable.Sized.Internal Data.Vector.Generic.Sized Data.Vector.Generic.Sized.Internal- Data.Vector.Storable.Sized Data.Vector.Mutable.Sized- Data.Vector.Generic.Mutable.Sized+ Data.Vector.Primitive.Mutable.Sized+ Data.Vector.Primitive.Sized+ Data.Vector.Sized Data.Vector.Storable.Mutable.Sized- Data.Vector.Generic.Mutable.Sized.Internal- Data.Vector.Unboxed.Sized+ Data.Vector.Storable.Sized Data.Vector.Unboxed.Mutable.Sized- other-modules:- Paths_vector_sized+ Data.Vector.Unboxed.Sized hs-source-dirs: src build-depends: adjunctions >=4.3 && <4.5- , base >=4.9 && <5+ , base >=4.14 && <5+ , binary >=0.8.3.0 , comonad >=4 && <6- , deepseq >=1.1 && <1.5+ , deepseq >=1.1 && <1.6 , distributive >=0.5 && <0.7 , finite-typelits >=0.1- , hashable >=1.2.4.0 && <1.3+ , hashable >=1.2.4.0 , indexed-list-literals >=0.2.0.0- , primitive >=0.5 && <0.8- , vector >=0.11 && <0.13+ , primitive >=0.5 && <0.10+ , indexed-traversable >=0.1.2 && <0.2+ , vector >=0.12 && <0.14 default-language: Haskell2010