vector-sized 1.4.2 → 1.4.3
raw patch · 8 files changed
+2089/−52 lines, 8 files
Files
- changelog.md +7/−0
- default.nix +10/−34
- package.yaml +32/−0
- shell.nix +0/−6
- src/Data/Vector/Generic/Sized.hs +46/−2
- src/Data/Vector/Primitive/Mutable/Sized.hs +471/−0
- src/Data/Vector/Primitive/Sized.hs +1513/−0
- vector-sized.cabal +10/−10
changelog.md view
@@ -2,6 +2,13 @@ ## WIP +## [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)`
default.nix view
@@ -1,36 +1,12 @@-{ pkgs ? import <nixpkgs> {}-, compiler ? "ghc8102"-, hoogle ? true-}:--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: {- } // pkgs.lib.optionalAttrs hoogle {- ghc = super.ghc // { withPackages = super.ghc.withHoogle; };- ghcWithPackages = self.ghc.withPackages;- };- };-- # 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;- } // pkgs.lib.optionalAttrs hoogle {- shellHook = attrs.shellHook + ''- export HIE_HOOGLE_DATABASE="$(cat $(which hoogle) | sed -n -e 's|.*--database \(.*\.hoo\).*|\1|p')"- '';- });+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 [ ] ./.;+}
+ package.yaml view
@@ -0,0 +1,32 @@+name: vector-sized+version: 1.4.3+synopsis: Size tagged vectors+description: Please see README.md+category: Data+author: Joe Hermaszewski+maintainer: whats.our.vector.victor@monoid.al+copyright: 2016 Joe Hermaszewski+license: BSD3+github: expipiplus1/vector-sized++extra-source-files:+- package.yaml+- readme.md+- changelog.md+- default.nix++dependencies:+- base >=4.9 && <5+- vector >=0.11 && <0.13+- deepseq >=1.1 && <1.5+- finite-typelits >=0.1+- primitive >=0.5 && <0.8+- indexed-list-literals >=0.2.0.0+- adjunctions >=4.3 && <4.5+- distributive >=0.5 && <0.7+- comonad >=4 && <6+- hashable >=1.2.4.0+- binary >=0.8.3.0++library:+ source-dirs: src
− shell.nix
@@ -1,6 +0,0 @@-{ pkgs ? import <nixpkgs> {}-, compiler ? "ghc882"-, hoogle ? true-}:--(import ./default.nix { inherit pkgs compiler hoogle; }).env
src/Data/Vector/Generic/Sized.hs view
@@ -253,13 +253,16 @@ import qualified Data.Vector.Generic.Mutable.Sized as SVGM import Data.Vector.Generic.Mutable.Sized.Internal import Data.Binary-import GHC.TypeLits+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 Control.Monad (mzero) import Control.Monad.Primitive+import Control.Monad.ST import Foreign.Storable import Data.Data import Control.Comonad@@ -268,6 +271,7 @@ 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@@ -1938,3 +1942,43 @@ 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))+ shiftL = coerce (shiftL @(v a))+ unsafeShiftL = coerce (unsafeShiftL @(v a))+ shiftR = coerce (shiftR @(v a))+ unsafeShiftR = coerce (unsafeShiftR @(v a))+ shift = coerce (shift @(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++-- | 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))+
+ src/Data/Vector/Primitive/Mutable/Sized.hs view
@@ -0,0 +1,471 @@+{-# LANGUAGE CPP #-}+{-# 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+#if MIN_VERSION_vector(0,12,0)+ -- * Modifying vectors+ , nextPermutation+#endif+ -- ** 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 #-}++#if MIN_VERSION_vector(0,12,0)+-- * 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 #-}+#endif++-- ** 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,1513 @@+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE CPP #-}++#if MIN_VERSION_base(4,12,0)+{-# LANGUAGE NoStarIsType #-}+#endif++{-|+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 ( length, null,+ 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,+ 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@)+ -> [(Int,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 #-}
vector-sized.cabal view
@@ -1,13 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.33.0.+-- This file has been generated from package.yaml by hpack version 0.34.2. -- -- see: https://github.com/sol/hpack------ hash: ee1654a35ad22a0b6764be7fe44e3e0c7b29dbf714956529471c549c06bfa011 name: vector-sized-version: 1.4.2+version: 1.4.3 synopsis: Size tagged vectors description: Please see README.md category: Data@@ -20,10 +18,10 @@ license-file: LICENSE build-type: Simple extra-source-files:+ package.yaml readme.md changelog.md default.nix- shell.nix source-repository head type: git@@ -31,16 +29,18 @@ 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+ Data.Vector.Unboxed.Sized other-modules: Paths_vector_sized hs-source-dirs: