vector-sized 0.6.1.0 → 1.0.0.0
raw patch · 11 files changed
+1979/−262 lines, 11 filesdep +indexed-list-literalsdep +primitivedep ~base
Dependencies added: indexed-list-literals, primitive
Dependency ranges changed: base
Files
- changelog.md +13/−0
- readme.md +12/−5
- src/Data/Vector/Generic/Mutable/Sized.hs +484/−0
- src/Data/Vector/Generic/Mutable/Sized/Internal.hs +22/−0
- src/Data/Vector/Generic/Sized.hs +219/−136
- src/Data/Vector/Generic/Sized/Internal.hs +27/−0
- src/Data/Vector/Mutable/Sized.hs +474/−0
- src/Data/Vector/Sized.hs +119/−60
- src/Data/Vector/Storable/Mutable/Sized.hs +475/−0
- src/Data/Vector/Storable/Sized.hs +122/−60
- vector-sized.cabal +12/−1
changelog.md view
@@ -1,11 +1,24 @@ # Change Log +## [1.0.0.0] - 2018-03-20++- More functions using `Finite` instead of `Int`+- Add `Read` and `Semigroup` instances+- Performance improvements for `Applicative`+- Add a `knownLength` function+- Add `fromTuple` (ghc < 8.3 for now)+- Add sized variants of mutable vectors +- Expose sized vector constructors from Internal modules++Huge thanks to all the contributors!+ ## [0.6.1.0] - 2017-08-04 - Add lenses ix, _head and _last ## [0.6.0.0] - 2017-06-07 - Make ordering of additions in types be more consistent - Make slice more general+- `Num`, `Fractional`, and `Floating` instances for vectors ## [0.5.1.0] - 2017-02-01 - Loosen upper bound on `vector`
readme.md view
@@ -3,12 +3,19 @@ This package exports a newtype tagging the vectors from the [vector](https://hackage.haskell.org/package/vector) package with a type level natural representing their size.- It also exports a few functions from vector appropriately retyped. -This package is fairly similar to the-[fixed-vector](https://hackage.haskell.org/package/fixed-vector) package. The-difference is that fixed-vector uses Peano naturals to represent the size tag-on the vectors and this package uses typelits.+This package is fairly similar to+the [fixed-vector](https://hackage.haskell.org/package/fixed-vector) package.+While both provide vectors of statically know length they use completely+different implementation with different tradeoffs. `vector-sized` is a newtype+wrapper over `vector` thus it's able to handle vectors of arbitrary length but+have to carry runtime representation of length which is significant memory+overhead for small vectors. `fixed-vector` defines all functions as+manipulations of Church-encoded product types (`∀r. (a→a→r) → r` for 2D vectors)+so it can work for both arbitrary product types like `data V2 a = V2 a a` and+opaque length-parametrized vectors provided by library. As consequence of+implementation it can't handle vectors larger than tens of elements.+ The initial code for this package was written by @bgamari in a [PR for vulkan](https://github.com/expipiplus1/vulkan/pull/1)
+ src/Data/Vector/Generic/Mutable/Sized.hs view
@@ -0,0 +1,484 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE RankNTypes #-}++{-|+This module reexports the functionality in 'Data.Vector.Generic.Mutable'+which maps well to explicity sized vectors.++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 resultant vector size is not know until compile time+are not exported.+-}++module Data.Vector.Generic.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 as VGM+import Data.Vector.Generic.Mutable.Sized.Internal+import GHC.TypeLits+import Data.Finite+import Data.Proxy+import Control.Monad.Primitive+import Prelude hiding ( length, null, replicate, init,+ tail, take, drop, splitAt, read )++-- * Accessors++-- ** Length information++-- | /O(1)/ Yield the length of the mutable vector as an 'Int'.+length :: forall v n s a. (KnownNat n)+ => MVector v n s a -> Int+length _ = fromInteger (natVal (Proxy :: Proxy n))+{-# inline length #-}++-- | /O(1)/ Yield the length of the mutable vector as a 'Proxy'.+length' :: forall v n s a. (KnownNat n)+ => MVector v n s a -> Proxy n+length' _ = Proxy+{-# inline length' #-}++-- | /O(1)/ Check whether the mutable vector is empty+null :: forall v n s a. (KnownNat n)+ => MVector v n s a -> Bool+null = (== 0) . length+{-# inline null #-}++-- ** Extracting subvectors++-- | /O(1)/ Yield a slice of the mutable vector without copying it with an+-- inferred length argument.+slice :: forall v i n k s a p. (KnownNat i, KnownNat n, KnownNat k, VGM.MVector v a)+ => p i -- ^ starting index+ -> MVector v (i+n+k) s a+ -> MVector v n s a+slice start (MVector v) = MVector (VGM.unsafeSlice i n v)+ where i = fromInteger (natVal start)+ n = fromInteger (natVal (Proxy :: Proxy n))+{-# inline slice #-}++-- | /O(1)/ Yield a slice of the mutable vector without copying it with an+-- explicit length argument.+slice' :: forall v i n k s a p+ . (KnownNat i, KnownNat n, KnownNat k, VGM.MVector v a)+ => p i -- ^ starting index+ -> p n -- ^ length+ -> MVector v (i+n+k) s a+ -> MVector v n s a+slice' start _ = slice start+{-# inline slice' #-}++-- | /O(1)/ Yield all but the last element of a non-empty mutable vector+-- without copying.+init :: forall v n s a. (VGM.MVector v a)+ => MVector v (n+1) s a -> MVector v n s a+init (MVector v) = MVector (VGM.unsafeInit v)+{-# inline init #-}++-- | /O(1)/ Yield all but the first element of a non-empty mutable vector+-- without copying.+tail :: forall v n s a. (VGM.MVector v a)+ => MVector v (1+n) s a -> MVector v n s a+tail (MVector v) = MVector (VGM.unsafeTail v)+{-# inline tail #-}++-- | /O(1)/ Yield the first n elements. The resultant vector always contains+-- this many elements. The length of the resultant vector is inferred from the+-- type.+take :: forall v n k s a. (KnownNat n, KnownNat k, VGM.MVector v a)+ => MVector v (n+k) s a -> MVector v n s a+take (MVector v) = MVector (VGM.unsafeTake i v)+ where i = fromInteger (natVal (Proxy :: Proxy n))+{-# inline take #-}++-- | /O(1)/ Yield the first n elements. The resultant vector always contains+-- this many elements. The length of the resultant vector is given explicitly+-- as a 'Proxy' argument.+take' :: forall v n k s a p. (KnownNat n, KnownNat k, VGM.MVector v a)+ => p n -> MVector v (n+k) s a -> MVector v n s a+take' _ = 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 resultant vector is+-- inferred from the type.+drop :: forall v n k s a. (KnownNat n, KnownNat k, VGM.MVector v a)+ => MVector v (n+k) s a -> MVector v k s a+drop (MVector v) = MVector (VGM.unsafeDrop i v)+ where i = fromInteger (natVal (Proxy :: Proxy n))+{-# 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 resultant vector is+-- givel explicitly as a 'Proxy' argument.+drop' :: forall v n k s a p. (KnownNat n, KnownNat k, VGM.MVector v a)+ => p n -> MVector v (n+k) s a -> MVector v k s a+drop' _ = drop+{-# inline drop' #-}++-- | /O(1)/ Yield the first n elements paired with the remainder without copying.+-- The lengths of the resultant vector are inferred from the type.+splitAt :: forall v n m s a. (KnownNat n, KnownNat m, VGM.MVector v a)+ => MVector v (n+m) s a -> (MVector v n s a, MVector v m s a)+splitAt (MVector v) = (MVector a, MVector b)+ where i = fromInteger (natVal (Proxy :: Proxy n))+ (a, b) = VGM.splitAt i v+{-# inline splitAt #-}++-- | /O(1)/ Yield the first n elements paired with the remainder without+-- copying. The length of the first resultant vector is passed explicitly as a+-- 'Proxy' argument.+splitAt' :: forall v n m s a p. (KnownNat n, KnownNat m, VGM.MVector v a)+ => p n -> MVector v (n+m) s a -> (MVector v n s a, MVector v m s a)+splitAt' _ = splitAt+{-# inline splitAt' #-}++-- ** Overlaps++-- | /O(1)/ Yield all but the the first n elements. The given vector must+-- contain at least this many elements The length of the resultant vector is+-- inferred from the type.+overlaps :: forall v n k s a. (KnownNat n, KnownNat k, VGM.MVector v a)+ => MVector v n s a+ -> MVector v k s a+ -> Bool+overlaps (MVector v) (MVector u) = VGM.overlaps v u+{-# inline overlaps #-}++-- * Construction++-- ** Initialisation++-- | Create a mutable vector where the length is inferred from the type.+new :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => m (MVector v n (PrimState m) a)+new = MVector <$> VGM.new (fromIntegral (natVal (Proxy :: Proxy n)))+{-# inline new #-}++-- | Create a mutable vector where the length is inferred from the type.+-- The memory is not initialized.+unsafeNew :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => m (MVector v n (PrimState m) a)+unsafeNew = MVector <$> VGM.new (fromIntegral (natVal (Proxy :: Proxy n)))+{-# inline unsafeNew #-}++-- | Create a mutable vector where the length is inferred from the type and+-- fill it with an initial value.+replicate :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => a -> m (MVector v n (PrimState m) a)+replicate = fmap MVector . VGM.replicate (fromIntegral (natVal (Proxy :: Proxy n)))+{-# 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 v n m a p. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => p n -> a -> m (MVector v n (PrimState m) a)+replicate' _ = 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 v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => m a -> m (MVector v n (PrimState m) a)+replicateM = fmap MVector . VGM.replicateM (fromIntegral (natVal (Proxy :: Proxy n)))+{-# 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 v n m a p. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => p n -> m a -> m (MVector v n (PrimState m) a)+replicateM' _ = replicateM+{-# inline replicateM' #-}++-- | Create a copy of a mutable vector.+clone :: forall v n m a. (PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -> m (MVector v n (PrimState m) a)+clone (MVector v) = MVector <$> VGM.clone v+{-# inline clone #-}++-- ** Growing++-- | Grow a mutable vector by an amount given explicitly as a 'Proxy'+-- argument.+grow :: forall v n k m a p. (KnownNat k, PrimMonad m, VGM.MVector v a)+ => p k -> MVector v n (PrimState m) a -> m (MVector v (n + k) (PrimState m) a)+grow _ (MVector v) = MVector <$> VGM.unsafeGrow v (fromIntegral (natVal (Proxy :: Proxy k)))+{-# inline grow #-}++-- | Grow a mutable vector (from the front) by an amount given explicitly+-- as a 'Proxy' argument.+growFront :: forall v n k m a p. (KnownNat k, PrimMonad m, VGM.MVector v a)+ => p k -> MVector v n (PrimState m) a -> m (MVector v (n + k) (PrimState m) a)+growFront _ (MVector v) = MVector <$>+ VGM.unsafeGrowFront v (fromIntegral (natVal (Proxy :: Proxy k)))+{-# inline growFront #-}++-- ** Restricting memory usage++-- | Reset all elements of the vector to some undefined value, clearing all+-- references to external objects.+clear :: (PrimMonad m, VGM.MVector v a) => MVector v n (PrimState m) a -> m ()+clear (MVector v) = VGM.clear v+{-# inline clear #-}++-- * Accessing individual elements++-- | /O(1)/ Yield the element at a given type-safe position using 'Finite'.+read :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -> Finite n -> m a+read (MVector v) i = v `VGM.unsafeRead` fromIntegral i+{-# inline read #-}++-- | /O(1)/ Yield the element at a given type-safe position using 'Proxy'.+read' :: forall v n k a m p. (KnownNat n, KnownNat k, PrimMonad m, VGM.MVector v a)+ => MVector v (n+k+1) (PrimState m) a -> p k -> m a+read' (MVector v) p = v `VGM.unsafeRead` fromInteger (natVal p)+{-# inline read' #-}++-- | /O(1)/ Yield the element at a given 'Int' position without bounds+-- checking.+unsafeRead :: forall v n a m. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -> Int -> m a+unsafeRead (MVector v) i = v `VGM.unsafeRead` i+{-# inline unsafeRead #-}++-- | /O(1)/ Replace the element at a given type-safe position using 'Finite'.+write :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -> Finite n -> a -> m ()+write (MVector v) i = VGM.unsafeWrite v (fromIntegral i)+{-# inline write #-}++-- | /O(1)/ Replace the element at a given type-safe position using 'Proxy'.+write' :: forall v n k a m p. (KnownNat n, KnownNat k, PrimMonad m, VGM.MVector v a)+ => MVector v (n+k+1) (PrimState m) a -> p k -> a -> m ()+write' (MVector v) p = VGM.unsafeWrite v (fromInteger (natVal p))+{-# inline write' #-}++-- | /O(1)/ Replace the element at a given 'Int' position without bounds+-- checking.+unsafeWrite :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -> Int -> a -> m ()+unsafeWrite (MVector v) = VGM.unsafeWrite v+{-# inline unsafeWrite #-}++-- | /O(1)/ Modify the element at a given type-safe position using 'Finite'.+modify :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -> (a -> a) -> Finite n -> m ()+modify (MVector v) f i = VGM.unsafeModify v f (fromIntegral i)+{-# inline modify #-}++-- | /O(1)/ Modify the element at a given type-safe position using 'Proxy'.+modify' :: forall v n k a m p. (KnownNat n, KnownNat k, PrimMonad m, VGM.MVector v a)+ => MVector v (n+k+1) (PrimState m) a -> (a -> a) -> p k -> m ()+modify' (MVector v) f p = VGM.unsafeModify v f (fromInteger (natVal p))+{-# inline modify' #-}++-- | /O(1)/ Modify the element at a given 'Int' position without bounds+-- checking.+unsafeModify :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -> (a -> a) -> Int -> m ()+unsafeModify (MVector v) = VGM.unsafeModify v+{-# inline unsafeModify #-}++-- | /O(1)/ Swap the elements at a given type-safe position using 'Finite's.+swap :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -> Finite n -> Finite n -> m ()+swap (MVector v) i j = VGM.unsafeSwap v (fromIntegral i) (fromIntegral j)+{-# inline swap #-}++-- | /O(1)/ Swap the elements at a given 'Int' position without bounds+-- checking.+unsafeSwap :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -> Int -> Int -> m ()+unsafeSwap (MVector v) = VGM.unsafeSwap v+{-# inline unsafeSwap #-}++-- | /O(1)/ Replace the element at a given type-safe position and return+-- the old element, using 'Finite'.+exchange :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -> Finite n -> a -> m a+exchange (MVector v) i = VGM.unsafeExchange v (fromIntegral i)+{-# inline exchange #-}++-- | /O(1)/ Replace the element at a given type-safe position and return+-- the old element, using 'Finite'.+exchange' :: forall v n k a m p. (KnownNat n, KnownNat k, PrimMonad m, VGM.MVector v a)+ => MVector v (n+k+1) (PrimState m) a -> p k -> a -> m a+exchange' (MVector v) p = VGM.unsafeExchange v (fromInteger (natVal p))+{-# inline exchange' #-}++-- | /O(1)/ Replace the element at a given 'Int' position and return+-- the old element. No bounds checks are performed.+unsafeExchange :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -> Int -> a -> m a+unsafeExchange (MVector v) = VGM.unsafeExchange v+{-# inline unsafeExchange #-}++#if MIN_VERSION_vector(0,12,0)+-- * Modifying vectors++-- | Compute the next (lexicographically) permutation of a given vector+-- in-place. Returns 'False' when the input is the last permutation.+nextPermutation :: forall v n e m. (KnownNat n, Ord e, PrimMonad m, VGM.MVector v e)+ => MVector v n (PrimState m) e -> m Bool+nextPermutation (MVector v) = VGM.nextPermutation v+{-# inline nextPermutation #-}+#endif++-- ** Filling and copying++-- | Set all elements of the vector to the given value.+set :: (PrimMonad m, VGM.MVector v a) => MVector v n (PrimState m) a -> a -> m ()+set (MVector v) = VGM.set v+{-# inline set #-}++-- | Copy a vector. The two vectors may not overlap.+copy :: (PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -- ^ target+ -> MVector v n (PrimState m) a -- ^ source+ -> m ()+copy (MVector v) (MVector u)+ | v `VGM.overlaps` u = error "copy: overlapping vectors"+ | otherwise = VGM.unsafeCopy v u+{-# inline copy #-}++-- | Copy a vector. The two vectors may not overlap. This is not checked.+unsafeCopy :: (PrimMonad m, VGM.MVector v a)+ => MVector v n (PrimState m) a -- ^ target+ -> MVector v n (PrimState m) a -- ^ source+ -> m ()+unsafeCopy (MVector v) (MVector u) = VGM.unsafeCopy v u+{-# 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, VGM.MVector v a)+ => MVector v n (PrimState m) a -- ^ target+ -> MVector v n (PrimState m) a -- ^ source+ -> m ()+move (MVector v) (MVector u) = VGM.unsafeMove v u+{-# inline move #-}++-- * Conversions++-- ** Unsized Mutable Vectors++-- | Convert a 'Data.Vector.Generic.Mutable.MVector' into+-- a 'Data.Vector.Generic.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.Generic.Mutable.MVector'.+toSized :: forall v n s a. (VGM.MVector v a, KnownNat n)+ => v s a -> Maybe (MVector v n s a)+toSized v+ | n' == fromIntegral (VGM.length v) = Just (MVector v)+ | otherwise = Nothing+ where n' = natVal (Proxy :: Proxy n)+{-# inline toSized #-}++-- | Takes a 'Data.Vector.Generic.Mutable.MVector' and returns+-- a continuation providing a 'Data.Vector.Generic.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.Generic.Mutable.MVector' into+-- a 'Data.Vector.Generic.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.Generic.Mutable.MVector'.+withSized :: forall v s a r. VGM.MVector v a+ => v s a -> (forall n. KnownNat n => MVector v n s a -> r) -> r+withSized v f = case someNatVal (fromIntegral (VGM.length v)) of+ Just (SomeNat (Proxy :: Proxy n)) -> f (MVector v :: MVector v n s a)+ Nothing -> error "withSized: VGM.length returned negative length."++-- | Convert a 'Data.Vector.Generic.Mutable.Sized.MVector' into a+-- 'Data.Vector.Generic.Mutable.MVector'.+--+-- Note that this does no copying; the returned+-- 'Data.Vector.Generic.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 v n s a -> v s a+fromSized (MVector v) = v+{-# inline fromSized #-}+
+ src/Data/Vector/Generic/Mutable/Sized/Internal.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE KindSignatures #-}++module Data.Vector.Generic.Mutable.Sized.Internal+ ( MVector(..)+ ) where++import GHC.Generics (Generic)+import GHC.TypeLits+import Control.DeepSeq (NFData)+import Data.Data+import Foreign.Storable++-- | A wrapper to tag mutable vectors with a type level length.+--+-- 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 )
src/Data/Vector/Generic/Sized.hs view
@@ -7,8 +7,12 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE CPP #-} {-| This module reexports the functionality in 'Data.Vector.Generic' which maps well@@ -22,11 +26,14 @@ -} module Data.Vector.Generic.Sized- ( Vector+ ( Vector+ , MVector -- * Accessors -- ** Length information , length , length'+ , knownLength+ , knownLength' -- ** Indexing , index , index'@@ -54,11 +61,13 @@ -- ** Initialization , empty , singleton+#if !MIN_VERSION_GLASGOW_HASKELL(8,3,0,0)+ , fromTuple+#endif , replicate , replicate' , generate , generate'- , generate_ , iterateN , iterateN' -- ** Monadic initialization@@ -66,7 +75,6 @@ , replicateM' , generateM , generateM'- , generateM_ -- ** Unfolding , unfoldrN , unfoldrN'@@ -222,6 +230,12 @@ , withSizedList -- ** Other Vector types , convert+ -- ** Mutable vectors+ , freeze+ , thaw+ , copy+ , unsafeFreeze+ , unsafeThaw -- ** Unsized Vectors , toSized , withSized@@ -229,45 +243,57 @@ , withVectorUnsafe ) where +import Data.Vector.Generic.Sized.Internal import qualified Data.Vector.Generic as VG import qualified Data.Vector as Boxed+import qualified Data.Vector.Generic.Mutable.Sized as SVGM+import Data.Vector.Generic.Mutable.Sized.Internal import GHC.Generics (Generic) import GHC.TypeLits+import Data.Bifunctor import Data.Finite import Data.Finite.Internal import Data.Proxy import Control.DeepSeq (NFData)+import Control.Monad.Primitive import Foreign.Storable import Data.Data+import Data.Functor.Classes import Foreign.Ptr (castPtr)-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 )+import Data.Semigroup+import Text.Read.Lex+import Text.ParserCombinators.ReadPrec+import GHC.Read+import Data.Type.Equality+import Unsafe.Coerce+import Prelude+ hiding (length, 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,+ scanr, scanr1, mapM, mapM_, sequence, sequence_) --- | A wrapper to tag vectors with a type level length.-newtype Vector v (n :: Nat) a = Vector (v a)- deriving ( Show, Eq, Ord, Functor, Foldable, Traversable, NFData, Generic- , Data, Typeable- ) +#if !MIN_VERSION_GLASGOW_HASKELL(8,3,0,0)+import Data.IndexedListLiterals hiding (toList)+import qualified Data.IndexedListLiterals as ILL+#endif++instance (KnownNat n, VG.Vector v a, Read (v a)) => Read (Vector v n a) where+ readPrec = parens $ prec 10 $ do+ expectP (Ident "Vector")+ vec <- readPrec+ if VG.length vec == (fromIntegral $ natVal (Proxy :: Proxy n)) then return $ Vector vec else pfail++type instance VG.Mutable (Vector v n) = MVector (VG.Mutable v) n+ -- | Any sized vector containing storable elements is itself storable. instance (KnownNat n, Storable a, VG.Vector v a) => Storable (Vector v n a) where- sizeOf _ = sizeOf (undefined :: a) * fromInteger (natVal (Proxy :: Proxy n))+ sizeOf _ = sizeOf (undefined :: a) * fromIntegral (natVal (Proxy :: Proxy n)) alignment _ = alignment (undefined :: a)- peek ptr = generateM (peekElemOff (castPtr ptr))- poke ptr = imapM_ (pokeElemOff (castPtr ptr))+ peek ptr = generateM (peekElemOff (castPtr ptr) . fromIntegral)+ poke ptr = imapM_ (pokeElemOff (castPtr ptr) . fromIntegral) -- | The 'Applicative' instance for sized vectors does not have the same -- behaviour as the 'Applicative' instance for the unsized vectors found in the@@ -276,30 +302,64 @@ instance KnownNat n => Applicative (Vector Boxed.Vector n) where pure = replicate (<*>) = zipWith ($)+ (*>) = seq+ (<*) = flip seq +-- | The 'Semigroup' instance for sized vectors does not have the same+-- behaviour as the 'Semigroup' instance for the unsized vectors found in the+-- 'vectors' package. This instance has @(<>) = zipWith (<>)@, but 'vectors'+-- uses concatentation.+instance (Semigroup g, VG.Vector v g) => Semigroup (Vector v n g) where+ (<>) = zipWith (<>)+ stimes = map . stimes+ -- | The 'Monoid' instance for sized vectors does not have the same -- behaviour as the 'Monoid' instance for the unsized vectors found in the--- 'vectors' package. Its @mempty@ is a vector of @mempty@s and its @mappend@--- is @zipWith mappend@.+-- 'vectors' package. This instance has @mempty = replicate mempty@ and+-- @mappend = zipWith mappend@, where the 'vectors' instance uses the empty+-- vector and concatenation.+--+-- If 'mempty' is not necessary, using the 'Semigroup' instance over this+-- 'Monoid' will dodge the 'KnownNat' constraint. instance (Monoid m, VG.Vector v m, KnownNat n) => Monoid (Vector v n m) where mempty = replicate mempty mappend = zipWith mappend-instance {-# OVERLAPPING #-} (VG.Vector v m) => Monoid (Vector v 0 m) where- mempty = empty- _empty1 `mappend` _empty2 = empty+ mconcat vs = generate $ mconcat . flip fmap vs . flip index --- | /O(1)/ Yield the length of the vector as an 'Int'.-length :: forall v n a. (KnownNat n)+-- | /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 v n a. KnownNat n => Vector v n a -> Int-length _ = fromInteger (natVal (Proxy :: Proxy n))+length _ = fromIntegral (natVal (Proxy :: Proxy n)) {-# inline length #-} --- | /O(1)/ Yield the length of the vector as a 'Proxy'.-length' :: forall v n a. (KnownNat n)- => Vector v n a -> Proxy n+-- | /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 v n a.+ Vector v n a -> Proxy n length' _ = Proxy {-# inline length' #-} +-- | /O(1)/ Reveal a 'KnownNat' instance for a vector's length, determined+-- at runtime.+knownLength :: forall v n a r. VG.Vector v a+ => Vector v 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 x = knownLength' v $ const x++-- | /O(1)/ Reveal a 'KnownNat' instance and 'Proxy' for a vector's length,+-- determined at runtime.+knownLength' :: forall v n a r. VG.Vector v a+ => Vector v 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' (Vector v) x = case someNatVal (fromIntegral (VG.length v)) of+ Just (SomeNat (Proxy :: Proxy n')) -> case unsafeCoerce Refl :: n' :~: n of Refl -> x Proxy+ Nothing -> error "impossible: Vector has negative length"+ -- | /O(1)/ Safe indexing using a 'Finite'. index :: forall v n a. (KnownNat n, VG.Vector v a) => Vector v n a -> Finite n -> a@@ -310,7 +370,7 @@ index' :: forall v n m a p. (KnownNat n, KnownNat m, VG.Vector v a) => Vector v (n+m+1) a -> p n -> a index' (Vector v) p = v `VG.unsafeIndex` i- where i = fromInteger (natVal p)+ where i = fromIntegral (natVal p) {-# inline index' #-} -- | /O(1)/ Indexing using an Int without bounds checking.@@ -361,7 +421,7 @@ indexM' :: forall v n k a m p. (KnownNat n, KnownNat k, VG.Vector v a, Monad m) => Vector v (n+k) a -> p n -> m a indexM' (Vector v) p = v `VG.indexM` i- where i = fromInteger (natVal p)+ where i = fromIntegral (natVal p) {-# inline indexM' #-} -- | /O(1)/ Indexing using an Int without bounds checking. See the@@ -392,8 +452,8 @@ -> Vector v (i+n+m) a -> Vector v n a slice start (Vector v) = Vector (VG.unsafeSlice i n v)- where i = fromInteger (natVal start)- n = fromInteger (natVal (Proxy :: Proxy n))+ where i = fromIntegral (natVal start)+ n = fromIntegral (natVal (Proxy :: Proxy n)) {-# inline slice #-} -- | /O(1)/ Yield a slice of the vector without copying it with an explicit@@ -427,7 +487,7 @@ take :: forall v n m a. (KnownNat n, KnownNat m, VG.Vector v a) => Vector v (n+m) a -> Vector v n a take (Vector v) = Vector (VG.unsafeTake i v)- where i = fromInteger (natVal (Proxy :: Proxy n))+ where i = fromIntegral (natVal (Proxy :: Proxy n)) {-# inline take #-} -- | /O(1)/ Yield the first n elements. The resultant vector always contains@@ -444,7 +504,7 @@ drop :: forall v n m a. (KnownNat n, KnownNat m, VG.Vector v a) => Vector v (n+m) a -> Vector v m a drop (Vector v) = Vector (VG.unsafeDrop i v)- where i = fromInteger (natVal (Proxy :: Proxy n))+ where i = fromIntegral (natVal (Proxy :: Proxy n)) {-# inline drop #-} -- | /O(1)/ Yield all but the the first n elements. The given vector must@@ -460,7 +520,7 @@ splitAt :: forall v n m a. (KnownNat n, KnownNat m, VG.Vector v a) => Vector v (n+m) a -> (Vector v n a, Vector v m a) splitAt (Vector v) = (Vector a, Vector b)- where i = fromInteger (natVal (Proxy :: Proxy n))+ where i = fromIntegral (natVal (Proxy :: Proxy n)) (a, b) = VG.splitAt i v {-# inline splitAt #-} @@ -492,12 +552,22 @@ singleton a = Vector (VG.singleton a) {-# inline singleton #-} +#if !MIN_VERSION_GLASGOW_HASKELL(8,3,0,0)+-- | /O(n)/ Construct a vector in a type safe manner+-- fromTuple (1,2) :: Vector v 2 Int+-- fromTuple ("hey", "what's", "going", "on") :: Vector v 4 String+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+#endif+ -- | /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) => a -> Vector v n a replicate a = Vector (VG.replicate i a)- where i = fromInteger (natVal (Proxy :: Proxy n))+ where i = fromIntegral (natVal (Proxy :: Proxy n)) {-# inline replicate #-} -- | /O(n)/ Construct a vector with the same element in each position where the@@ -510,35 +580,24 @@ -- | /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 v n a. (KnownNat n, VG.Vector v a)- => (Int -> a) -> Vector v n a-generate f = Vector (VG.generate i f)- where i = fromInteger (natVal (Proxy :: Proxy n))+ => (Finite n -> a) -> Vector v n a+generate f = Vector (VG.generate i (f . Finite . fromIntegral))+ where i = fromIntegral (natVal (Proxy :: Proxy n)) {-# 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 v n a p. (KnownNat n, VG.Vector v a)- => p n -> (Int -> a) -> Vector v n a+ => p n -> (Finite n -> a) -> Vector v n a generate' _ = generate {-# inline generate' #-} --- | /O(n)/ construct a vector of the given length by applying the function to--- each index where the length is inferred from the type.------ The function can expect a @'Finite' n@, meaning that its input will--- always be between @0@ and @n - 1@.-generate_ :: forall v n a. (KnownNat n, VG.Vector v a)- => (Finite n -> a) -> Vector v n a-generate_ f = Vector (VG.generate i (f . Finite . fromIntegral))- where i = fromInteger (natVal (Proxy :: Proxy n))-{-# inline generate_ #-}- -- | /O(n)/ Apply function n times to value. Zeroth element is original value. -- The length is inferred from the type. iterateN :: forall v n a. (KnownNat n, VG.Vector v a) => (a -> a) -> a -> Vector v n a iterateN f z = Vector (VG.iterateN i f z)- where i = fromInteger (natVal (Proxy :: Proxy n))+ where i = fromIntegral (natVal (Proxy :: Proxy n)) {-# inline iterateN #-} -- | /O(n)/ Apply function n times to value. Zeroth element is original value.@@ -557,7 +616,7 @@ replicateM :: forall v n m a. (KnownNat n, VG.Vector v a, Monad m) => m a -> m (Vector v n a) replicateM a = Vector <$> VG.replicateM i a- where i = fromInteger (natVal (Proxy :: Proxy n))+ where i = fromIntegral (natVal (Proxy :: Proxy n)) {-# inline replicateM #-} -- | /O(n)/ Execute the monadic action @n@ times and store the results in a@@ -570,30 +629,19 @@ -- | /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 v n m a. (KnownNat n, VG.Vector v a, Monad m)- => (Int -> m a) -> m (Vector v n a)-generateM f = Vector <$> VG.generateM i f- where i = fromInteger (natVal (Proxy :: Proxy n))+ => (Finite n -> m a) -> m (Vector v n a)+generateM f = Vector <$> VG.generateM i (f . Finite . fromIntegral)+ where i = fromIntegral (natVal (Proxy :: Proxy n)) {-# 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 v n m a p. (KnownNat n, VG.Vector v a, Monad m)- => p n -> (Int -> m a) -> m (Vector v n a)+ => p n -> (Finite n -> m a) -> m (Vector v n a) generateM' _ = generateM {-# inline generateM' #-} --- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to--- each index where n is inferred from the type. ----- The function can expect a @'Finite' n@, meaning that its input will--- always be between @0@ and @n - 1@.-generateM_ :: forall v n m a. (KnownNat n, VG.Vector v a, Monad m)- => (Finite n -> m a) -> m (Vector v n a)-generateM_ f = Vector <$> VG.generateM i (f . Finite . fromIntegral)- where i = fromInteger (natVal (Proxy :: Proxy n))-{-# inline generateM_ #-}---- -- ** Unfolding -- @@ -603,7 +651,7 @@ unfoldrN :: forall v n a b. (KnownNat n, VG.Vector v a) => (b -> (a, b)) -> b -> Vector v n a unfoldrN f z = Vector (VG.unfoldrN i (Just . f) z)- where i = fromInteger (natVal (Proxy :: Proxy n))+ where i = fromIntegral (natVal (Proxy :: Proxy n)) {-# inline unfoldrN #-} -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying@@ -623,7 +671,7 @@ enumFromN :: forall v n a. (KnownNat n, VG.Vector v a, Num a) => a -> Vector v n a enumFromN a = Vector (VG.enumFromN a i)- where i = fromInteger (natVal (Proxy :: Proxy n))+ where i = fromIntegral (natVal (Proxy :: Proxy n)) {-# inline enumFromN #-} -- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@@@ -638,7 +686,7 @@ enumFromStepN :: forall v n a. (KnownNat n, VG.Vector v a, Num a) => a -> a -> Vector v n a enumFromStepN a a' = Vector (VG.enumFromStepN a a' i)- where i = fromInteger (natVal (Proxy :: Proxy n))+ where i = fromIntegral (natVal (Proxy :: Proxy n)) {-# inline enumFromStepN #-} -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,@@ -703,10 +751,10 @@ -- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7> -- (//) :: (VG.Vector v a)- => Vector v m a -- ^ initial vector (of length @m@)- -> [(Int, a)] -- ^ list of index/value pairs (of length @n@)+ => Vector v m a -- ^ initial vector (of length @m@)+ -> [(Finite m, a)] -- ^ list of index/value pairs (of length @n@) -> Vector v m a-Vector v // us = Vector (v VG.// us)+Vector v // us = Vector (v VG.// (fmap . first) (fromIntegral . getFinite) us) {-# inline (//) #-} -- | /O(m+n)/ For each pair @(i,a)@ from the vector of index/value pairs,@@ -883,9 +931,9 @@ -- -- | /O(n)/ Pair each element in a vector with its index-indexed :: (VG.Vector v a, VG.Vector v (Int,a))- => Vector v n a -> Vector v n (Int,a)-indexed (Vector v) = Vector (VG.indexed v)+indexed :: (VG.Vector v a, VG.Vector v (Int, a), VG.Vector v (Finite n,a))+ => Vector v n a -> Vector v n (Finite n,a)+indexed (Vector v) = Vector ((VG.map . first) (Finite . fromIntegral) $ VG.indexed v) {-# inline indexed #-} --@@ -900,8 +948,8 @@ -- | /O(n)/ Apply a function to every element of a vector and its index imap :: (VG.Vector v a, VG.Vector v b)- => (Int -> a -> b) -> Vector v n a -> Vector v n b-imap f (Vector v) = Vector (VG.imap f v)+ => (Finite n -> a -> b) -> Vector v n a -> Vector v n b+imap f (Vector v) = Vector (VG.imap (f . Finite . fromIntegral) v) {-# inline imap #-} -- | /O(n*m)/ Map a function over a vector and concatenate the results. The@@ -925,8 +973,8 @@ -- | /O(n)/ Apply the monadic action to every element of a vector and its -- index, yielding a vector of results imapM :: (Monad m, VG.Vector v a, VG.Vector v b)- => (Int -> a -> m b) -> Vector v n a -> m (Vector v n b)-imapM f (Vector v) = Vector <$> (VG.imapM f v)+ => (Finite n -> a -> m b) -> Vector v n a -> m (Vector v n b)+imapM f (Vector v) = Vector <$> (VG.imapM (f . Finite . fromIntegral) v) {-# inline imapM #-} -- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the@@ -937,8 +985,8 @@ -- | /O(n)/ Apply the monadic action to every element of a vector and its -- index, ignoring the results-imapM_ :: (Monad m, VG.Vector v a) => (Int -> a -> m b) -> Vector v n a -> m ()-imapM_ f (Vector v) = VG.imapM_ f v+imapM_ :: (Monad m, VG.Vector v a) => (Finite n -> a -> m b) -> Vector v n a -> m ()+imapM_ f (Vector v) = VG.imapM_ (f . Finite . fromIntegral) v {-# inline imapM_ #-} -- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a@@ -1009,37 +1057,37 @@ -- | /O(n)/ Zip two vectors of the same length with a function that also takes -- the elements' indices). izipWith :: (VG.Vector v a,VG.Vector v b,VG.Vector v c)- => (Int -> a -> b -> c)+ => (Finite n -> a -> b -> c) -> Vector v n a -> Vector v n b -> Vector v n c izipWith f (Vector xs) (Vector ys)- = Vector (VG.izipWith f xs ys)+ = Vector (VG.izipWith (f . Finite . fromIntegral) xs ys) {-# inline izipWith #-} izipWith3 :: (VG.Vector v a,VG.Vector v b,VG.Vector v c,VG.Vector v d)- => (Int -> a -> b -> c -> d)+ => (Finite n -> a -> b -> c -> d) -> Vector v n a -> Vector v n b -> Vector v n c -> Vector v n d izipWith3 f (Vector as) (Vector bs) (Vector cs)- = Vector (VG.izipWith3 f as bs cs)+ = Vector (VG.izipWith3 (f . Finite . fromIntegral) as bs cs) {-# inline izipWith3 #-} izipWith4 :: (VG.Vector v a,VG.Vector v b,VG.Vector v c,VG.Vector v d,VG.Vector v e)- => (Int -> a -> b -> c -> d -> e)+ => (Finite n -> a -> b -> c -> d -> e) -> Vector v n a -> Vector v n b -> Vector v n c -> Vector v n d -> Vector v n e izipWith4 f (Vector as) (Vector bs) (Vector cs) (Vector ds)- = Vector (VG.izipWith4 f as bs cs ds)+ = Vector (VG.izipWith4 (f . Finite . fromIntegral) as bs cs ds) {-# inline izipWith4 #-} izipWith5 :: (VG.Vector v a,VG.Vector v b,VG.Vector v c,VG.Vector v d,VG.Vector v e,VG.Vector v f)- => (Int -> a -> b -> c -> d -> e -> f)+ => (Finite n -> a -> b -> c -> d -> e -> f) -> Vector v n a -> Vector v n b -> Vector v n c@@ -1047,11 +1095,11 @@ -> Vector v n e -> Vector v n f izipWith5 f (Vector as) (Vector bs) (Vector cs) (Vector ds) (Vector es)- = Vector (VG.izipWith5 f as bs cs ds es)+ = Vector (VG.izipWith5 (f . Finite . fromIntegral) as bs cs ds es) {-# inline izipWith5 #-} izipWith6 :: (VG.Vector v a,VG.Vector v b,VG.Vector v c,VG.Vector v d,VG.Vector v e,VG.Vector v f,VG.Vector v g)- => (Int -> a -> b -> c -> d -> e -> f -> g)+ => (Finite n -> a -> b -> c -> d -> e -> f -> g) -> Vector v n a -> Vector v n b -> Vector v n c@@ -1060,7 +1108,7 @@ -> Vector v n f -> Vector v n g izipWith6 f (Vector as) (Vector bs) (Vector cs) (Vector ds) (Vector es) (Vector fs)- = Vector (VG.izipWith6 f as bs cs ds es fs)+ = Vector (VG.izipWith6 (f . Finite . fromIntegral) as bs cs ds es fs) {-# inline izipWith6 #-} -- | /O(n)/ Zip two vectors of the same length@@ -1118,8 +1166,8 @@ -- | /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, VG.Vector v a, VG.Vector v b, VG.Vector v c)- => (Int -> a -> b -> m c) -> Vector v n a -> Vector v n b -> m (Vector v n c)-izipWithM m (Vector as) (Vector bs) = Vector <$> VG.izipWithM m as bs+ => (Finite n -> a -> b -> m c) -> Vector v n a -> Vector v n b -> m (Vector v n c)+izipWithM m (Vector as) (Vector bs) = Vector <$> VG.izipWithM (m . Finite . fromIntegral) as bs {-# inline izipWithM #-} -- | /O(n)/ Zip the two vectors with the monadic action and ignore the results@@ -1131,8 +1179,8 @@ -- | /O(n)/ Zip the two vectors with a monadic action that also takes -- the element index and ignore the results izipWithM_ :: (Monad m, VG.Vector v a, VG.Vector v b)- => (Int -> a -> b -> m c) -> Vector v n a -> Vector v n b -> m ()-izipWithM_ m (Vector as) (Vector bs) = VG.izipWithM_ m as bs+ => (Finite n -> a -> b -> m c) -> Vector v n a -> Vector v n b -> m ()+izipWithM_ m (Vector as) (Vector bs) = VG.izipWithM_ (m . Finite . fromIntegral) as bs {-# inline izipWithM_ #-} -- Unzipping@@ -1210,15 +1258,15 @@ -- | /O(n)/ Yield 'Just' the index of the first element matching the predicate -- or 'Nothing' if no such element exists.-findIndex :: VG.Vector v a => (a -> Bool) -> Vector v n a -> Maybe Int-findIndex f (Vector v) = VG.findIndex f v+findIndex :: VG.Vector v a => (a -> Bool) -> Vector v n a -> Maybe (Finite n)+findIndex f (Vector v) = Finite . fromIntegral <$> VG.findIndex f v {-# 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 :: (VG.Vector v a, Eq a) => a -> Vector v n a -> Maybe Int-elemIndex x (Vector v) = VG.elemIndex x v+elemIndex :: (VG.Vector v a, Eq a) => a -> Vector v n a -> Maybe (Finite n)+elemIndex x (Vector v) = Finite . fromIntegral <$> VG.elemIndex x v {-# inline elemIndex #-} --------------------------------------------------------------------------------@@ -1266,25 +1314,25 @@ {-# inline foldr1' #-} -- | /O(n)/ Left fold (function applied to each element and its index)-ifoldl :: VG.Vector v b => (a -> Int -> b -> a) -> a -> Vector v n b -> a-ifoldl f z = VG.ifoldl f z . fromSized+ifoldl :: VG.Vector v b => (a -> Finite n -> b -> a) -> a -> Vector v n b -> a+ifoldl f z = VG.ifoldl (\x -> f x . Finite . fromIntegral) z . fromSized {-# inline ifoldl #-} -- | /O(n)/ Left fold with strict accumulator (function applied to each element -- and its index)-ifoldl' :: VG.Vector v b => (a -> Int -> b -> a) -> a -> Vector v n b -> a-ifoldl' f z = VG.ifoldl' f z . fromSized+ifoldl' :: VG.Vector v b => (a -> Finite n -> b -> a) -> a -> Vector v n b -> a+ifoldl' f z = VG.ifoldl' (\x -> f x . Finite . fromIntegral) z . fromSized {-# inline ifoldl' #-} -- | /O(n)/ Right fold (function applied to each element and its index)-ifoldr :: VG.Vector v a => (Int -> a -> b -> b) -> b -> Vector v n a -> b-ifoldr f z = VG.ifoldr f z . fromSized+ifoldr :: VG.Vector v a => (Finite n -> a -> b -> b) -> b -> Vector v n a -> b+ifoldr f z = VG.ifoldr (f . Finite . fromIntegral) z . fromSized {-# inline ifoldr #-} -- | /O(n)/ Right fold with strict accumulator (function applied to each -- element and its index)-ifoldr' :: VG.Vector v a => (Int -> a -> b -> b) -> b -> Vector v n a -> b-ifoldr' f z = VG.ifoldr' f z . fromSized+ifoldr' :: VG.Vector v a => (Finite n -> a -> b -> b) -> b -> Vector v n a -> b+ifoldr' f z = VG.ifoldr' (f . Finite . fromIntegral) z . fromSized {-# inline ifoldr' #-} -- ** Specialised folds@@ -1344,27 +1392,27 @@ {-# inline minimumBy #-} -- | /O(n)/ Yield the index of the maximum element of the non-empty vector.-maxIndex :: (VG.Vector v a, Ord a, KnownNat n) => Vector v (n+1) a -> Int-maxIndex = VG.maxIndex . fromSized+maxIndex :: (VG.Vector v a, Ord a, KnownNat n) => Vector v (n+1) a -> Finite (n+1)+maxIndex = Finite . fromIntegral . VG.maxIndex . fromSized {-# inline maxIndex #-} -- | /O(n)/ Yield the index of the maximum element of the non-empty vector -- according to the given comparison function. maxIndexBy :: (VG.Vector v a, KnownNat n)- => (a -> a -> Ordering) -> Vector v (n+1) a -> Int-maxIndexBy cmpr = VG.maxIndexBy cmpr . fromSized+ => (a -> a -> Ordering) -> Vector v (n+1) a -> Finite (n + 1)+maxIndexBy cmpr = Finite . fromIntegral . VG.maxIndexBy cmpr . fromSized {-# inline maxIndexBy #-} -- | /O(n)/ Yield the index of the minimum element of the non-empty vector.-minIndex :: (VG.Vector v a, Ord a, KnownNat n) => Vector v (n+1) a -> Int-minIndex = VG.minIndex . fromSized+minIndex :: (VG.Vector v a, Ord a, KnownNat n) => Vector v (n+1) a -> Finite (n+1)+minIndex = Finite . fromIntegral . VG.minIndex . fromSized {-# inline minIndex #-} -- | /O(n)/ Yield the index of the minimum element of the non-empty vector -- according to the given comparison function. minIndexBy :: (VG.Vector v a, KnownNat n)- => (a -> a -> Ordering) -> Vector v (n+1) a -> Int-minIndexBy cmpr = VG.minIndexBy cmpr . fromSized+ => (a -> a -> Ordering) -> Vector v (n+1) a -> Finite (n + 1)+minIndexBy cmpr = Finite . fromIntegral . VG.minIndexBy cmpr . fromSized {-# inline minIndexBy #-} -- ** Monadic folds@@ -1375,8 +1423,8 @@ {-# inline foldM #-} -- | /O(n)/ Monadic fold (action applied to each element and its index)-ifoldM :: (Monad m, VG.Vector v b) => (a -> Int -> b -> m a) -> a -> Vector v n b -> m a-ifoldM m z = VG.ifoldM m z . fromSized+ifoldM :: (Monad m, VG.Vector v b) => (a -> Finite n -> b -> m a) -> a -> Vector v n b -> m a+ifoldM m z = VG.ifoldM (\x -> m x . Finite . fromIntegral) z . fromSized {-# inline ifoldM #-} -- | /O(n)/ Monadic fold over non-empty vectors@@ -1393,8 +1441,8 @@ -- | /O(n)/ Monadic fold with strict accumulator (action applied to each -- element and its index) ifoldM' :: (Monad m, VG.Vector v b)- => (a -> Int -> b -> m a) -> a -> Vector v n b -> m a-ifoldM' m z = VG.ifoldM' m z . fromSized+ => (a -> Finite n -> b -> m a) -> a -> Vector v n b -> m a+ifoldM' m z = VG.ifoldM' (\x -> m x . Finite . fromIntegral) z . fromSized {-# inline ifoldM' #-} -- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator@@ -1412,8 +1460,8 @@ -- | /O(n)/ Monadic fold that discards the result (action applied to -- each element and its index) ifoldM_ :: (Monad m, VG.Vector v b)- => (a -> Int -> b -> m a) -> a -> Vector v n b -> m ()-ifoldM_ m z = VG.ifoldM_ m z . fromSized+ => (a -> Finite n -> b -> m a) -> a -> Vector v n b -> m ()+ifoldM_ m z = VG.ifoldM_ (\x -> m x . Finite . fromIntegral) z . fromSized {-# inline ifoldM_ #-} -- | /O(n)/ Monadic fold over non-empty vectors that discards the result@@ -1431,8 +1479,8 @@ -- | /O(n)/ Monadic fold with strict accumulator that discards the result -- (action applied to each element and its index) ifoldM'_ :: (Monad m, VG.Vector v b)- => (a -> Int -> b -> m a) -> a -> Vector v n b -> m ()-ifoldM'_ m z = VG.ifoldM'_ m z . fromSized+ => (a -> Finite n -> b -> m a) -> a -> Vector v n b -> m ()+ifoldM'_ m z = VG.ifoldM'_ (\x -> m x . Finite . fromIntegral) z . fromSized {-# inline ifoldM'_ #-} -- | /O(n)/ Monad fold over non-empty vectors with strict accumulator@@ -1567,7 +1615,7 @@ fromListN :: forall v n a. (VG.Vector v a, KnownNat n) => [a] -> Maybe (Vector v n a) fromListN = toSized . VG.fromListN i- where i = fromInteger (natVal (Proxy :: Proxy n))+ where i = fromIntegral (natVal (Proxy :: Proxy n)) {-# inline fromListN #-} -- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of@@ -1595,6 +1643,41 @@ convert = withVectorUnsafe VG.convert {-# inline convert #-} +-- ** Mutable vectors++-- | /O(n)/ Yield an immutable copy of the mutable vector.+freeze :: (PrimMonad m, VG.Vector v a)+ => SVGM.MVector (VG.Mutable v) n (PrimState m) a+ -> m (Vector v n a)+freeze (MVector v) = Vector <$> VG.freeze v++-- | /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, VG.Vector v a)+ => SVGM.MVector (VG.Mutable v) n (PrimState m) a+ -> m (Vector v n a)+unsafeFreeze (MVector v) = Vector <$> VG.unsafeFreeze v++-- | /O(n)/ Yield a mutable copy of the immutable vector.+thaw :: (PrimMonad m, VG.Vector v a)+ => Vector v n a+ -> m (SVGM.MVector (VG.Mutable v) n (PrimState m) a)+thaw (Vector v) = MVector <$> VG.thaw v++-- | /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, VG.Vector v a)+ => Vector v n a+ -> m (SVGM.MVector (VG.Mutable v) n (PrimState m) a)+unsafeThaw (Vector v) = MVector <$> VG.unsafeThaw v++-- | /O(n)/ Copy an immutable vector into a mutable one.+copy :: (PrimMonad m, VG.Vector v a)+ => SVGM.MVector (VG.Mutable v) n (PrimState m) a+ -> Vector v n a+ -> m ()+copy (MVector v) (Vector u) = VG.unsafeCopy v u+ -- ** Unsized vectors -- | Convert a 'Data.Vector.Generic.Vector' into a@@ -1618,8 +1701,8 @@ withSized :: forall v a r. VG.Vector v a => v a -> (forall n. KnownNat n => Vector v n a -> r) -> r withSized v f = case someNatVal (fromIntegral (VG.length v)) of- Just (SomeNat (Proxy :: Proxy n)) -> f (Vector v :: Vector v n a)- Nothing -> error "withSized: VG.length returned negative length."+ Just (SomeNat (Proxy :: Proxy n)) -> f (Vector v :: Vector v n a)+ Nothing -> error "impossible: Vector has negative length" fromSized :: Vector v n a -> v a fromSized (Vector v) = v
+ src/Data/Vector/Generic/Sized/Internal.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE KindSignatures #-}++module Data.Vector.Generic.Sized.Internal+ ( Vector(..)+ ) where++import Control.DeepSeq (NFData)+import Data.Data+import Data.Functor.Classes+import Foreign.Storable+import GHC.Generics (Generic)+import GHC.TypeLits++-- | A wrapper to tag vectors with a type level length.+--+-- 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+ , Show1, Eq1, Ord1+ , Data, Typeable+ )
+ src/Data/Vector/Mutable/Sized.hs view
@@ -0,0 +1,474 @@+{-# 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.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 resultant vector size is not know until compile time are+not exported.+-}++module Data.Vector.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.Mutable as VM+import GHC.TypeLits+import Data.Finite+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.Storable.Mutable'+type MVector = VGM.MVector VM.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. (KnownNat n)+ => 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, KnownNat k)+ => 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, KnownNat k)+ => 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. ()+ => 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. ()+ => MVector (1+n) s a -> MVector n s a+tail = VGM.tail+{-# inline tail #-}++-- | /O(1)/ Yield the first n elements. The resultant vector always contains+-- this many elements. The length of the resultant vector is inferred from the+-- type.+take :: forall n k s a. (KnownNat n, KnownNat k)+ => MVector (n+k) s a -> MVector n s a+take = VGM.take+{-# inline take #-}++-- | /O(1)/ Yield the first n elements. The resultant vector always contains+-- this many elements. The length of the resultant vector is given explicitly+-- as a 'Proxy' argument.+take' :: forall n k s a p. (KnownNat n, KnownNat k)+ => 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 resultant vector is+-- inferred from the type.+drop :: forall n k s a. (KnownNat n, KnownNat k)+ => 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 resultant vector is+-- givel explicitly as a 'Proxy' argument.+drop' :: forall n k s a p. (KnownNat n, KnownNat k)+ => 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 remainder without copying.+-- The lengths of the resultant vector are inferred from the type.+splitAt :: forall n m s a. (KnownNat n, KnownNat m)+ => 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 remainder without+-- copying. The length of the first resultant vector is passed explicitly as a+-- 'Proxy' argument.+splitAt' :: forall n m s a p. (KnownNat n, KnownNat m)+ => p n -> MVector (n+m) s a -> (MVector n s a, MVector m s a)+splitAt' = VGM.splitAt'+{-# inline splitAt' #-}++-- ** Overlaps++-- | /O(1)/ Yield all but the the first n elements. The given vector must+-- contain at least this many elements The length of the resultant vector is+-- inferred from the type.+overlaps :: forall n k s a. (KnownNat n, KnownNat k)+ => 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)+ => 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)+ => 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)+ => 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)+ => 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)+ => 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)+ => 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+ => 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)+ => 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)+ => 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 => 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. (KnownNat n, PrimMonad m)+ => 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 n, KnownNat k, PrimMonad m)+ => 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. (KnownNat n, PrimMonad m)+ => 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. (KnownNat n, PrimMonad m)+ => 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 n, KnownNat k, PrimMonad m)+ => 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. (KnownNat n, PrimMonad m)+ => 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. (KnownNat n, PrimMonad m)+ => 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 n, KnownNat k, PrimMonad m)+ => 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. (KnownNat n, PrimMonad m)+ => MVector n (PrimState m) a -> (a -> a) -> Int -> m ()+unsafeModify = VGM.unsafeModify+{-# inline unsafeModify #-}++-- | /O(1)/ Swap the elements at a given type-safe position using 'Finite's.+swap :: forall n m a. (KnownNat n, PrimMonad m)+ => MVector n (PrimState m) a -> Finite n -> Finite n -> m ()+swap = VGM.swap+{-# inline swap #-}++-- | /O(1)/ Swap the elements at a given 'Int' position without bounds+-- checking.+unsafeSwap :: forall n m a. (KnownNat n, PrimMonad m)+ => 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. (KnownNat n, PrimMonad m)+ => 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 n, KnownNat k, PrimMonad m)+ => 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. (KnownNat n, PrimMonad m)+ => 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 (lexicographically) permutation of a given vector+-- in-place. Returns 'False' when the input is the last permutation.+nextPermutation :: forall n e m. (KnownNat n, Ord e, PrimMonad m)+ => 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 => MVector n (PrimState m) a -> a -> m ()+set = VGM.set+{-# inline set #-}++-- | Copy a vector. The two vectors may not overlap.+copy :: PrimMonad m+ => MVector n (PrimState m) a -- ^ target+ -> MVector n (PrimState m) a -- ^ source+ -> m ()+copy = VGM.copy+{-# inline copy #-}++-- | Copy a vector. The two vectors may not overlap. This is not checked.+unsafeCopy :: PrimMonad m+ => 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+ => MVector n (PrimState m) a -- ^ target+ -> MVector n (PrimState m) a -- ^ source+ -> m ()+move = VGM.move+{-# inline move #-}++-- * Conversions++-- ** Unsized Mutable Vectors++-- | Convert a 'Data.Vector.Generic.Mutable.MVector' into+-- a 'Data.Vector.Generic.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.Generic.Mutable.MVector'.+toSized :: forall n a s. KnownNat n+ => VM.MVector s a -> Maybe (MVector n s a)+toSized = VGM.toSized+{-# inline toSized #-}++-- | Takes a 'Data.Vector.Mutable.MVector' and returns+-- a continuation providing a 'Data.Vector.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.Mutable.MVector' into+-- a 'Data.Vector.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.Mutable.MVector'.+withSized :: forall s a r. ()+ => VM.MVector s a -> (forall n. KnownNat n => MVector n s a -> r) -> r+withSized = VGM.withSized+{-# inline withSized #-}++-- | Convert a 'Data.Vector.Generic.Mutable.Sized.MVector' into a+-- 'Data.Vector.Generic.Mutable.MVector'.+--+-- Note that this does no copying; the returned+-- 'Data.Vector.Generic.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 -> VM.MVector s a+fromSized = VGM.fromSized+{-# inline fromSized #-}++
src/Data/Vector/Sized.hs view
@@ -1,12 +1,12 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE KindSignatures #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-}+{-# LANGUAGE CPP #-} + {-| This module re-exports the functionality in 'Data.Vector.Generic.Sized' specialized to 'Data.Vector'.@@ -20,10 +20,13 @@ module Data.Vector.Sized ( Vector+ , VM.MVector -- * Accessors -- ** Length information , length , length'+ , knownLength+ , knownLength' -- ** Indexing , index , index'@@ -51,11 +54,13 @@ -- ** Initialization , empty , singleton+#if !MIN_VERSION_GLASGOW_HASKELL(8,3,0,0)+ , fromTuple+#endif , replicate , replicate' , generate , generate'- , generate_ , iterateN , iterateN' -- ** Monadic initialization@@ -63,7 +68,6 @@ , replicateM' , generateM , generateM'- , generateM_ -- ** Unfolding , unfoldrN , unfoldrN'@@ -217,6 +221,12 @@ , fromListN , fromListN' , withSizedList+ -- ** Mutable vectors+ , freeze+ , thaw+ , copy+ , unsafeFreeze+ , unsafeThaw -- ** Unsized Vectors , toSized , withSized@@ -226,9 +236,14 @@ import qualified Data.Vector.Generic.Sized as V import qualified Data.Vector as VU+import qualified Data.Vector.Mutable.Sized as VM import GHC.TypeLits import Data.Finite import Data.Proxy+#if !MIN_VERSION_GLASGOW_HASKELL(8,3,0,0)+import Data.IndexedListLiterals hiding (toList)+#endif+import Control.Monad.Primitive import Prelude hiding ( length, null, replicate, (++), concat, head, last,@@ -248,18 +263,38 @@ -- 'Data.Vector' type Vector = V.Vector VU.Vector --- | /O(1)/ Yield the length of the vector as an 'Int'.+-- | /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'.-length' :: forall n a. KnownNat n- => Vector n a -> Proxy n+-- | /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.+ 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.+ 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. KnownNat n => Vector n a -> Finite n -> a@@ -437,6 +472,16 @@ singleton = V.singleton {-# inline singleton #-} +#if !MIN_VERSION_GLASGOW_HASKELL(8,3,0,0)+-- | /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 input length ty.+ (IndexedListLiterals input length ty, KnownNat length)+ => input -> Vector length ty+fromTuple = V.fromTuple+#endif+ -- | /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@@ -454,27 +499,17 @@ -- | /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- => (Int -> a) -> Vector n 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- => p n -> (Int -> a) -> Vector n a+ => p n -> (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 inferred from the type.------ The function can expect a @'Finite' n@, meaning that its input will--- always be between @0@ and @n - 1@.-generate_ :: forall n a. KnownNat 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@@ -510,24 +545,14 @@ -- | /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, Monad m)- => (Int -> m a) -> m (Vector n a)+ => (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 inferred from the type.------ The function can expect a @'Finite' n@, meaning that its input will--- always be between @0@ and @n - 1@.-generateM_ :: forall n m a. (KnownNat n, 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, Monad m)- => p n -> (Int -> m a) -> m (Vector n a)+ => p n -> (Finite n -> m a) -> m (Vector n a) generateM' = V.generateM' {-# inline generateM' #-} @@ -634,8 +659,8 @@ -- -- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7> ---(//) :: Vector m a -- ^ initial vector (of length @m@)- -> [(Int, a)] -- ^ list of index/value pairs (of length @n@)+(//) :: Vector m a -- ^ initial vector (of length @m@)+ -> [(Finite m, a)] -- ^ list of index/value pairs (of length @n@) -> Vector m a (//) = (V.//) {-# inline (//) #-}@@ -800,7 +825,7 @@ -- -- | /O(n)/ Pair each element in a vector with its index-indexed :: Vector n a -> Vector n (Int,a)+indexed :: Vector n a -> Vector n (Finite n,a) indexed = V.indexed {-# inline indexed #-} @@ -814,7 +839,7 @@ {-# inline map #-} -- | /O(n)/ Apply a function to every element of a vector and its index-imap :: (Int -> a -> b) -> Vector n a -> Vector n b+imap :: (Finite n -> a -> b) -> Vector n a -> Vector n b imap = V.imap {-# inline imap #-} @@ -836,7 +861,7 @@ -- | /O(n)/ Apply the monadic action to every element of a vector and its -- index, yielding a vector of results-imapM :: Monad m => (Int -> a -> m b) -> Vector n a -> m (Vector n b)+imapM :: Monad m => (Finite n -> a -> m b) -> Vector n a -> m (Vector n b) imapM = V.imapM {-# inline imapM #-} @@ -848,7 +873,7 @@ -- | /O(n)/ Apply the monadic action to every element of a vector and its -- index, ignoring the results-imapM_ :: Monad m => (Int -> a -> m b) -> Vector n a -> m ()+imapM_ :: Monad m => (Finite n -> a -> m b) -> Vector n a -> m () imapM_ = V.imapM_ {-# inline imapM_ #-} @@ -910,14 +935,14 @@ -- | /O(n)/ Zip two vectors of the same length with a function that also takes -- the elements' indices).-izipWith :: (Int -> a -> b -> c)+izipWith :: (Finite n -> a -> b -> c) -> Vector n a -> Vector n b -> Vector n c izipWith = V.izipWith {-# inline izipWith #-} -izipWith3 :: (Int -> a -> b -> c -> d)+izipWith3 :: (Finite n -> a -> b -> c -> d) -> Vector n a -> Vector n b -> Vector n c@@ -925,7 +950,7 @@ izipWith3 = V.izipWith3 {-# inline izipWith3 #-} -izipWith4 :: (Int -> a -> b -> c -> d -> e)+izipWith4 :: (Finite n -> a -> b -> c -> d -> e) -> Vector n a -> Vector n b -> Vector n c@@ -934,7 +959,7 @@ izipWith4 = V.izipWith4 {-# inline izipWith4 #-} -izipWith5 :: (Int -> a -> b -> c -> d -> e -> f)+izipWith5 :: (Finite n -> a -> b -> c -> d -> e -> f) -> Vector n a -> Vector n b -> Vector n c@@ -944,7 +969,7 @@ izipWith5 = V.izipWith5 {-# inline izipWith5 #-} -izipWith6 :: (Int -> a -> b -> c -> d -> e -> f -> g)+izipWith6 :: (Finite n -> a -> b -> c -> d -> e -> f -> g) -> Vector n a -> Vector n b -> Vector n c@@ -1005,7 +1030,7 @@ -- | /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- => (Int -> a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)+ => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c) izipWithM = V.izipWithM {-# inline izipWithM #-} @@ -1018,7 +1043,7 @@ -- | /O(n)/ Zip the two vectors with a monadic action that also takes -- the element index and ignore the results izipWithM_ :: Monad m- => (Int -> a -> b -> m c) -> Vector n a -> Vector n b -> m ()+ => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m () izipWithM_ = V.izipWithM_ {-# inline izipWithM_ #-} @@ -1075,14 +1100,14 @@ -- | /O(n)/ Yield 'Just' the index of the first element matching the predicate -- or 'Nothing' if no such element exists.-findIndex :: (a -> Bool) -> Vector n a -> Maybe Int+findIndex :: (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 :: (Eq a) => a -> Vector n a -> Maybe Int+elemIndex :: (Eq a) => a -> Vector n a -> Maybe (Finite n) elemIndex = V.elemIndex {-# inline elemIndex #-} @@ -1131,24 +1156,24 @@ {-# inline foldr1' #-} -- | /O(n)/ Left fold (function applied to each element and its index)-ifoldl :: (a -> Int -> b -> a) -> a -> Vector n b -> a+ifoldl :: (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' :: (a -> Int -> b -> a) -> a -> Vector n b -> a+ifoldl' :: (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 :: (Int -> a -> b -> b) -> b -> Vector n a -> b+ifoldr :: (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' :: (Int -> a -> b -> b) -> b -> Vector n a -> b+ifoldr' :: (Finite n -> a -> b -> b) -> b -> Vector n a -> b ifoldr' = V.ifoldr' {-# inline ifoldr' #-} @@ -1209,26 +1234,26 @@ {-# inline minimumBy #-} -- | /O(n)/ Yield the index of the maximum element of the non-empty vector.-maxIndex :: (Ord a, KnownNat n) => Vector (n+1) a -> Int+maxIndex :: (Ord a, KnownNat n) => 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 :: KnownNat n- => (a -> a -> Ordering) -> Vector (n+1) a -> Int+ => (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 :: (Ord a, KnownNat n) => Vector (n+1) a -> Int+minIndex :: (Ord a, KnownNat n) => 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 :: KnownNat n- => (a -> a -> Ordering) -> Vector (n+1) a -> Int+ => (a -> a -> Ordering) -> Vector (n+1) a -> Finite (n + 1) minIndexBy = V.minIndexBy {-# inline minIndexBy #-} @@ -1240,7 +1265,7 @@ {-# inline foldM #-} -- | /O(n)/ Monadic fold (action applied to each element and its index)-ifoldM :: Monad m => (a -> Int -> b -> m a) -> a -> Vector n b -> m a+ifoldM :: Monad m => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a ifoldM = V.ifoldM {-# inline ifoldM #-} @@ -1258,7 +1283,7 @@ -- | /O(n)/ Monadic fold with strict accumulator (action applied to each -- element and its index) ifoldM' :: Monad m- => (a -> Int -> b -> m a) -> a -> Vector n b -> m a+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a ifoldM' = V.ifoldM' {-# inline ifoldM' #-} @@ -1277,7 +1302,7 @@ -- | /O(n)/ Monadic fold that discards the result (action applied to -- each element and its index) ifoldM_ :: Monad m- => (a -> Int -> b -> m a) -> a -> Vector n b -> m ()+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m () ifoldM_ = V.ifoldM_ {-# inline ifoldM_ #-} @@ -1296,7 +1321,7 @@ -- | /O(n)/ Monadic fold with strict accumulator that discards the result -- (action applied to each element and its index) ifoldM'_ :: Monad m- => (a -> Int -> b -> m a) -> a -> Vector n b -> m ()+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m () ifoldM'_ = V.ifoldM'_ {-# inline ifoldM'_ #-} @@ -1451,6 +1476,41 @@ withSizedList xs = withSized (VU.fromList xs) {-# inline withSizedList #-} +-- ** Mutable vectors++-- | /O(n)/ Yield an immutable copy of the mutable vector.+freeze :: PrimMonad m+ => VM.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+ => VM.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+ => Vector n a+ -> m (VM.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+ => Vector n a+ -> m (VM.MVector n (PrimState m) a)+unsafeThaw = V.unsafeThaw++-- | /O(n)/ Copy an immutable vector into a mutable one.+copy :: PrimMonad m+ => VM.MVector n (PrimState m) a+ -> Vector n a+ -> m ()+copy = V.copy+ -- ** Unsized vectors -- | Convert a 'Data.Vector.Generic.Vector' into a@@ -1481,4 +1541,3 @@ withVectorUnsafe :: (VU.Vector a -> VU.Vector b) -> Vector n a -> Vector n b withVectorUnsafe = V.withVectorUnsafe {-# inline withVectorUnsafe #-}-
+ src/Data/Vector/Storable/Mutable/Sized.hs view
@@ -0,0 +1,475 @@+{-# 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.Storable.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 resultant vector size is not know until compile time are+not exported.+-}++module Data.Vector.Storable.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.Storable.Mutable as VSM+import Foreign.Storable+import GHC.TypeLits+import Data.Finite+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.Storable.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. (KnownNat n)+ => 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, KnownNat k, Storable 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, KnownNat k, Storable 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. Storable 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. Storable a+ => MVector (1+n) s a -> MVector n s a+tail = VGM.tail+{-# inline tail #-}++-- | /O(1)/ Yield the first n elements. The resultant vector always contains+-- this many elements. The length of the resultant vector is inferred from the+-- type.+take :: forall n k s a. (KnownNat n, KnownNat k, Storable a)+ => MVector (n+k) s a -> MVector n s a+take = VGM.take+{-# inline take #-}++-- | /O(1)/ Yield the first n elements. The resultant vector always contains+-- this many elements. The length of the resultant vector is given explicitly+-- as a 'Proxy' argument.+take' :: forall n k s a p. (KnownNat n, KnownNat k, Storable 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 resultant vector is+-- inferred from the type.+drop :: forall n k s a. (KnownNat n, KnownNat k, Storable 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 resultant vector is+-- givel explicitly as a 'Proxy' argument.+drop' :: forall n k s a p. (KnownNat n, KnownNat k, Storable 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 remainder without copying.+-- The lengths of the resultant vector are inferred from the type.+splitAt :: forall n m s a. (KnownNat n, KnownNat m, Storable 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 remainder without+-- copying. The length of the first resultant vector is passed explicitly as a+-- 'Proxy' argument.+splitAt' :: forall n m s a p. (KnownNat n, KnownNat m, Storable a)+ => p n -> MVector (n+m) s a -> (MVector n s a, MVector m s a)+splitAt' = VGM.splitAt'+{-# inline splitAt' #-}++-- ** Overlaps++-- | /O(1)/ Yield all but the the first n elements. The given vector must+-- contain at least this many elements The length of the resultant vector is+-- inferred from the type.+overlaps :: forall n k s a. (KnownNat n, KnownNat k, Storable 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, Storable 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, Storable 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, Storable 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, Storable 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, Storable 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, Storable 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, Storable 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, Storable 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, Storable 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, Storable 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. (KnownNat n, PrimMonad m, Storable 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 n, KnownNat k, PrimMonad m, Storable 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. (KnownNat n, PrimMonad m, Storable 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. (KnownNat n, PrimMonad m, Storable 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 n, KnownNat k, PrimMonad m, Storable 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. (KnownNat n, PrimMonad m, Storable 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. (KnownNat n, PrimMonad m, Storable 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 n, KnownNat k, PrimMonad m, Storable 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. (KnownNat n, PrimMonad m, Storable a)+ => MVector n (PrimState m) a -> (a -> a) -> Int -> m ()+unsafeModify = VGM.unsafeModify+{-# inline unsafeModify #-}++-- | /O(1)/ Swap the elements at a given type-safe position using 'Finite's.+swap :: forall n m a. (KnownNat n, PrimMonad m, Storable a)+ => MVector n (PrimState m) a -> Finite n -> Finite n -> m ()+swap = VGM.swap+{-# inline swap #-}++-- | /O(1)/ Swap the elements at a given 'Int' position without bounds+-- checking.+unsafeSwap :: forall n m a. (KnownNat n, PrimMonad m, Storable 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. (KnownNat n, PrimMonad m, Storable 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 n, KnownNat k, PrimMonad m, Storable 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. (KnownNat n, PrimMonad m, Storable 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 (lexicographically) permutation of a given vector+-- in-place. Returns 'False' when the input is the last permutation.+nextPermutation :: forall n e m. (KnownNat n, Ord e, PrimMonad m, Storable 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, Storable 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, Storable 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, Storable 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, Storable a)+ => MVector n (PrimState m) a -- ^ target+ -> MVector n (PrimState m) a -- ^ source+ -> m ()+move = VGM.move+{-# inline move #-}++-- | Convert a 'Data.Vector.Storable.Mutable.MVector' into+-- a 'Data.Vector.Storable.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.Storable.Mutable.MVector'.+toSized :: forall n a s. (KnownNat n, Storable a)+ => VSM.MVector s a -> Maybe (MVector n s a)+toSized = VGM.toSized+{-# inline toSized #-}++-- | Takes a 'Data.Vector.Storable.Mutable.MVector' and returns+-- a continuation providing a 'Data.Vector.Storable.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.Storable.Mutable.MVector' into+-- a 'Data.Vector.Storable.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.Storable.Mutable.MVector'.+withSized :: forall s a r. Storable a+ => VSM.MVector s a -> (forall n. KnownNat n => MVector n s a -> r) -> r+withSized = VGM.withSized+{-# inline withSized #-}++-- | Convert a 'Data.Vector.Storable.Mutable.Sized.MVector' into a+-- 'Data.Vector.Storable.Mutable.MVector'.+--+-- Note that this does no copying; the returned+-- 'Data.Vector.Storable.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/Storable/Sized.hs view
@@ -1,10 +1,11 @@+{-# LANGUAGE KindSignatures #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE KindSignatures #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-}+{-# LANGUAGE CPP #-} {-| This module re-exports the functionality in 'Data.Vector.Generic.Sized'@@ -19,10 +20,13 @@ module Data.Vector.Storable.Sized ( Vector+ , VSM.MVector -- * Accessors -- ** Length information , length , length'+ , knownLength+ , knownLength' -- ** Indexing , index , index'@@ -50,11 +54,13 @@ -- ** Initialization , empty , singleton+#if !MIN_VERSION_GLASGOW_HASKELL(8,3,0,0)+ , fromTuple+#endif , replicate , replicate' , generate , generate'- , generate_ , iterateN , iterateN' -- ** Monadic initialization@@ -62,7 +68,6 @@ , replicateM' , generateM , generateM'- , generateM_ -- ** Unfolding , unfoldrN , unfoldrN'@@ -216,6 +221,12 @@ , fromListN , fromListN' , withSizedList+ -- ** Mutable vectors+ , freeze+ , thaw+ , copy+ , unsafeFreeze+ , unsafeThaw -- ** Unsized Vectors , toSized , withSized@@ -225,9 +236,14 @@ import qualified Data.Vector.Generic.Sized as V import qualified Data.Vector.Storable as VS+#if !MIN_VERSION_GLASGOW_HASKELL(8,3,0,0)+import Data.IndexedListLiterals (IndexedListLiterals)+#endif+import qualified Data.Vector.Storable.Mutable.Sized as VSM import GHC.TypeLits import Data.Finite import Data.Proxy+import Control.Monad.Primitive import Foreign.Storable import Prelude hiding ( length, null, replicate, (++), concat,@@ -248,18 +264,38 @@ -- 'Data.Vector.Storable' type Vector = V.Vector VS.Vector --- | /O(1)/ Yield the length of the vector as an 'Int'.-length :: forall n a. (KnownNat n)+-- | /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'.-length' :: forall n a. (KnownNat n)- => Vector n a -> Proxy n+-- | /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. Storable 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. Storable 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. (KnownNat n, Storable a) => Vector n a -> Finite n -> a@@ -444,6 +480,17 @@ singleton = V.singleton {-# inline singleton #-} +#if !MIN_VERSION_GLASGOW_HASKELL(8,3,0,0)+-- | /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.+ (Storable a, IndexedListLiterals input length a, KnownNat length)+ => input -> Vector length a+fromTuple = V.fromTuple+{-# inline fromTuple #-}+#endif+ -- | /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)@@ -461,27 +508,17 @@ -- | /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, Storable a)- => (Int -> a) -> Vector n 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, Storable a)- => p n -> (Int -> a) -> Vector n a+ => p n -> (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 inferred from the type.------ The function can expect a @'Finite' n@, meaning that its input will--- always be between @0@ and @n - 1@.-generate_ :: forall n a. (KnownNat n, Storable a)- => (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, Storable a)@@ -517,28 +554,18 @@ -- | /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, Storable a, Monad m)- => (Int -> m a) -> m (Vector n a)+ => (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, Storable a, Monad m)- => p n -> (Int -> m a) -> m (Vector n a)+ => p n -> (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 inferred from the type. ----- The function can expect a @'Finite' n@, meaning that its input will--- always be between @0@ and @n - 1@.-generateM_ :: forall n m a. (KnownNat n, Storable a, Monad m)- => (Finite n -> m a) -> m (Vector n a)-generateM_ = V.generateM_-{-# inline generateM_ #-}---- -- ** Unfolding -- @@ -645,8 +672,8 @@ -- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7> -- (//) :: (Storable a)- => Vector m a -- ^ initial vector (of length @m@)- -> [(Int, a)] -- ^ list of index/value pairs (of length @n@)+ => Vector m a -- ^ initial vector (of length @m@)+ -> [(Finite m, a)] -- ^ list of index/value pairs (of length @n@) -> Vector m a (//) = (V.//) {-# inline (//) #-}@@ -824,8 +851,8 @@ -- -- | /O(n)/ Pair each element in a vector with its index-indexed :: (Storable a, Storable (Int,a))- => Vector n a -> Vector n (Int,a)+indexed :: (Storable a, Storable (Int, a), Storable (Finite n, a))+ => Vector n a -> Vector n (Finite n,a) indexed = V.indexed {-# inline indexed #-} @@ -841,7 +868,7 @@ -- | /O(n)/ Apply a function to every element of a vector and its index imap :: (Storable a, Storable b)- => (Int -> a -> b) -> Vector n a -> Vector n b+ => (Finite n -> a -> b) -> Vector n a -> Vector n b imap = V.imap {-# inline imap #-} @@ -866,7 +893,7 @@ -- | /O(n)/ Apply the monadic action to every element of a vector and its -- index, yielding a vector of results imapM :: (Monad m, Storable a, Storable b)- => (Int -> a -> m b) -> Vector n a -> m (Vector n b)+ => (Finite n -> a -> m b) -> Vector n a -> m (Vector n b) imapM = V.imapM {-# inline imapM #-} @@ -878,7 +905,7 @@ -- | /O(n)/ Apply the monadic action to every element of a vector and its -- index, ignoring the results-imapM_ :: (Monad m, Storable a) => (Int -> a -> m b) -> Vector n a -> m ()+imapM_ :: (Monad m, Storable a) => (Finite n -> a -> m b) -> Vector n a -> m () imapM_ = V.imapM_ {-# inline imapM_ #-} @@ -947,7 +974,7 @@ -- | /O(n)/ Zip two vectors of the same length with a function that also takes -- the elements' indices). izipWith :: (Storable a,Storable b,Storable c)- => (Int -> a -> b -> c)+ => (Finite n -> a -> b -> c) -> Vector n a -> Vector n b -> Vector n c@@ -955,7 +982,7 @@ {-# inline izipWith #-} izipWith3 :: (Storable a,Storable b,Storable c,Storable d)- => (Int -> a -> b -> c -> d)+ => (Finite n -> a -> b -> c -> d) -> Vector n a -> Vector n b -> Vector n c@@ -964,7 +991,7 @@ {-# inline izipWith3 #-} izipWith4 :: (Storable a,Storable b,Storable c,Storable d,Storable e)- => (Int -> a -> b -> c -> d -> e)+ => (Finite n -> a -> b -> c -> d -> e) -> Vector n a -> Vector n b -> Vector n c@@ -974,7 +1001,7 @@ {-# inline izipWith4 #-} izipWith5 :: (Storable a,Storable b,Storable c,Storable d,Storable e,Storable f)- => (Int -> a -> b -> c -> d -> e -> f)+ => (Finite n -> a -> b -> c -> d -> e -> f) -> Vector n a -> Vector n b -> Vector n c@@ -985,7 +1012,7 @@ {-# inline izipWith5 #-} izipWith6 :: (Storable a,Storable b,Storable c,Storable d,Storable e,Storable f,Storable g)- => (Int -> a -> b -> c -> d -> e -> f -> g)+ => (Finite n -> a -> b -> c -> d -> e -> f -> g) -> Vector n a -> Vector n b -> Vector n c@@ -1051,7 +1078,7 @@ -- | /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, Storable a, Storable b, Storable c)- => (Int -> a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)+ => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c) izipWithM = V.izipWithM {-# inline izipWithM #-} @@ -1064,7 +1091,7 @@ -- | /O(n)/ Zip the two vectors with a monadic action that also takes -- the element index and ignore the results izipWithM_ :: (Monad m, Storable a, Storable b)- => (Int -> a -> b -> m c) -> Vector n a -> Vector n b -> m ()+ => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m () izipWithM_ = V.izipWithM_ {-# inline izipWithM_ #-} @@ -1129,14 +1156,14 @@ -- | /O(n)/ Yield 'Just' the index of the first element matching the predicate -- or 'Nothing' if no such element exists.-findIndex :: Storable a => (a -> Bool) -> Vector n a -> Maybe Int+findIndex :: Storable 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 :: (Storable a, Eq a) => a -> Vector n a -> Maybe Int+elemIndex :: (Storable a, Eq a) => a -> Vector n a -> Maybe (Finite n) elemIndex = V.elemIndex {-# inline elemIndex #-} @@ -1185,24 +1212,24 @@ {-# inline foldr1' #-} -- | /O(n)/ Left fold (function applied to each element and its index)-ifoldl :: Storable b => (a -> Int -> b -> a) -> a -> Vector n b -> a+ifoldl :: Storable 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' :: Storable b => (a -> Int -> b -> a) -> a -> Vector n b -> a+ifoldl' :: Storable 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 :: Storable a => (Int -> a -> b -> b) -> b -> Vector n a -> b+ifoldr :: Storable 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' :: Storable a => (Int -> a -> b -> b) -> b -> Vector n a -> b+ifoldr' :: Storable a => (Finite n -> a -> b -> b) -> b -> Vector n a -> b ifoldr' = V.ifoldr' {-# inline ifoldr' #-} @@ -1263,26 +1290,26 @@ {-# inline minimumBy #-} -- | /O(n)/ Yield the index of the maximum element of the non-empty vector.-maxIndex :: (Storable a, Ord a, KnownNat n) => Vector (n+1) a -> Int+maxIndex :: (Storable a, Ord a, KnownNat n) => 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 :: (Storable a, KnownNat n)- => (a -> a -> Ordering) -> Vector (n+1) a -> Int+ => (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 :: (Storable a, Ord a, KnownNat n) => Vector (n+1) a -> Int+minIndex :: (Storable a, Ord a, KnownNat n) => 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 :: (Storable a, KnownNat n)- => (a -> a -> Ordering) -> Vector (n+1) a -> Int+ => (a -> a -> Ordering) -> Vector (n+1) a -> Finite (n + 1) minIndexBy = V.minIndexBy {-# inline minIndexBy #-} @@ -1294,7 +1321,7 @@ {-# inline foldM #-} -- | /O(n)/ Monadic fold (action applied to each element and its index)-ifoldM :: (Monad m, Storable b) => (a -> Int -> b -> m a) -> a -> Vector n b -> m a+ifoldM :: (Monad m, Storable b) => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a ifoldM = V.ifoldM {-# inline ifoldM #-} @@ -1312,7 +1339,7 @@ -- | /O(n)/ Monadic fold with strict accumulator (action applied to each -- element and its index) ifoldM' :: (Monad m, Storable b)- => (a -> Int -> b -> m a) -> a -> Vector n b -> m a+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a ifoldM' = V.ifoldM' {-# inline ifoldM' #-} @@ -1331,7 +1358,7 @@ -- | /O(n)/ Monadic fold that discards the result (action applied to -- each element and its index) ifoldM_ :: (Monad m, Storable b)- => (a -> Int -> b -> m a) -> a -> Vector n b -> m ()+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m () ifoldM_ = V.ifoldM_ {-# inline ifoldM_ #-} @@ -1350,7 +1377,7 @@ -- | /O(n)/ Monadic fold with strict accumulator that discards the result -- (action applied to each element and its index) ifoldM'_ :: (Monad m, Storable b)- => (a -> Int -> b -> m a) -> a -> Vector n b -> m ()+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m () ifoldM'_ = V.ifoldM'_ {-# inline ifoldM'_ #-} @@ -1506,6 +1533,41 @@ => [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, Storable 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, Storable 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, Storable 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, Storable 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, Storable a)+ => VSM.MVector n (PrimState m) a+ -> Vector n a+ -> m ()+copy = V.copy -- ** Unsized vectors
vector-sized.cabal view
@@ -1,5 +1,5 @@ name: vector-sized-version: 0.6.1.0+version: 1.0.0.0 synopsis: Size tagged vectors description: Please see README.md homepage: http://github.com/expipiplus1/vector-sized#readme@@ -14,15 +14,26 @@ , changelog.md cabal-version: >=1.10 +-- nice literals are not enabled on GHC 8.4; see+-- https://github.com/DavidM-D/indexed-list-literals/issues/1+ library hs-source-dirs: src exposed-modules: Data.Vector.Sized , Data.Vector.Generic.Sized+ , Data.Vector.Generic.Sized.Internal , Data.Vector.Storable.Sized+ , Data.Vector.Mutable.Sized+ , Data.Vector.Generic.Mutable.Sized+ , Data.Vector.Storable.Mutable.Sized+ , Data.Vector.Generic.Mutable.Sized.Internal build-depends: base >= 4.9 && < 5 , vector >= 0.11 && < 0.13 , deepseq >= 1.1 && < 1.5 , finite-typelits >= 0.1+ , primitive >= 0.5 && < 0.7+ if impl(ghc < 8.3)+ build-depends: indexed-list-literals >= 0.1.0.1 default-language: Haskell2010 source-repository head