summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjophish <>2018-11-08 15:04:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2018-11-08 15:04:00 (GMT)
commitdc374e9998224cb2eec46267aed22f81cdf23568 (patch)
tree2a5b0a49274bed0a8605041cda4f45aacc0d506c
parent0ec823f489ccaf32ac41e1e21f1f2af1da7d2886 (diff)
version 1.1.0.01.1.0.0
-rw-r--r--changelog.md19
-rw-r--r--src/Data/Vector/Generic/Sized.hs28
-rw-r--r--src/Data/Vector/Generic/Sized/Internal.hs48
-rw-r--r--src/Data/Vector/Sized.hs3
-rw-r--r--src/Data/Vector/Storable/Sized.hs4
-rw-r--r--src/Data/Vector/Unboxed/Mutable/Sized.hs477
-rw-r--r--src/Data/Vector/Unboxed/Sized.hs1598
-rw-r--r--vector-sized.cabal8
8 files changed, 2180 insertions, 5 deletions
diff --git a/changelog.md b/changelog.md
index f911f40..ca53323 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,24 @@
# Change Log
+## [1.1.0.0] - 2018-11-08
+
+- Generalise Ix instance
+- Add Unboxed vectors
+- Fiddle extension guarding
+
+Thanks everyone!
+
+## [1.0.5.0] - 2018-10-17
+
+- Add Ix instance
+- Add Comonad instance
+
+Thanks mpilgrem and KingoftheHomeless
+
+## [1.0.4.1] - 2018-09-04
+
+- Fix compilation on ghc 8.6.
+
## [1.0.4.0] - 2018-07-14
- Add Monad instance for boxed vectors.
diff --git a/src/Data/Vector/Generic/Sized.hs b/src/Data/Vector/Generic/Sized.hs
index cd1443b..848e2fc 100644
--- a/src/Data/Vector/Generic/Sized.hs
+++ b/src/Data/Vector/Generic/Sized.hs
@@ -14,6 +14,10 @@
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE CPP #-}
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE NoStarIsType #-}
+#endif
+
{-|
This module reexports the functionality in 'Data.Vector.Generic' which maps well
to explicity sized vectors.
@@ -257,6 +261,7 @@ import Control.Monad.Primitive
import Foreign.Storable
import Data.Data
import Data.Functor.Classes
+import Control.Comonad
import Foreign.Ptr (castPtr)
import Data.Semigroup
import Text.Read.Lex
@@ -313,6 +318,29 @@ instance KnownNat n => Monad (Vector Boxed.Vector n) where
xs >>= f = imap (\i x -> f x `index` i) xs
(>>) = seq
+-- | Non-empty sized vectors are lawful comonads.
+--
+-- 'extract' is 'head'
+--
+-- 'duplicate' generates all unique sequences of a vector with the same length as it,
+-- using wrap-around.
+--
+-- e.g.
+-- @
+-- duplicate [1,2,3,4,5] = [[1,2,3,4,5], [2,3,4,5,1], [3,4,5,1,2], [4,5,1,2,3], [5,1,2,3,4]]
+-- @
+instance (KnownNat n, n ~ (1 + m)) => Comonad (Vector Boxed.Vector n) where
+ extract = head
+ extend f r@(Vector v) = Vector $ VG.generate len (\i -> f (Vector (VG.slice i len v')))
+ where
+ v' = v VG.++ VG.init v
+ len = length r
+
+instance (KnownNat n, n ~ (1 + m)) => ComonadApply (Vector Boxed.Vector n) where
+ (<@>) = (<*>)
+ (<@) = (<*)
+ (@>) = (*>)
+
-- | 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'
diff --git a/src/Data/Vector/Generic/Sized/Internal.hs b/src/Data/Vector/Generic/Sized/Internal.hs
index ccfba86..ed63ba8 100644
--- a/src/Data/Vector/Generic/Sized/Internal.hs
+++ b/src/Data/Vector/Generic/Sized/Internal.hs
@@ -2,6 +2,7 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
+{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE KindSignatures #-}
{-# OPTIONS_HADDOCK not-home #-}
@@ -11,11 +12,15 @@ module Data.Vector.Generic.Sized.Internal
) where
import Control.DeepSeq (NFData)
-import Data.Data
-import Data.Functor.Classes
-import Foreign.Storable
+import Data.Data (Data, Typeable)
+import Data.Functor.Classes (Eq1, Ord1, Show1)
+import Data.Vector as V (and, foldl', null, zipWith, zipWith3)
+import qualified Data.Vector.Generic as VG (Vector, convert, empty, fromList,
+ toList)
+import GHC.Arr (Ix (inRange, range, unsafeIndex,
+ unsafeRangeSize))
import GHC.Generics (Generic)
-import GHC.TypeLits
+import GHC.TypeLits (Nat)
-- | A wrapper to tag vectors with a type level length.
--
@@ -26,3 +31,38 @@ newtype Vector v (n :: Nat) a = Vector (v a)
, Show1, Eq1, Ord1
, Data, Typeable
)
+
+instance (Ix a, Ord (v a), VG.Vector v a) => Ix (Vector v n a) where
+
+ -- range is consistent with range :: ((a,..,a), (a,..,a)) -> [(a,..,a)]
+ range (Vector l, Vector u) = Vector <$> enumerate ranges
+ where
+ ranges = V.zipWith (curry range) lc uc
+ lc = VG.convert l
+ uc = VG.convert u
+ enumerate v
+ | V.null v = [VG.empty]
+ | otherwise = map VG.fromList $ enumerate' (VG.toList v)
+ enumerate' [] = [[]]
+ enumerate' (xs:xss) = [ x : xs' | x <- xs, xs' <- enumerate' xss ]
+
+ -- index/unsafeIndex is consistent with
+ -- index :: ((a,..,a), (a,..,a)) -> (a,..,a) -> Int
+ unsafeIndex (Vector l, Vector u) (Vector i) = V.foldl' f 0 v
+ where
+ f acc (index', rangeSize') = acc * rangeSize' + index'
+ v = V.zipWith3 indexAndRangeSize lc uc ic
+ lc = VG.convert l
+ uc = VG.convert u
+ ic = VG.convert i
+ indexAndRangeSize l' u' i' = let b' = (l', u')
+ in (unsafeIndex b' i', unsafeRangeSize b')
+
+ -- i is in range (l, u) if, and only if, that is true for all elements,
+ -- element-by-element
+ inRange (Vector l, Vector u) (Vector i) =
+ V.and $ V.zipWith3 (curry inRange) lc uc ic
+ where
+ lc = VG.convert l
+ uc = VG.convert u
+ ic = VG.convert i
diff --git a/src/Data/Vector/Sized.hs b/src/Data/Vector/Sized.hs
index cfb3b63..65c4bee 100644
--- a/src/Data/Vector/Sized.hs
+++ b/src/Data/Vector/Sized.hs
@@ -6,6 +6,9 @@
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE CPP #-}
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE NoStarIsType #-}
+#endif
{-|
This module re-exports the functionality in 'Data.Vector.Generic.Sized'
diff --git a/src/Data/Vector/Storable/Sized.hs b/src/Data/Vector/Storable/Sized.hs
index 8a10ba1..9cb3436 100644
--- a/src/Data/Vector/Storable/Sized.hs
+++ b/src/Data/Vector/Storable/Sized.hs
@@ -7,6 +7,10 @@
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE CPP #-}
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE NoStarIsType #-}
+#endif
+
{-|
This module re-exports the functionality in 'Data.Vector.Generic.Sized'
specialized to 'Data.Vector.Storable'
diff --git a/src/Data/Vector/Unboxed/Mutable/Sized.hs b/src/Data/Vector/Unboxed/Mutable/Sized.hs
new file mode 100644
index 0000000..8493c8f
--- /dev/null
+++ b/src/Data/Vector/Unboxed/Mutable/Sized.hs
@@ -0,0 +1,477 @@
+{-# 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.Unboxed.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.Unboxed.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
+ -- * Unbox
+ , Unbox
+ ) where
+
+import qualified Data.Vector.Generic.Mutable.Sized as VGM
+import qualified Data.Vector.Unboxed.Mutable as VSM
+import Data.Vector.Unboxed (Unbox)
+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.Unbox.Mutable'
+type MVector = VGM.MVector VSM.MVector
+
+-- * Accessors
+
+-- ** Length information
+
+-- | /O(1)/ Yield the length of the mutable vector as an 'Int'.
+length :: forall n s a. (KnownNat n)
+ => MVector n s a -> Int
+length = VGM.length
+{-# inline length #-}
+
+-- | /O(1)/ Yield the length of the mutable vector as a 'Proxy'.
+length' :: forall n s a. ()
+ => MVector n s a -> Proxy n
+length' = VGM.length'
+{-# inline length' #-}
+
+-- | /O(1)/ Check whether the mutable vector is empty
+null :: forall n s a. (KnownNat n)
+ => MVector n s a -> Bool
+null = VGM.null
+{-# inline null #-}
+
+-- ** Extracting subvectors
+
+-- | /O(1)/ Yield a slice of the mutable vector without copying it with an
+-- inferred length argument.
+slice :: forall i n k s a p. (KnownNat i, KnownNat n, Unbox 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, Unbox 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. Unbox 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. Unbox 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, Unbox 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, Unbox 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, Unbox 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, Unbox 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, Unbox 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, Unbox 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. Unbox 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, Unbox 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, Unbox 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, Unbox 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, Unbox 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, Unbox 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, Unbox 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, Unbox 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, Unbox 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, Unbox 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, Unbox a) => MVector n (PrimState m) a -> m ()
+clear = VGM.clear
+{-# inline clear #-}
+
+-- * Accessing individual elements
+
+-- | /O(1)/ Yield the element at a given type-safe position using 'Finite'.
+read :: forall n m a. (PrimMonad m, Unbox a)
+ => MVector n (PrimState m) a -> Finite n -> m a
+read = VGM.read
+{-# inline read #-}
+
+-- | /O(1)/ Yield the element at a given type-safe position using 'Proxy'.
+read' :: forall n k a m p. (KnownNat k, PrimMonad m, Unbox a)
+ => MVector (n+k+1) (PrimState m) a -> p k -> m a
+read' = VGM.read'
+{-# inline read' #-}
+
+-- | /O(1)/ Yield the element at a given 'Int' position without bounds
+-- checking.
+unsafeRead :: forall n a m. (PrimMonad m, Unbox a)
+ => MVector n (PrimState m) a -> Int -> m a
+unsafeRead = VGM.unsafeRead
+{-# inline unsafeRead #-}
+
+-- | /O(1)/ Replace the element at a given type-safe position using 'Finite'.
+write :: forall n m a. (PrimMonad m, Unbox a)
+ => MVector n (PrimState m) a -> Finite n -> a -> m ()
+write = VGM.write
+{-# inline write #-}
+
+-- | /O(1)/ Replace the element at a given type-safe position using 'Proxy'.
+write' :: forall n k a m p. (KnownNat k, PrimMonad m, Unbox a)
+ => MVector (n+k+1) (PrimState m) a -> p k -> a -> m ()
+write' = VGM.write'
+{-# inline write' #-}
+
+-- | /O(1)/ Replace the element at a given 'Int' position without bounds
+-- checking.
+unsafeWrite :: forall n m a. (PrimMonad m, Unbox a)
+ => MVector n (PrimState m) a -> Int -> a -> m ()
+unsafeWrite = VGM.unsafeWrite
+{-# inline unsafeWrite #-}
+
+-- | /O(1)/ Modify the element at a given type-safe position using 'Finite'.
+modify :: forall n m a. (PrimMonad m, Unbox a)
+ => MVector n (PrimState m) a -> (a -> a) -> Finite n -> m ()
+modify = VGM.modify
+{-# inline modify #-}
+
+-- | /O(1)/ Modify the element at a given type-safe position using 'Proxy'.
+modify' :: forall n k a m p. (KnownNat k, PrimMonad m, Unbox a)
+ => MVector (n+k+1) (PrimState m) a -> (a -> a) -> p k -> m ()
+modify' = VGM.modify'
+{-# inline modify' #-}
+
+-- | /O(1)/ Modify the element at a given 'Int' position without bounds
+-- checking.
+unsafeModify :: forall n m a. (PrimMonad m, Unbox 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. (PrimMonad m, Unbox 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. (PrimMonad m, Unbox a)
+ => MVector n (PrimState m) a -> Int -> Int -> m ()
+unsafeSwap = VGM.unsafeSwap
+{-# inline unsafeSwap #-}
+
+-- | /O(1)/ Replace the element at a given type-safe position and return
+-- the old element, using 'Finite'.
+exchange :: forall n m a. (PrimMonad m, Unbox a)
+ => MVector n (PrimState m) a -> Finite n -> a -> m a
+exchange = VGM.exchange
+{-# inline exchange #-}
+
+-- | /O(1)/ Replace the element at a given type-safe position and return
+-- the old element, using 'Finite'.
+exchange' :: forall n k a m p. (KnownNat k, PrimMonad m, Unbox a)
+ => MVector (n+k+1) (PrimState m) a -> p k -> a -> m a
+exchange' = VGM.exchange'
+{-# inline exchange' #-}
+
+-- | /O(1)/ Replace the element at a given 'Int' position and return
+-- the old element. No bounds checks are performed.
+unsafeExchange :: forall n m a. (PrimMonad m, Unbox 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. (Ord e, PrimMonad m, Unbox 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, Unbox 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, Unbox 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, Unbox 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, Unbox a)
+ => MVector n (PrimState m) a -- ^ target
+ -> MVector n (PrimState m) a -- ^ source
+ -> m ()
+move = VGM.move
+{-# inline move #-}
+
+-- | Convert a 'Data.Vector.Unbox.Mutable.MVector' into
+-- a 'Data.Vector.Unbox.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.Unbox.Mutable.MVector'.
+toSized :: forall n a s. (KnownNat n, Unbox a)
+ => VSM.MVector s a -> Maybe (MVector n s a)
+toSized = VGM.toSized
+{-# inline toSized #-}
+
+-- | Takes a 'Data.Vector.Unbox.Mutable.MVector' and returns
+-- a continuation providing a 'Data.Vector.Unbox.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.Unbox.Mutable.MVector' into
+-- a 'Data.Vector.Unbox.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.Unbox.Mutable.MVector'.
+withSized :: forall s a r. Unbox a
+ => VSM.MVector s a -> (forall n. KnownNat n => MVector n s a -> r) -> r
+withSized = VGM.withSized
+{-# inline withSized #-}
+
+-- | Convert a 'Data.Vector.Unbox.Mutable.Sized.MVector' into a
+-- 'Data.Vector.Unbox.Mutable.MVector'.
+--
+-- Note that this does no copying; the returned
+-- 'Data.Vector.Unbox.Mutable.MVector' is a reference to the exact same
+-- vector in memory as the given one, and any modifications to it are also
+-- reflected in the given 'MVector'.
+fromSized :: MVector n s a -> VSM.MVector s a
+fromSized = VGM.fromSized
+{-# inline fromSized #-}
+
+
diff --git a/src/Data/Vector/Unboxed/Sized.hs b/src/Data/Vector/Unboxed/Sized.hs
new file mode 100644
index 0000000..20ad638
--- /dev/null
+++ b/src/Data/Vector/Unboxed/Sized.hs
@@ -0,0 +1,1598 @@
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE CPP #-}
+
+{-|
+This module re-exports the functionality in 'Data.Vector.Generic.Sized'
+ specialized to 'Data.Vector.Unboxed'
+
+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.Unboxed.Sized
+ ( Vector
+ , VUM.MVector
+ -- * Accessors
+ -- ** Length information
+ , length
+ , length'
+ , knownLength
+ , knownLength'
+ -- ** Indexing
+ , index
+ , index'
+ , unsafeIndex
+ , head
+ , last
+ -- ** Monadic indexing
+ , indexM
+ , indexM'
+ , unsafeIndexM
+ , headM
+ , lastM
+ -- ** Extracting subvectors (slicing)
+ , slice
+ , slice'
+ , init
+ , tail
+ , take
+ , take'
+ , drop
+ , drop'
+ , splitAt
+ , splitAt'
+ -- * Construction
+ -- ** Initialization
+ , empty
+ , singleton
+ , fromTuple
+ , replicate
+ , replicate'
+ , generate
+ , generate'
+ , iterateN
+ , iterateN'
+ -- ** Monadic initialization
+ , replicateM
+ , replicateM'
+ , generateM
+ , generateM'
+ -- ** Unfolding
+ , unfoldrN
+ , unfoldrN'
+ -- ** Enumeration
+ , enumFromN
+ , enumFromN'
+ , enumFromStepN
+ , enumFromStepN'
+ -- ** Concatenation
+ , cons
+ , snoc
+ , (++)
+ -- ** Restricting memory usage
+ , force
+ -- * Modifying vectors
+ -- ** Bulk updates
+ , (//)
+ , update
+ , update_
+ , unsafeUpd
+ , unsafeUpdate
+ , unsafeUpdate_
+ -- ** Accumulations
+ , accum
+ , accumulate
+ , accumulate_
+ , unsafeAccum
+ , unsafeAccumulate
+ , unsafeAccumulate_
+ -- ** Permutations
+ , reverse
+ , backpermute
+ , unsafeBackpermute
+ -- * Lenses
+ , ix
+ , _head
+ , _last
+ -- * Elementwise operations
+ -- ** Indexing
+ , indexed
+ -- ** Mapping
+ , map
+ , imap
+ , concatMap
+ -- ** Monadic mapping
+ , mapM
+ , imapM
+ , mapM_
+ , imapM_
+ , forM
+ , forM_
+ -- ** Zipping
+ , zipWith
+ , zipWith3
+ , zipWith4
+ , zipWith5
+ , zipWith6
+ , izipWith
+ , izipWith3
+ , izipWith4
+ , izipWith5
+ , izipWith6
+ , zip
+ , zip3
+ , zip4
+ , zip5
+ , zip6
+ -- ** Monadic zipping
+ , zipWithM
+ , izipWithM
+ , zipWithM_
+ , izipWithM_
+ -- ** Unzipping
+ , unzip
+ , unzip3
+ , unzip4
+ , unzip5
+ , unzip6
+ -- * Working with predicates
+ -- ** Searching
+ , elem
+ , notElem
+ , find
+ , findIndex
+ , elemIndex
+ -- * Folding
+ , foldl
+ , foldl1
+ , foldl'
+ , foldl1'
+ , foldr
+ , foldr1
+ , foldr'
+ , foldr1'
+ , ifoldl
+ , ifoldl'
+ , ifoldr
+ , ifoldr'
+ -- ** Specialised folds
+ , all
+ , any
+ , and
+ , or
+ , sum
+ , product
+ , maximum
+ , maximumBy
+ , minimum
+ , minimumBy
+ , maxIndex
+ , maxIndexBy
+ , minIndex
+ , minIndexBy
+ -- ** Monadic folds
+ , foldM
+ , ifoldM
+ , fold1M
+ , foldM'
+ , ifoldM'
+ , fold1M'
+ , foldM_
+ , ifoldM_
+ , fold1M_
+ , foldM'_
+ , ifoldM'_
+ , fold1M'_
+ -- ** Monadic sequencing
+ , sequence
+ , sequence_
+ -- * Prefix sums (scans)
+ , prescanl
+ , prescanl'
+ , postscanl
+ , postscanl'
+ , scanl
+ , scanl'
+ , scanl1
+ , scanl1'
+ , prescanr
+ , prescanr'
+ , postscanr
+ , postscanr'
+ , scanr
+ , scanr'
+ , scanr1
+ , scanr1'
+ -- * Conversions
+ -- ** Lists
+ , toList
+ , fromList
+ , fromListN
+ , fromListN'
+ , withSizedList
+ -- ** Mutable vectors
+ , freeze
+ , thaw
+ , copy
+ , unsafeFreeze
+ , unsafeThaw
+ -- ** Unsized Vectors
+ , toSized
+ , withSized
+ , fromSized
+ , withVectorUnsafe
+ -- ** Unbox
+ , Unbox
+ ) where
+
+import qualified Data.Vector.Generic.Sized as V
+import qualified Data.Vector.Unboxed as VU
+import Data.IndexedListLiterals (IndexedListLiterals)
+import qualified Data.Vector.Unboxed.Mutable.Sized as VUM
+import GHC.TypeLits
+import Data.Finite
+import Data.Proxy
+import Control.Monad.Primitive
+import Data.Vector.Unboxed (Unbox)
+import Prelude hiding ( length, null,
+ replicate, (++), concat,
+ head, last,
+ init, tail, take, drop, splitAt, reverse,
+ map, concat, concatMap,
+ zipWith, zipWith3, zip, zip3, unzip, unzip3,
+ filter, takeWhile, dropWhile, span, break,
+ elem, notElem,
+ foldl, foldl1, foldr, foldr1,
+ all, any, and, or, sum, product, maximum, minimum,
+ scanl, scanl1, scanr, scanr1,
+ enumFromTo, enumFromThenTo,
+ mapM, mapM_, sequence, sequence_,
+ showsPrec )
+
+-- | 'Data.Vector.Generic.Sized.Vector' specialized to use
+-- 'Data.Vector.Unboxed'
+type Vector = V.Vector VU.Vector
+
+-- | /O(1)/ Yield the length of the vector as an 'Int'. This is more like
+-- 'natVal' than 'Data.Vector.length', extracting the value from the 'KnownNat'
+-- instance and not looking at the vector itself.
+length :: forall n a. KnownNat n
+ => Vector n a -> Int
+length = V.length
+{-# inline length #-}
+
+-- | /O(1)/ Yield the length of the vector as a 'Proxy'. This function
+-- doesn't /do/ anything; it merely allows the size parameter of the vector
+-- to be passed around as a 'Proxy'.
+length' :: forall n a.
+ Vector n a -> Proxy n
+length' = V.length'
+{-# inline length' #-}
+
+-- | /O(1)/ Reveal a 'KnownNat' instance for a vector's length, determined
+-- at runtime.
+knownLength :: forall n a r. Unbox 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. Unbox 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. Unbox a
+ => Vector n a -> Finite n -> a
+index = V.index
+{-# inline index #-}
+
+-- | /O(1)/ Safe indexing using a 'Proxy'.
+index' :: forall n m a p. (KnownNat n, Unbox a)
+ => Vector (n+m+1) a -> p n -> a
+index' = V.index'
+{-# inline index' #-}
+
+-- | /O(1)/ Indexing using an Int without bounds checking.
+unsafeIndex :: forall n a. Unbox a
+ => Vector n a -> Int -> a
+unsafeIndex = V.unsafeIndex
+{-# inline unsafeIndex #-}
+
+-- | /O(1)/ Yield the first element of a non-empty vector.
+head :: forall n a. (Unbox a)
+ => Vector (1+n) a -> a
+head = V.head
+{-# inline head #-}
+
+-- | /O(1)/ Yield the last element of a non-empty vector.
+last :: forall n a. (Unbox a)
+ => Vector (n+1) a -> a
+last = V.last
+{-# inline last #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) an arbitrary element by its index.
+ix :: forall n a f. (Unbox a, Functor f)
+ => Finite n -> (a -> f a) -> Vector n a -> f (Vector n a)
+ix = V.ix
+{-# inline ix #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) the first element of a non-empty vector.
+_head :: forall n a f. (Unbox a, Functor f)
+ => (a -> f a) -> Vector (1+n) a -> f (Vector (1+n) a)
+_head = V._head
+{-# inline _head #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) the last element of a non-empty vector.
+_last :: forall n a f. (Unbox a, Functor f)
+ => (a -> f a) -> Vector (n+1) a -> f (Vector (n+1) a)
+_last = V._last
+{-# inline _last #-}
+
+
+-- | /O(1)/ Safe indexing in a monad. See the documentation for 'VG.indexM' for
+-- an explanation of why this is useful.
+indexM :: forall n a m. (Unbox a, Monad m)
+ => Vector n a -> Finite n -> m a
+indexM = V.indexM
+{-# inline indexM #-}
+
+-- | /O(1)/ Safe indexing in a monad using a 'Proxy'. See the documentation for
+-- 'VG.indexM' for an explanation of why this is useful.
+indexM' :: forall n k a m p. (KnownNat n, Unbox a, Monad m)
+ => Vector (n+k) a -> p n -> m a
+indexM' = V.indexM'
+{-# inline indexM' #-}
+
+-- | /O(1)/ Indexing using an Int without bounds checking. See the
+-- documentation for 'VG.indexM' for an explanation of why this is useful.
+unsafeIndexM :: forall n a m. (Unbox a, Monad m)
+ => Vector n a -> Int -> m a
+unsafeIndexM = V.unsafeIndexM
+{-# inline unsafeIndexM #-}
+
+-- | /O(1)/ Yield the first element of a non-empty vector in a monad. See the
+-- documentation for 'VG.indexM' for an explanation of why this is useful.
+headM :: forall n a m. (Unbox a, Monad m)
+ => Vector (1+n) a -> m a
+headM = V.headM
+{-# inline headM #-}
+
+-- | /O(1)/ Yield the last element of a non-empty vector in a monad. See the
+-- documentation for 'VG.indexM' for an explanation of why this is useful.
+lastM :: forall n a m. (Unbox a, Monad m)
+ => Vector (n+1) a -> m a
+lastM = V.lastM
+{-# inline lastM #-}
+
+-- | /O(1)/ Yield a slice of the vector without copying it with an inferred
+-- length argument.
+slice :: forall i n m a p. (KnownNat i, KnownNat n, Unbox a)
+ => p i -- ^ starting index
+ -> Vector (i+n+m) a
+ -> Vector n a
+slice = V.slice
+{-# inline slice #-}
+
+-- | /O(1)/ Yield a slice of the vector without copying it with an explicit
+-- length argument.
+slice' :: forall i n m a p. (KnownNat i, KnownNat n, Unbox a)
+ => p i -- ^ starting index
+ -> p n -- ^ length
+ -> Vector (i+n+m) a
+ -> Vector n a
+slice' = V.slice'
+{-# inline slice' #-}
+
+-- | /O(1)/ Yield all but the last element of a non-empty vector without
+-- copying.
+init :: forall n a. (Unbox a)
+ => Vector (n+1) a -> Vector n a
+init = V.init
+{-# inline init #-}
+
+-- | /O(1)/ Yield all but the first element of a non-empty vector without
+-- copying.
+tail :: forall n a. (Unbox a)
+ => Vector (1+n) a -> Vector n a
+tail = V.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 m a. (KnownNat n, Unbox a)
+ => Vector (n+m) a -> Vector n a
+take = V.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 m a p. (KnownNat n, Unbox a)
+ => p n -> Vector (n+m) a -> Vector n a
+take' = V.take'
+{-# inline take' #-}
+
+-- | /O(1)/ Yield all but the the first n elements. The given vector must
+-- contain at least this many elements The length of the resultant vector is
+-- inferred from the type.
+drop :: forall n m a. (KnownNat n, Unbox a)
+ => Vector (n+m) a -> Vector m a
+drop = V.drop
+{-# inline drop #-}
+
+-- | /O(1)/ Yield all but the the first n elements. The given vector must
+-- contain at least this many elements The length of the resultant vector is
+-- givel explicitly as a 'Proxy' argument.
+drop' :: forall n m a p. (KnownNat n, Unbox a)
+ => p n -> Vector (n+m) a -> Vector m a
+drop' = V.drop'
+{-# inline drop' #-}
+
+-- | /O(1)/ Yield the first n elements paired with the remainder without copying.
+-- The lengths of the resultant vector are inferred from the type.
+splitAt :: forall n m a. (KnownNat n, Unbox a)
+ => Vector (n+m) a -> (Vector n a, Vector m a)
+splitAt = V.splitAt
+{-# inline splitAt #-}
+
+-- | /O(1)/ Yield the first n elements paired with the remainder without
+-- copying. The length of the first resultant vector is passed explicitly as a
+-- 'Proxy' argument.
+splitAt' :: forall n m a p. (KnownNat n, Unbox a)
+ => p n -> Vector (n+m) a -> (Vector n a, Vector m a)
+splitAt' = V.splitAt'
+{-# inline splitAt' #-}
+
+--------------------------------------------------------------------------------
+-- * Construction
+--------------------------------------------------------------------------------
+
+--
+-- ** Initialization
+--
+
+-- | /O(1)/ Empty vector.
+empty :: forall a. (Unbox a)
+ => Vector 0 a
+empty = V.empty
+{-# inline empty #-}
+
+-- | /O(1)/ Vector with exactly one element.
+singleton :: forall a. (Unbox a)
+ => a -> Vector 1 a
+singleton = V.singleton
+{-# inline singleton #-}
+
+-- | /O(n)/ Construct a vector in a type safe manner
+-- fromTuple (1,2) :: Vector 2 Int
+-- fromTuple ("hey", "what's", "going", "on") :: Vector 4 String
+fromTuple :: forall a input length.
+ (Unbox a, IndexedListLiterals input length a, KnownNat length)
+ => input -> Vector length a
+fromTuple = V.fromTuple
+{-# inline fromTuple #-}
+
+-- | /O(n)/ Construct a vector with the same element in each position where the
+-- length is inferred from the type.
+replicate :: forall n a. (KnownNat n, Unbox a)
+ => a -> Vector n a
+replicate = V.replicate
+{-# inline replicate #-}
+
+-- | /O(n)/ Construct a vector with the same element in each position where the
+-- length is given explicitly as a 'Proxy' argument.
+replicate' :: forall n a p. (KnownNat n, Unbox a)
+ => p n -> a -> Vector n a
+replicate' = V.replicate'
+{-# inline replicate' #-}
+
+-- | /O(n)/ construct a vector of the given length by applying the function to
+-- each index where the length is inferred from the type.
+generate :: forall n a. (KnownNat n, Unbox 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, Unbox a)
+ => p n -> (Finite n -> a) -> Vector n a
+generate' = V.generate'
+{-# inline generate' #-}
+
+-- | /O(n)/ Apply function n times to value. Zeroth element is original value.
+-- The length is inferred from the type.
+iterateN :: forall n a. (KnownNat n, Unbox a)
+ => (a -> a) -> a -> Vector n a
+iterateN = V.iterateN
+{-# inline iterateN #-}
+
+-- | /O(n)/ Apply function n times to value. Zeroth element is original value.
+-- The length is given explicitly as a 'Proxy' argument.
+iterateN' :: forall n a p. (KnownNat n, Unbox a)
+ => p n -> (a -> a) -> a -> Vector n a
+iterateN' = V.iterateN'
+{-# inline iterateN' #-}
+
+--
+-- ** Monadic initialisation
+--
+
+-- | /O(n)/ Execute the monadic action @n@ times and store the results in a
+-- vector where @n@ is inferred from the type.
+replicateM :: forall n m a. (KnownNat n, Unbox a, Monad m)
+ => m a -> m (Vector n a)
+replicateM = V.replicateM
+{-# inline replicateM #-}
+
+-- | /O(n)/ Execute the monadic action @n@ times and store the results in a
+-- vector where @n@ is given explicitly as a 'Proxy' argument.
+replicateM' :: forall n m a p. (KnownNat n, Unbox a, Monad m)
+ => p n -> m a -> m (Vector n a)
+replicateM' = V.replicateM'
+{-# inline replicateM' #-}
+
+-- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
+-- each index where n is inferred from the type.
+generateM :: forall n m a. (KnownNat n, Unbox a, Monad m)
+ => (Finite n -> m a) -> m (Vector n a)
+generateM = V.generateM
+{-# inline generateM #-}
+
+-- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
+-- each index where n is given explicitly as a 'Proxy' argument.
+generateM' :: forall n m a p. (KnownNat n, Unbox a, Monad m)
+ => p n -> (Finite n -> m a) -> m (Vector n a)
+generateM' = V.generateM'
+{-# inline generateM' #-}
+
+--
+-- ** Unfolding
+--
+
+-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
+-- the generator function to the a seed. The length, @n@, is inferred from the
+-- type.
+unfoldrN :: forall n a b. (KnownNat n, Unbox a)
+ => (b -> (a, b)) -> b -> Vector n a
+unfoldrN = V.unfoldrN
+{-# inline unfoldrN #-}
+
+-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
+-- the generator function to the a seed. The length, @n@, is given explicitly
+-- as a 'Proxy' argument.
+unfoldrN' :: forall n a b p. (KnownNat n, Unbox a)
+ => p n -> (b -> (a, b)) -> b -> Vector n a
+unfoldrN' = V.unfoldrN'
+{-# inline unfoldrN' #-}
+
+--
+-- ** Enumeration
+--
+
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
+-- etc. The length, @n@, is inferred from the type.
+enumFromN :: forall n a. (KnownNat n, Unbox a, Num a)
+ => a -> Vector n a
+enumFromN = V.enumFromN
+{-# inline enumFromN #-}
+
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
+-- etc. The length, @n@, is given explicitly as a 'Proxy' argument.
+enumFromN' :: forall n a p. (KnownNat n, Unbox a, Num a)
+ => a -> p n -> Vector n a
+enumFromN' = V.enumFromN'
+{-# inline enumFromN' #-}
+
+-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
+-- @x+y+y@ etc. The length, @n@, is inferred from the type.
+enumFromStepN :: forall n a. (KnownNat n, Unbox a, Num a)
+ => a -> a -> Vector n a
+enumFromStepN = V.enumFromStepN
+{-# inline enumFromStepN #-}
+
+-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
+-- @x+y+y@ etc. The length, @n@, is given explicitly as a 'Proxy' argument.
+enumFromStepN' :: forall n a p. (KnownNat n, Unbox a, Num a)
+ => a -> a -> p n -> Vector n a
+enumFromStepN' = V.enumFromStepN'
+{-# inline enumFromStepN' #-}
+
+--
+-- ** Concatenation
+--
+
+-- | /O(n)/ Prepend an element.
+cons :: forall n a. Unbox a
+ => a -> Vector n a -> Vector (1+n) a
+cons = V.cons
+{-# inline cons #-}
+
+-- | /O(n)/ Append an element.
+snoc :: forall n a. Unbox a
+ => Vector n a -> a -> Vector (n+1) a
+snoc = V.snoc
+{-# inline snoc #-}
+
+-- | /O(m+n)/ Concatenate two vectors.
+(++) :: forall n m a. Unbox a
+ => Vector n a -> Vector m a -> Vector (n+m) a
+(++) = (V.++)
+{-# inline (++) #-}
+
+--
+-- ** Restricting memory usage
+--
+
+-- | /O(n)/ Yield the argument but force it not to retain any extra memory,
+-- possibly by copying it.
+--
+-- This is especially useful when dealing with slices. For example:
+--
+-- > force (slice 0 2 <huge vector>)
+--
+-- Here, the slice retains a reference to the huge vector. Forcing it creates
+-- a copy of just the elements that belong to the slice and allows the huge
+-- vector to be garbage collected.
+force :: Unbox a => Vector n a -> Vector n a
+force = V.force
+{-# inline force #-}
+
+
+--------------------------------------------------------------------------------
+-- * Modifying vectors
+--------------------------------------------------------------------------------
+
+--
+-- ** Bulk updates
+--
+
+-- | /O(m+n)/ For each pair @(i,a)@ from the list, replace the vector
+-- element at position @i@ by @a@.
+--
+-- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7>
+--
+(//) :: (Unbox a)
+ => Vector m a -- ^ initial vector (of length @m@)
+ -> [(Finite m, a)] -- ^ list of index/value pairs (of length @n@)
+ -> Vector m a
+(//) = (V.//)
+{-# inline (//) #-}
+
+-- | /O(m+n)/ For each pair @(i,a)@ from the vector of index/value pairs,
+-- replace the vector element at position @i@ by @a@.
+--
+-- > update <5,9,2,7> <(2,1),(0,3),(2,8)> = <3,9,8,7>
+--
+update :: (Unbox a)
+ => Vector m a -- ^ initial vector (of length @m@)
+ -> Vector n (Int, a) -- ^ vector of index/value pairs (of length @n@)
+ -> Vector m a
+update = V.update
+{-# inline update #-}
+
+-- | /O(m+n)/ For each index @i@ from the index vector and the
+-- corresponding value @a@ from the value vector, replace the element of the
+-- initial vector at position @i@ by @a@.
+--
+-- > update_ <5,9,2,7> <2,0,2> <1,3,8> = <3,9,8,7>
+--
+-- This function is useful for instances of 'Vector' that cannot store pairs.
+-- Otherwise, 'update' is probably more convenient.
+--
+-- @
+-- update_ xs is ys = 'update' xs ('zip' is ys)
+-- @
+update_ :: Unbox a
+ => Vector m a -- ^ initial vector (of length @m@)
+ -> Vector n Int -- ^ index vector (of length @n@)
+ -> Vector n a -- ^ value vector (of length @n@)
+ -> Vector m a
+update_ = V.update_
+{-# inline update_ #-}
+
+-- | Same as ('//') but without bounds checking.
+unsafeUpd :: (Unbox a)
+ => Vector m a -- ^ initial vector (of length @m@)
+ -> [(Int, a)] -- ^ list of index/value pairs (of length @n@)
+ -> Vector m a
+unsafeUpd = V.unsafeUpd
+{-# inline unsafeUpd #-}
+
+-- | Same as 'update' but without bounds checking.
+unsafeUpdate :: (Unbox a)
+ => Vector m a -- ^ initial vector (of length @m@)
+ -> Vector n (Int, a) -- ^ vector of index/value pairs (of length @n@)
+ -> Vector m a
+unsafeUpdate = V.unsafeUpdate
+{-# inline unsafeUpdate #-}
+
+-- | Same as 'update_' but without bounds checking.
+unsafeUpdate_ :: Unbox a
+ => Vector m a -- ^ initial vector (of length @m@)
+ -> Vector n Int -- ^ index vector (of length @n@)
+ -> Vector n a -- ^ value vector (of length @n@)
+ -> Vector m a
+unsafeUpdate_ = V.unsafeUpdate_
+{-# inline unsafeUpdate_ #-}
+
+--
+-- ** Accumulations
+--
+
+-- | /O(m+n)/ For each pair @(i,b)@ from the list, replace the vector element
+-- @a@ at position @i@ by @f a b@.
+--
+-- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4>
+accum :: Unbox a
+ => (a -> b -> a) -- ^ accumulating function @f@
+ -> Vector m a -- ^ initial vector (of length @m@)
+ -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)
+ -> Vector m a
+accum = V.accum
+{-# inline accum #-}
+
+-- | /O(m+n)/ For each pair @(i,b)@ from the vector of pairs, replace the vector
+-- element @a@ at position @i@ by @f a b@.
+--
+-- > accumulate (+) <5,9,2> <(2,4),(1,6),(0,3),(1,7)> = <5+3, 9+6+7, 2+4>
+accumulate :: (Unbox a, Unbox b)
+ => (a -> b -> a) -- ^ accumulating function @f@
+ -> Vector m a -- ^ initial vector (of length @m@)
+ -> Vector n (Int,b) -- ^ vector of index/value pairs (of length @n@)
+ -> Vector m a
+accumulate = V.accumulate
+{-# inline accumulate #-}
+
+-- | /O(m+n)/ For each index @i@ from the index vector and the
+-- corresponding value @b@ from the the value vector,
+-- replace the element of the initial vector at
+-- position @i@ by @f a b@.
+--
+-- > accumulate_ (+) <5,9,2> <2,1,0,1> <4,6,3,7> = <5+3, 9+6+7, 2+4>
+--
+-- This function is useful for instances of 'Vector' that cannot store pairs.
+-- Otherwise, 'accumulate' is probably more convenient:
+--
+-- @
+-- accumulate_ f as is bs = 'accumulate' f as ('zip' is bs)
+-- @
+accumulate_ :: (Unbox a, Unbox b)
+ => (a -> b -> a) -- ^ accumulating function @f@
+ -> Vector m a -- ^ initial vector (of length @m@)
+ -> Vector n Int -- ^ index vector (of length @n@)
+ -> Vector n b -- ^ value vector (of length @n@)
+ -> Vector m a
+accumulate_ = V.accumulate_
+{-# inline accumulate_ #-}
+
+-- | Same as 'accum' but without bounds checking.
+unsafeAccum :: Unbox a
+ => (a -> b -> a) -- ^ accumulating function @f@
+ -> Vector m a -- ^ initial vector (of length @m@)
+ -> [(Int,b)] -- ^ list of index/value pairs (of length @n@)
+ -> Vector m a
+unsafeAccum = V.unsafeAccum
+{-# inline unsafeAccum #-}
+
+-- | Same as 'accumulate' but without bounds checking.
+unsafeAccumulate :: (Unbox a, Unbox b)
+ => (a -> b -> a) -- ^ accumulating function @f@
+ -> Vector m a -- ^ initial vector (of length @m@)
+ -> Vector n (Int,b) -- ^ vector of index/value pairs (of length @n@)
+ -> Vector m a
+unsafeAccumulate = V.unsafeAccumulate
+{-# inline unsafeAccumulate #-}
+
+-- | Same as 'accumulate_' but without bounds checking.
+unsafeAccumulate_ :: (Unbox a, Unbox b)
+ => (a -> b -> a) -- ^ accumulating function @f@
+ -> Vector m a -- ^ initial vector (of length @m@)
+ -> Vector n Int -- ^ index vector (of length @n@)
+ -> Vector n b -- ^ value vector (of length @n@)
+ -> Vector m a
+unsafeAccumulate_ = V.unsafeAccumulate_
+{-# inline unsafeAccumulate_ #-}
+
+--
+-- ** Permutations
+--
+
+-- | /O(n)/ Reverse a vector
+reverse :: (Unbox a) => Vector n a -> Vector n a
+reverse = V.reverse
+{-# inline reverse #-}
+
+-- | /O(n)/ Yield the vector obtained by replacing each element @i@ of the
+-- index vector by @xs'!'i@. This is equivalent to @'map' (xs'!') is@ but is
+-- often much more efficient.
+--
+-- > backpermute <a,b,c,d> <0,3,2,3,1,0> = <a,d,c,d,b,a>
+backpermute :: Unbox a
+ => Vector m a -- ^ @xs@ value vector
+ -> Vector n Int -- ^ @is@ index vector (of length @n@)
+ -> Vector n a
+backpermute = V.backpermute
+{-# inline backpermute #-}
+
+-- | Same as 'backpermute' but without bounds checking.
+unsafeBackpermute :: Unbox a
+ => Vector m a -- ^ @xs@ value vector
+ -> Vector n Int -- ^ @is@ index vector (of length @n@)
+ -> Vector n a
+unsafeBackpermute = V.unsafeBackpermute
+{-# inline unsafeBackpermute #-}
+
+--------------------------------------------------------------------------------
+-- * Elementwise Operations
+--------------------------------------------------------------------------------
+
+--
+-- ** Indexing
+--
+
+-- | /O(n)/ Pair each element in a vector with its index
+indexed :: (Unbox a, Unbox (Finite n))
+ => Vector n a -> Vector n (Finite n,a)
+indexed = V.indexed
+{-# inline indexed #-}
+
+--
+-- ** Mapping
+--
+
+-- | /O(n)/ Map a function over a vector
+map :: (Unbox a, Unbox b)
+ => (a -> b) -> Vector n a -> Vector n b
+map = V.map
+{-# inline map #-}
+
+-- | /O(n)/ Apply a function to every element of a vector and its index
+imap :: (Unbox a, Unbox b)
+ => (Finite n -> a -> b) -> Vector n a -> Vector n b
+imap = V.imap
+{-# inline imap #-}
+
+-- | /O(n*m)/ Map a function over a vector and concatenate the results. The
+-- function is required to always return the same length vector.
+concatMap :: (Unbox a, Unbox b)
+ => (a -> Vector m b) -> Vector n a -> Vector (n*m) b
+concatMap = V.concatMap
+{-# inline concatMap #-}
+
+--
+-- ** Monadic mapping
+--
+
+-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a
+-- vector of results
+mapM :: (Monad m, Unbox a, Unbox b)
+ => (a -> m b) -> Vector n a -> m (Vector n b)
+mapM = V.mapM
+{-# inline mapM #-}
+
+-- | /O(n)/ Apply the monadic action to every element of a vector and its
+-- index, yielding a vector of results
+imapM :: (Monad m, Unbox a, Unbox b)
+ => (Finite n -> a -> m b) -> Vector n a -> m (Vector n b)
+imapM = V.imapM
+{-# inline imapM #-}
+
+-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the
+-- results
+mapM_ :: (Monad m, Unbox a) => (a -> m b) -> Vector n a -> m ()
+mapM_ = V.mapM_
+{-# inline mapM_ #-}
+
+-- | /O(n)/ Apply the monadic action to every element of a vector and its
+-- index, ignoring the results
+imapM_ :: (Monad m, Unbox a) => (Finite n -> a -> m b) -> Vector n a -> m ()
+imapM_ = V.imapM_
+{-# inline imapM_ #-}
+
+-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a
+-- vector of results. Equvalent to @flip 'mapM'@.
+forM :: (Monad m, Unbox a, Unbox b)
+ => Vector n a -> (a -> m b) -> m (Vector n b)
+forM = V.forM
+{-# inline forM #-}
+
+-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the
+-- results. Equivalent to @flip 'mapM_'@.
+forM_ :: (Monad m, Unbox a) => Vector n a -> (a -> m b) -> m ()
+forM_ = V.forM_
+{-# inline forM_ #-}
+
+--
+-- ** Zipping
+--
+
+-- | /O(n)/ Zip two vectors of the same length with the given function.
+zipWith :: (Unbox a, Unbox b, Unbox c)
+ => (a -> b -> c) -> Vector n a -> Vector n b -> Vector n c
+zipWith = V.zipWith
+{-# inline zipWith #-}
+
+-- | Zip three vectors with the given function.
+zipWith3 :: (Unbox a, Unbox b, Unbox c, Unbox d)
+ => (a -> b -> c -> d) -> Vector n a -> Vector n b -> Vector n c -> Vector n d
+zipWith3 = V.zipWith3
+{-# inline zipWith3 #-}
+
+zipWith4 :: (Unbox a,Unbox b,Unbox c,Unbox d,Unbox e)
+ => (a -> b -> c -> d -> e)
+ -> Vector n a
+ -> Vector n b
+ -> Vector n c
+ -> Vector n d
+ -> Vector n e
+zipWith4 = V.zipWith4
+{-# inline zipWith4 #-}
+
+zipWith5 :: (Unbox a,Unbox b,Unbox c,Unbox d,Unbox e,Unbox f)
+ => (a -> b -> c -> d -> e -> f)
+ -> Vector n a
+ -> Vector n b
+ -> Vector n c
+ -> Vector n d
+ -> Vector n e
+ -> Vector n f
+zipWith5 = V.zipWith5
+{-# inline zipWith5 #-}
+
+zipWith6 :: (Unbox a,Unbox b,Unbox c,Unbox d,Unbox e,Unbox f,Unbox g)
+ => (a -> b -> c -> d -> e -> f -> g)
+ -> Vector n a
+ -> Vector n b
+ -> Vector n c
+ -> Vector n d
+ -> Vector n e
+ -> Vector n f
+ -> Vector n g
+zipWith6 = V.zipWith6
+{-# inline zipWith6 #-}
+
+-- | /O(n)/ Zip two vectors of the same length with a function that also takes
+-- the elements' indices).
+izipWith :: (Unbox a,Unbox b,Unbox c)
+ => (Finite n -> a -> b -> c)
+ -> Vector n a
+ -> Vector n b
+ -> Vector n c
+izipWith = V.izipWith
+{-# inline izipWith #-}
+
+izipWith3 :: (Unbox a,Unbox b,Unbox c,Unbox d)
+ => (Finite n -> a -> b -> c -> d)
+ -> Vector n a
+ -> Vector n b
+ -> Vector n c
+ -> Vector n d
+izipWith3 = V.izipWith3
+{-# inline izipWith3 #-}
+
+izipWith4 :: (Unbox a,Unbox b,Unbox c,Unbox d,Unbox e)
+ => (Finite n -> a -> b -> c -> d -> e)
+ -> Vector n a
+ -> Vector n b
+ -> Vector n c
+ -> Vector n d
+ -> Vector n e
+izipWith4 = V.izipWith4
+{-# inline izipWith4 #-}
+
+izipWith5 :: (Unbox a,Unbox b,Unbox c,Unbox d,Unbox e,Unbox f)
+ => (Finite n -> a -> b -> c -> d -> e -> f)
+ -> Vector n a
+ -> Vector n b
+ -> Vector n c
+ -> Vector n d
+ -> Vector n e
+ -> Vector n f
+izipWith5 = V.izipWith5
+{-# inline izipWith5 #-}
+
+izipWith6 :: (Unbox a,Unbox b,Unbox c,Unbox d,Unbox e,Unbox f,Unbox g)
+ => (Finite n -> a -> b -> c -> d -> e -> f -> g)
+ -> Vector n a
+ -> Vector n b
+ -> Vector n c
+ -> Vector n d
+ -> Vector n e
+ -> Vector n f
+ -> Vector n g
+izipWith6 = V.izipWith6
+{-# inline izipWith6 #-}
+
+-- | /O(n)/ Zip two vectors of the same length
+zip :: (Unbox a, Unbox b)
+ => Vector n a -> Vector n b -> Vector n (a, b)
+zip = V.zip
+{-# inline zip #-}
+
+zip3 :: (Unbox a, Unbox b, Unbox c)
+ => Vector n a -> Vector n b -> Vector n c -> Vector n (a, b, c)
+zip3 = V.zip3
+{-# inline zip3 #-}
+
+zip4 :: (Unbox a,Unbox b,Unbox c,Unbox d)
+ => Vector n a
+ -> Vector n b
+ -> Vector n c
+ -> Vector n d
+ -> Vector n (a,b,c,d)
+zip4 = V.zip4
+{-# inline zip4 #-}
+
+zip5 :: (Unbox a,Unbox b,Unbox c,Unbox d,Unbox e)
+ => Vector n a
+ -> Vector n b
+ -> Vector n c
+ -> Vector n d
+ -> Vector n e
+ -> Vector n (a,b,c,d,e)
+zip5 = V.zip5
+{-# inline zip5 #-}
+
+zip6 :: (Unbox a,Unbox b,Unbox c,Unbox d,Unbox e,Unbox f)
+ => Vector n a
+ -> Vector n b
+ -> Vector n c
+ -> Vector n d
+ -> Vector n e
+ -> Vector n f
+ -> Vector n (a,b,c,d,e,f)
+zip6 = V.zip6
+{-# inline zip6 #-}
+
+--
+-- ** Monadic zipping
+--
+
+-- | /O(n)/ Zip the two vectors of the same length with the monadic action and
+-- yield a vector of results
+zipWithM :: (Monad m, Unbox a, Unbox b, Unbox c)
+ => (a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)
+zipWithM = V.zipWithM
+{-# inline zipWithM #-}
+
+-- | /O(n)/ Zip the two vectors with a monadic action that also takes the
+-- element index and yield a vector of results
+izipWithM :: (Monad m, Unbox a, Unbox b, Unbox c)
+ => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)
+izipWithM = V.izipWithM
+{-# inline izipWithM #-}
+
+-- | /O(n)/ Zip the two vectors with the monadic action and ignore the results
+zipWithM_ :: (Monad m, Unbox a, Unbox b)
+ => (a -> b -> m c) -> Vector n a -> Vector n b -> m ()
+zipWithM_ = V.zipWithM_
+{-# inline zipWithM_ #-}
+
+-- | /O(n)/ Zip the two vectors with a monadic action that also takes
+-- the element index and ignore the results
+izipWithM_ :: (Monad m, Unbox a, Unbox b)
+ => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m ()
+izipWithM_ = V.izipWithM_
+{-# inline izipWithM_ #-}
+
+-- Unzipping
+-- ---------
+
+-- | /O(min(m,n))/ Unzip a vector of pairs.
+unzip :: (Unbox a, Unbox b)
+ => Vector n (a, b) -> (Vector n a, Vector n b)
+unzip = V.unzip
+{-# inline unzip #-}
+
+unzip3 :: (Unbox a, Unbox b, Unbox c)
+ => Vector n (a, b, c) -> (Vector n a, Vector n b, Vector n c)
+unzip3 = V.unzip3
+{-# inline unzip3 #-}
+
+unzip4 :: (Unbox a, Unbox b, Unbox c, Unbox d)
+ => Vector n (a, b, c, d) -> (Vector n a, Vector n b, Vector n c, Vector n d)
+unzip4 = V.unzip4
+{-# inline unzip4 #-}
+
+unzip5 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e)
+ => Vector n (a, b, c, d, e) -> (Vector n a, Vector n b, Vector n c, Vector n d, Vector n e)
+unzip5 = V.unzip5
+{-# inline unzip5 #-}
+
+unzip6 :: (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f)
+ => Vector n (a, b, c, d, e, f) -> (Vector n a, Vector n b, Vector n c, Vector n d, Vector n e, Vector n f)
+unzip6 = V.unzip6
+{-# inline unzip6 #-}
+
+--------------------------------------------------------------------------------
+-- * Working with predicates
+--------------------------------------------------------------------------------
+
+--
+-- ** Searching
+--
+
+
+infix 4 `elem`
+-- | /O(n)/ Check if the vector contains an element
+elem :: (Unbox a, Eq a) => a -> Vector n a -> Bool
+elem = V.elem
+{-# inline elem #-}
+
+infix 4 `notElem`
+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem')
+notElem :: (Unbox a, Eq a) => a -> Vector n a -> Bool
+notElem = V.notElem
+{-# inline notElem #-}
+
+-- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing'
+-- if no such element exists.
+find :: Unbox a => (a -> Bool) -> Vector n a -> Maybe a
+find = V.find
+{-# inline find #-}
+
+-- | /O(n)/ Yield 'Just' the index of the first element matching the predicate
+-- or 'Nothing' if no such element exists.
+findIndex :: Unbox 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 :: (Unbox a, Eq a) => a -> Vector n a -> Maybe (Finite n)
+elemIndex = V.elemIndex
+{-# inline elemIndex #-}
+
+--------------------------------------------------------------------------------
+-- * Folding
+--------------------------------------------------------------------------------
+
+-- | /O(n)/ Left fold
+foldl :: Unbox b => (a -> b -> a) -> a -> Vector n b -> a
+foldl = V.foldl
+{-# inline foldl #-}
+
+-- | /O(n)/ Left fold on non-empty vectors
+foldl1 :: Unbox a => (a -> a -> a) -> Vector (1+n) a -> a
+foldl1 = V.foldl1
+{-# inline foldl1 #-}
+
+-- | /O(n)/ Left fold with strict accumulator
+foldl' :: Unbox b => (a -> b -> a) -> a -> Vector n b -> a
+foldl' = V.foldl'
+{-# inline foldl' #-}
+
+-- | /O(n)/ Left fold on non-empty vectors with strict accumulator
+foldl1' :: Unbox a => (a -> a -> a) -> Vector (1+n) a -> a
+foldl1' = V.foldl1'
+{-# inline foldl1' #-}
+
+-- | /O(n)/ Right fold
+foldr :: Unbox a => (a -> b -> b) -> b -> Vector n a -> b
+foldr = V.foldr
+{-# inline foldr #-}
+
+-- | /O(n)/ Right fold on non-empty vectors
+foldr1 :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> a
+foldr1 = V.foldr1
+{-# inline foldr1 #-}
+
+-- | /O(n)/ Right fold with a strict accumulator
+foldr' :: Unbox a => (a -> b -> b) -> b -> Vector n a -> b
+foldr' = V.foldr'
+{-# inline foldr' #-}
+
+-- | /O(n)/ Right fold on non-empty vectors with strict accumulator
+foldr1' :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> a
+foldr1' = V.foldr1'
+{-# inline foldr1' #-}
+
+-- | /O(n)/ Left fold (function applied to each element and its index)
+ifoldl :: Unbox 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' :: Unbox 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 :: Unbox 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' :: Unbox a => (Finite n -> a -> b -> b) -> b -> Vector n a -> b
+ifoldr' = V.ifoldr'
+{-# inline ifoldr' #-}
+
+-- ** Specialised folds
+
+-- | /O(n)/ Check if all elements satisfy the predicate.
+all :: Unbox a => (a -> Bool) -> Vector n a -> Bool
+all = V.all
+{-# inline all #-}
+
+-- | /O(n)/ Check if any element satisfies the predicate.
+any :: Unbox a => (a -> Bool) -> Vector n a -> Bool
+any = V.any
+{-# inline any #-}
+
+-- | /O(n)/ Check if all elements are 'True'
+and :: Vector n Bool -> Bool
+and = V.and
+{-# inline and #-}
+
+-- | /O(n)/ Check if any element is 'True'
+or :: Vector n Bool -> Bool
+or = V.or
+{-# inline or #-}
+
+-- | /O(n)/ Compute the sum of the elements
+sum :: (Unbox a, Num a) => Vector n a -> a
+sum = V.sum
+{-# inline sum #-}
+
+-- | /O(n)/ Compute the produce of the elements
+product :: (Unbox a, Num a) => Vector n a -> a
+product = V.product
+{-# inline product #-}
+
+-- | /O(n)/ Yield the maximum element of the non-empty vector.
+maximum :: (Unbox a, Ord a) => Vector (n+1) a -> a
+maximum = V.maximum
+{-# inline maximum #-}
+
+-- | /O(n)/ Yield the maximum element of the non-empty vector according to the
+-- given comparison function.
+maximumBy :: Unbox a
+ => (a -> a -> Ordering) -> Vector (n+1) a -> a
+maximumBy = V.maximumBy
+{-# inline maximumBy #-}
+
+-- | /O(n)/ Yield the minimum element of the non-empty vector.
+minimum :: (Unbox a, Ord a) => Vector (n+1) a -> a
+minimum = V.minimum
+{-# inline minimum #-}
+
+-- | /O(n)/ Yield the minimum element of the non-empty vector according to the
+-- given comparison function.
+minimumBy :: Unbox a
+ => (a -> a -> Ordering) -> Vector (n+1) a -> a
+minimumBy = V.minimumBy
+{-# inline minimumBy #-}
+
+-- | /O(n)/ Yield the index of the maximum element of the non-empty vector.
+maxIndex :: (Unbox a, Ord a) => Vector (n+1) a -> Finite (n + 1)
+maxIndex = V.maxIndex
+{-# inline maxIndex #-}
+
+-- | /O(n)/ Yield the index of the maximum element of the non-empty vector
+-- according to the given comparison function.
+maxIndexBy :: Unbox a
+ => (a -> a -> Ordering) -> Vector (n+1) a -> Finite (n + 1)
+maxIndexBy = V.maxIndexBy
+{-# inline maxIndexBy #-}
+
+-- | /O(n)/ Yield the index of the minimum element of the non-empty vector.
+minIndex :: (Unbox a, Ord a) => Vector (n+1) a -> Finite (n + 1)
+minIndex = V.minIndex
+{-# inline minIndex #-}
+
+-- | /O(n)/ Yield the index of the minimum element of the non-empty vector
+-- according to the given comparison function.
+minIndexBy :: Unbox a
+ => (a -> a -> Ordering) -> Vector (n+1) a -> Finite (n + 1)
+minIndexBy = V.minIndexBy
+{-# inline minIndexBy #-}
+
+-- ** Monadic folds
+
+-- | /O(n)/ Monadic fold
+foldM :: (Monad m, Unbox b) => (a -> b -> m a) -> a -> Vector n b -> m a
+foldM = V.foldM
+{-# inline foldM #-}
+
+-- | /O(n)/ Monadic fold (action applied to each element and its index)
+ifoldM :: (Monad m, Unbox b) => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a
+ifoldM = V.ifoldM
+{-# inline ifoldM #-}
+
+-- | /O(n)/ Monadic fold over non-empty vectors
+fold1M :: (Monad m, Unbox a)
+ => (a -> a -> m a) -> Vector (1+n) a -> m a
+fold1M = V.fold1M
+{-# inline fold1M #-}
+
+-- | /O(n)/ Monadic fold with strict accumulator
+foldM' :: (Monad m, Unbox b) => (a -> b -> m a) -> a -> Vector n b -> m a
+foldM' = V.foldM'
+{-# inline foldM' #-}
+
+-- | /O(n)/ Monadic fold with strict accumulator (action applied to each
+-- element and its index)
+ifoldM' :: (Monad m, Unbox b)
+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a
+ifoldM' = V.ifoldM'
+{-# inline ifoldM' #-}
+
+-- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator
+fold1M' :: (Monad m, Unbox a)
+ => (a -> a -> m a) -> Vector (n+1) a -> m a
+fold1M' = V.fold1M'
+{-# inline fold1M' #-}
+
+-- | /O(n)/ Monadic fold that discards the result
+foldM_ :: (Monad m, Unbox b)
+ => (a -> b -> m a) -> a -> Vector n b -> m ()
+foldM_ = V.foldM_
+{-# inline foldM_ #-}
+
+-- | /O(n)/ Monadic fold that discards the result (action applied to
+-- each element and its index)
+ifoldM_ :: (Monad m, Unbox b)
+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()
+ifoldM_ = V.ifoldM_
+{-# inline ifoldM_ #-}
+
+-- | /O(n)/ Monadic fold over non-empty vectors that discards the result
+fold1M_ :: (Monad m, Unbox a)
+ => (a -> a -> m a) -> Vector (n+1) a -> m ()
+fold1M_ = V.fold1M_
+{-# inline fold1M_ #-}
+
+-- | /O(n)/ Monadic fold with strict accumulator that discards the result
+foldM'_ :: (Monad m, Unbox b)
+ => (a -> b -> m a) -> a -> Vector n b -> m ()
+foldM'_ = V.foldM'_
+{-# inline foldM'_ #-}
+
+-- | /O(n)/ Monadic fold with strict accumulator that discards the result
+-- (action applied to each element and its index)
+ifoldM'_ :: (Monad m, Unbox b)
+ => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()
+ifoldM'_ = V.ifoldM'_
+{-# inline ifoldM'_ #-}
+
+-- | /O(n)/ Monad fold over non-empty vectors with strict accumulator
+-- that discards the result
+fold1M'_ :: (Monad m, Unbox a)
+ => (a -> a -> m a) -> Vector (n+1) a -> m ()
+fold1M'_ = V.fold1M'_
+{-# inline fold1M'_ #-}
+
+-- ** Monadic sequencing
+
+-- | Evaluate each action and collect the results
+sequence :: (Monad m, Unbox a, Unbox (m a))
+ => Vector n (m a) -> m (Vector n a)
+sequence = V.sequence
+{-# inline sequence #-}
+
+-- | Evaluate each action and discard the results
+sequence_ :: (Monad m, Unbox (m a)) => Vector n (m a) -> m ()
+sequence_ = V.sequence_
+{-# inline sequence_ #-}
+
+--------------------------------------------------------------------------------
+-- * Prefix sums (scans)
+--------------------------------------------------------------------------------
+
+-- | /O(n)/ Prescan
+--
+-- @
+-- prescanl f z = 'init' . 'scanl' f z
+-- @
+--
+-- Example: @prescanl (+) 0 \<1,2,3,4\> = \<0,1,3,6\>@
+--
+prescanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
+prescanl = V.prescanl
+{-# inline prescanl #-}
+
+-- | /O(n)/ Prescan with strict accumulator
+prescanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
+prescanl' = V.prescanl'
+{-# inline prescanl' #-}
+
+-- | /O(n)/ Scan
+postscanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
+postscanl = V.postscanl
+{-# inline postscanl #-}
+
+-- | /O(n)/ Scan with strict accumulator
+postscanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
+postscanl' = V.postscanl'
+{-# inline postscanl' #-}
+
+-- | /O(n)/ Haskell-style scan
+scanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
+scanl = V.scanl
+{-# inline scanl #-}
+
+-- | /O(n)/ Haskell-style scan with strict accumulator
+scanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
+scanl' = V.scanl'
+{-# inline scanl' #-}
+
+-- | /O(n)/ Scan over a non-empty vector
+scanl1 :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
+scanl1 = V.scanl1
+{-# inline scanl1 #-}
+
+-- | /O(n)/ Scan over a non-empty vector with a strict accumulator
+scanl1' :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
+scanl1' = V.scanl1'
+{-# inline scanl1' #-}
+
+-- | /O(n)/ Right-to-left prescan
+prescanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
+prescanr = V.prescanr
+{-# inline prescanr #-}
+
+-- | /O(n)/ Right-to-left prescan with strict accumulator
+prescanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
+prescanr' = V.prescanr'
+{-# inline prescanr' #-}
+
+-- | /O(n)/ Right-to-left scan
+postscanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
+postscanr = V.postscanr
+{-# inline postscanr #-}
+
+-- | /O(n)/ Right-to-left scan with strict accumulator
+postscanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
+postscanr' = V.postscanr'
+{-# inline postscanr' #-}
+
+-- | /O(n)/ Right-to-left Haskell-style scan
+scanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
+scanr = V.scanr
+{-# inline scanr #-}
+
+-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator
+scanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
+scanr' = V.scanr'
+{-# inline scanr' #-}
+
+-- | /O(n)/ Right-to-left scan over a non-empty vector
+scanr1 :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
+scanr1 = V.scanr1
+{-# inline scanr1 #-}
+
+-- | /O(n)/ Right-to-left scan over a non-empty vector with a strict
+-- accumulator
+scanr1' :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
+scanr1' = V.scanr1'
+{-# inline scanr1' #-}
+
+
+-- * Conversions
+
+-- ** Lists
+
+-- | /O(n)/ Convert a vector to a list
+toList :: Unbox a => Vector n a -> [a]
+toList = V.toList
+{-# inline toList #-}
+
+-- | /O(n)/ Convert a list to a vector
+fromList :: (Unbox a, KnownNat n) => [a] -> Maybe (Vector n a)
+fromList = V.fromList
+{-# inline fromList #-}
+
+-- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
+-- the resultant vector is inferred from the type.
+fromListN :: forall n a. (Unbox a, KnownNat n)
+ => [a] -> Maybe (Vector n a)
+fromListN = V.fromListN
+{-# inline fromListN #-}
+
+-- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
+-- the resultant vector is given explicitly as a 'Proxy' argument.
+fromListN' :: forall n a p. (Unbox a, KnownNat n)
+ => p n -> [a] -> Maybe (Vector n a)
+fromListN' = V.fromListN'
+{-# inline fromListN' #-}
+
+-- | /O(n)/ Takes a list and returns a continuation providing a vector with
+-- a size parameter corresponding to the length of the list.
+--
+-- Essentially converts a list into a vector with the proper size
+-- parameter, determined at runtime.
+--
+-- See 'withSized'
+withSizedList :: forall a r. Unbox a
+ => [a] -> (forall n. KnownNat n => Vector n a -> r) -> r
+withSizedList xs = withSized (VU.fromList xs)
+{-# inline withSizedList #-}
+
+-- ** Mutable vectors
+
+-- | /O(n)/ Yield an immutable copy of the mutable vector.
+freeze :: (PrimMonad m, Unbox a)
+ => VUM.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, Unbox a)
+ => VUM.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, Unbox a)
+ => Vector n a
+ -> m (VUM.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, Unbox a)
+ => Vector n a
+ -> m (VUM.MVector n (PrimState m) a)
+unsafeThaw = V.unsafeThaw
+
+-- | /O(n)/ Copy an immutable vector into a mutable one.
+copy :: (PrimMonad m, Unbox a)
+ => VUM.MVector n (PrimState m) a
+ -> Vector n a
+ -> m ()
+copy = V.copy
+
+-- ** Unsized vectors
+
+-- | Convert a 'Data.Vector.Generic.Vector' into a
+-- 'Data.Vector.Generic.Sized.Vector' if it has the correct size, otherwise
+-- return Nothing.
+toSized :: forall n a. (Unbox a, KnownNat n)
+ => VU.Vector a -> Maybe (Vector n a)
+toSized = V.toSized
+{-# inline toSized #-}
+
+-- | Takes a 'Data.Vector.Unbox.Vector' and returns a continuation
+-- providing a 'Data.Vector.Unbox.Sized.Vector' with a size parameter
+-- @n@ that is determined at runtime based on the length of the input
+-- vector.
+--
+-- Essentially converts a 'Data.Vector.Unbox.Vector' into
+-- a 'Data.Vector.Unbox.Sized.Vector' with the correct size parameter
+-- @n@.
+withSized :: forall a r. Unbox a
+ => VU.Vector a -> (forall n. KnownNat n => Vector n a -> r) -> r
+withSized = V.withSized
+{-# inline withSized #-}
+
+fromSized :: Vector n a -> VU.Vector a
+fromSized = V.fromSized
+{-# inline fromSized #-}
+
+-- | Apply a function on unsized vectors to a sized vector. The function must
+-- preserve the size of the vector, this is not checked.
+withVectorUnsafe :: forall a b (n :: Nat). ()
+ => (VU.Vector a -> VU.Vector b) -> Vector n a -> Vector n b
+withVectorUnsafe = V.withVectorUnsafe
+{-# inline withVectorUnsafe #-}
+
diff --git a/vector-sized.cabal b/vector-sized.cabal
index ad7a688..af1d131 100644
--- a/vector-sized.cabal
+++ b/vector-sized.cabal
@@ -1,5 +1,5 @@
name: vector-sized
-version: 1.0.4.0
+version: 1.1.0.0
synopsis: Size tagged vectors
description: Please see README.md
homepage: http://github.com/expipiplus1/vector-sized#readme
@@ -24,6 +24,8 @@ library
, Data.Vector.Generic.Mutable.Sized
, Data.Vector.Storable.Mutable.Sized
, Data.Vector.Generic.Mutable.Sized.Internal
+ , Data.Vector.Unboxed.Sized
+ , Data.Vector.Unboxed.Mutable.Sized
build-depends: base >= 4.9 && < 5
, vector >= 0.11 && < 0.13
, deepseq >= 1.1 && < 1.5
@@ -32,8 +34,12 @@ library
, indexed-list-literals >= 0.2.0.0
, adjunctions >= 4.3 && < 4.5
, distributive >= 0.5 && < 0.7
+ , comonad >=4 && <6
default-language: Haskell2010
+ -- if impl(ghc >= 8.6)
+ -- default-extensions: NoStarIsType
+
source-repository head
type: git
location: https://github.com/expipiplus1/vector-sized