diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -2,6 +2,13 @@
 
 ## WIP
 
+## [1.4.3] - 2020-12-08
+
+- Add Primitive flavour of sized vectors
+- Add `instance Bits (v a) => Bits (Vector v n a)`
+
+Thanks to @Bodigrim and @mstksg
+
 ## [1.4.2] - 2020-08-20
 
 - Add `instance Unbox a, KnownNat n) => Unbox (Vector n a)`
diff --git a/default.nix b/default.nix
--- a/default.nix
+++ b/default.nix
@@ -1,36 +1,12 @@
-{ pkgs ? import <nixpkgs> {}
-, compiler ? "ghc8102"
-, hoogle ? true
-}:
-
-let src = pkgs.nix-gitignore.gitignoreSource [] ./.;
-
-    # Any overrides we require to the specified haskell package set
-    haskellPackages = with pkgs.haskell.lib;
-      pkgs.haskell.packages.${compiler}.override {
-      overrides = self: super: {
-      } // pkgs.lib.optionalAttrs hoogle {
-        ghc = super.ghc // { withPackages = super.ghc.withHoogle; };
-        ghcWithPackages = self.ghc.withPackages;
-      };
-    };
-
-    # Any packages to appear in the environment provisioned by nix-shell
-    extraEnvPackages = with haskellPackages; [
-    ];
-
-    # Generate a haskell derivation using the cabal2nix tool on `package.yaml`
-    drv = haskellPackages.callCabal2nix "" src {};
+{ nixpkgsSrc ? <nixpkgs>, pkgs ? import nixpkgsSrc { }, compiler ? null }:
 
-    # Insert the extra environment packages into the environment generated by
-    # cabal2nix
-    envWithExtras = pkgs.lib.overrideDerivation drv.env (attrs: {
-      buildInputs = attrs.buildInputs ++ extraEnvPackages;
-    } // pkgs.lib.optionalAttrs hoogle {
-      shellHook   = attrs.shellHook + ''
-        export HIE_HOOGLE_DATABASE="$(cat $(which hoogle) | sed -n -e 's|.*--database \(.*\.hoo\).*|\1|p')"
-      '';
-    });
+let
+  haskellPackages = if compiler == null then
+    pkgs.haskellPackages
+  else
+    pkgs.haskell.packages.${compiler};
 
-in
-  drv // { env = envWithExtras; }
+in haskellPackages.developPackage {
+  name = "";
+  root = pkgs.nix-gitignore.gitignoreSource [ ] ./.;
+}
diff --git a/package.yaml b/package.yaml
new file mode 100644
--- /dev/null
+++ b/package.yaml
@@ -0,0 +1,32 @@
+name: vector-sized
+version: 1.4.3
+synopsis: Size tagged vectors
+description: Please see README.md
+category: Data
+author: Joe Hermaszewski
+maintainer: whats.our.vector.victor@monoid.al
+copyright: 2016 Joe Hermaszewski
+license: BSD3
+github: expipiplus1/vector-sized
+
+extra-source-files:
+- package.yaml
+- readme.md
+- changelog.md
+- default.nix
+
+dependencies:
+- base >=4.9 && <5
+- vector >=0.11 && <0.13
+- deepseq >=1.1 && <1.5
+- finite-typelits >=0.1
+- primitive >=0.5 && <0.8
+- indexed-list-literals >=0.2.0.0
+- adjunctions >=4.3 && <4.5
+- distributive >=0.5 && <0.7
+- comonad >=4 && <6
+- hashable >=1.2.4.0
+- binary >=0.8.3.0
+
+library:
+  source-dirs: src
diff --git a/shell.nix b/shell.nix
deleted file mode 100644
--- a/shell.nix
+++ /dev/null
@@ -1,6 +0,0 @@
-{ pkgs ? import <nixpkgs> {}
-, compiler ? "ghc882"
-, hoogle ? true
-}:
-
-(import ./default.nix { inherit pkgs compiler hoogle; }).env
diff --git a/src/Data/Vector/Generic/Sized.hs b/src/Data/Vector/Generic/Sized.hs
--- a/src/Data/Vector/Generic/Sized.hs
+++ b/src/Data/Vector/Generic/Sized.hs
@@ -253,13 +253,16 @@
 import qualified Data.Vector.Generic.Mutable.Sized as SVGM
 import Data.Vector.Generic.Mutable.Sized.Internal
 import Data.Binary
-import GHC.TypeLits
+import Data.Bits
 import Data.Bifunctor
-import Data.Finite
+import Data.Foldable (for_)
+import Data.Coerce
+import Data.Finite hiding (shift)
 import Data.Finite.Internal
 import Data.Proxy
 import Control.Monad (mzero)
 import Control.Monad.Primitive
+import Control.Monad.ST
 import Foreign.Storable
 import Data.Data
 import Control.Comonad
@@ -268,6 +271,7 @@
 import Text.Read.Lex
 import Text.ParserCombinators.ReadPrec
 import GHC.Read
+import GHC.TypeLits
 import Unsafe.Coerce
 import qualified Data.Functor.Rep as Rep
 import Data.Distributive
@@ -1938,3 +1942,43 @@
 instance (VG.Vector v a, Binary a, KnownNat n) => Binary (Vector v n a) where
   get = replicateM Data.Binary.get
   put = mapM_ put
+
+-- | Only usable if @v a@ is itself an instance of 'Bits', like in the case
+-- with the bitvec library @Bit@ type for unboxed vectors.
+instance (VG.Vector v a, Bits (v a), Bits a, KnownNat n) => Bits (Vector v n a) where
+    (.&.) = coerce ((.&.) @(v a))
+    (.|.) = coerce ((.|.) @(v a))
+    xor   = coerce (xor   @(v a))
+    complement = coerce (complement @(v a))
+    shiftL = coerce (shiftL @(v a))
+    unsafeShiftL = coerce (unsafeShiftL @(v a))
+    shiftR = coerce (shiftR @(v a))
+    unsafeShiftR = coerce (unsafeShiftR @(v a))
+    shift  = coerce (shift  @(v a))
+    rotate = coerce (rotate @(v a))
+    rotateL = coerce (rotateL @(v a))
+    rotateR = coerce (rotateR @(v a))
+    bitSize x = case bitSizeMaybe x of
+      Nothing -> error "Vector v n a: bitSize"
+      Just c  -> c
+    bitSizeMaybe _ = (* fromInteger (natVal (Proxy @n))) <$> bitSizeMaybe @a undefined
+    isSigned _ = False
+    testBit = coerce (testBit @(v a))
+    popCount = coerce (popCount @(v a))
+    setBit = coerce (setBit @(v a))
+    complementBit = coerce (complementBit @(v a))
+    -- need to do special stuff because they return a vector from scratch
+    bit n = runST $ do
+      v <- SVGM.replicate zeroBits
+      for_ (packFinite (fromIntegral n)) $ \i ->
+        SVGM.write v i (complement zeroBits)
+      freeze v
+    zeroBits = replicate zeroBits
+
+-- | Treats a bit vector as n times the size of the stored bits, reflecting
+-- the 'Bits' instance; does not necessarily reflect exact in-memory
+-- representation.  See 'Storable' instance to get information on the
+-- actual in-memry representation.
+instance (VG.Vector v a, Bits (v a), FiniteBits a, KnownNat n) => FiniteBits (Vector v n a) where
+    finiteBitSize _ = finiteBitSize @a undefined * fromIntegral (natVal (Proxy @n))
+
diff --git a/src/Data/Vector/Primitive/Mutable/Sized.hs b/src/Data/Vector/Primitive/Mutable/Sized.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Primitive/Mutable/Sized.hs
@@ -0,0 +1,471 @@
+{-# LANGUAGE CPP              #-}
+{-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes       #-}
+{-# LANGUAGE TypeOperators    #-}
+
+{-|
+This module re-exports the functionality in 'Data.Vector.Generic.Mutable.Sized'
+ specialized to 'Data.Vector.Primitive.Mutable'.
+
+Functions returning a vector determine the size from the type context unless
+they have a @'@ suffix in which case they take an explicit 'Proxy' argument.
+
+Functions where the resulting vector size is not known until runtime are
+not exported.
+-}
+
+module Data.Vector.Primitive.Mutable.Sized
+ ( MVector
+   -- * Accessors
+   -- ** Length information
+  , length
+  , length'
+  , null
+   -- ** Extracting subvectors
+  , slice
+  , slice'
+  , init
+  , tail
+  , take
+  , take'
+  , drop
+  , drop'
+  , splitAt
+  , splitAt'
+  -- ** Overlaps
+  , overlaps
+  -- * Construction
+  -- ** Initialisation
+  , new
+  , unsafeNew
+  , replicate
+  , replicate'
+  , replicateM
+  , replicateM'
+  , clone
+  -- ** Growing
+  , grow
+  , growFront
+  -- ** Restricting memory usage
+  , clear
+  -- * Accessing individual elements
+  , read
+  , read'
+  , write
+  , write'
+  , modify
+  , modify'
+  , swap
+  , exchange
+  , exchange'
+  , unsafeRead
+  , unsafeWrite
+  , unsafeModify
+  , unsafeSwap
+  , unsafeExchange
+#if MIN_VERSION_vector(0,12,0)
+  -- * Modifying vectors
+  , nextPermutation
+#endif
+  -- ** Filling and copying
+  , set
+  , copy
+  , move
+  , unsafeCopy
+    -- * Conversions
+    -- ** Unsized Mutable Vectors
+  , toSized
+  , withSized
+  , fromSized
+  ) where
+
+import qualified Data.Vector.Generic.Mutable.Sized as VGM
+import qualified Data.Vector.Primitive.Mutable as VSM
+import GHC.TypeLits
+import Data.Finite
+import Data.Primitive (Prim)
+import Data.Proxy
+import Control.Monad.Primitive
+import Prelude hiding ( length, null, replicate, init,
+                        tail, take, drop, splitAt, read )
+
+
+-- | 'Data.Vector.Generic.Mutable.Sized.Vector' specialized to use
+-- 'Data.Vector.Primitive.Mutable'.
+type MVector = VGM.MVector VSM.MVector
+
+-- * Accessors
+
+-- ** Length information
+
+-- | /O(1)/ Yield the length of the mutable vector as an 'Int'.
+length :: forall n s a. (KnownNat n)
+       => MVector n s a -> Int
+length = VGM.length
+{-# inline length #-}
+
+-- | /O(1)/ Yield the length of the mutable vector as a 'Proxy'.
+length' :: forall n s a. ()
+        => MVector n s a -> Proxy n
+length' = VGM.length'
+{-# inline length' #-}
+
+-- | /O(1)/ Check whether the mutable vector is empty.
+null :: forall n s a. (KnownNat n)
+       => MVector n s a -> Bool
+null = VGM.null
+{-# inline null #-}
+
+-- ** Extracting subvectors
+
+-- | /O(1)/ Yield a slice of the mutable vector without copying it with an
+-- inferred length argument.
+slice :: forall i n k s a p. (KnownNat i, KnownNat n, Prim a)
+      => p i -- ^ starting index
+      -> MVector (i+n+k) s a
+      -> MVector n s a
+slice = VGM.slice
+{-# inline slice #-}
+
+-- | /O(1)/ Yield a slice of the mutable vector without copying it with an
+-- explicit length argument.
+slice' :: forall i n k s a p
+        . (KnownNat i, KnownNat n, Prim a)
+       => p i -- ^ starting index
+       -> p n -- ^ length
+       -> MVector (i+n+k) s a
+       -> MVector n s a
+slice' = VGM.slice'
+{-# inline slice' #-}
+
+-- | /O(1)/ Yield all but the last element of a non-empty mutable vector
+-- without copying.
+init :: forall n s a. Prim a
+     => MVector (n+1) s a -> MVector n s a
+init = VGM.init
+{-# inline init #-}
+
+-- | /O(1)/ Yield all but the first element of a non-empty mutable vector
+-- without copying.
+tail :: forall n s a. Prim a
+     => MVector (1+n) s a -> MVector n s a
+tail = VGM.tail
+{-# inline tail #-}
+
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is inferred from the
+-- type.
+take :: forall n k s a. (KnownNat n, Prim a)
+     => MVector (n+k) s a -> MVector n s a
+take = VGM.take
+{-# inline take #-}
+
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is given explicitly
+-- as a 'Proxy' argument.
+take' :: forall n k s a p. (KnownNat n, Prim a)
+      => p n -> MVector (n+k) s a -> MVector n s a
+take' = VGM.take'
+{-# inline take' #-}
+
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
+-- inferred from the type.
+drop :: forall n k s a. (KnownNat n, Prim a)
+     => MVector (n+k) s a -> MVector k s a
+drop = VGM.drop
+{-# inline drop #-}
+
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
+-- givel explicitly as a 'Proxy' argument.
+drop' :: forall n k s a p. (KnownNat n, Prim a)
+      => p n -> MVector (n+k) s a -> MVector k s a
+drop' = VGM.drop'
+{-# inline drop' #-}
+
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.
+-- The lengths of the resulting vectors are inferred from the type.
+splitAt :: forall n m s a. (KnownNat n, Prim a)
+        => MVector (n+m) s a -> (MVector n s a, MVector m s a)
+splitAt = VGM.splitAt
+{-# inline splitAt #-}
+
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without
+-- copying.  The length of the first resulting vector is passed explicitly as a
+-- 'Proxy' argument.
+splitAt' :: forall n m s a p. (KnownNat n, Prim a)
+         => p n -> MVector (n+m) s a -> (MVector n s a, MVector m s a)
+splitAt' = VGM.splitAt'
+{-# inline splitAt' #-}
+
+-- ** Overlaps
+
+-- | /O(1)/ Check if two vectors overlap.
+overlaps :: forall n k s a. Prim a
+         => MVector n s a
+         -> MVector k s a
+         -> Bool
+overlaps = VGM.overlaps
+{-# inline overlaps #-}
+
+-- * Construction
+
+-- ** Initialisation
+
+-- | Create a mutable vector where the length is inferred from the type.
+new :: forall n m a. (KnownNat n, PrimMonad m, Prim a)
+    => m (MVector n (PrimState m) a)
+new = VGM.new
+{-# inline new #-}
+
+-- | Create a mutable vector where the length is inferred from the type.
+-- The memory is not initialized.
+unsafeNew :: forall n m a. (KnownNat n, PrimMonad m, Prim a)
+          => m (MVector n (PrimState m) a)
+unsafeNew = VGM.unsafeNew
+{-# inline unsafeNew #-}
+
+-- | Create a mutable vector where the length is inferred from the type and
+-- fill it with an initial value.
+replicate :: forall n m a. (KnownNat n, PrimMonad m, Prim a)
+          => a -> m (MVector n (PrimState m) a)
+replicate = VGM.replicate
+{-# inline replicate #-}
+
+-- | Create a mutable vector where the length is given explicitly as
+-- a 'Proxy' argument and fill it with an initial value.
+replicate' :: forall n m a p. (KnownNat n, PrimMonad m, Prim a)
+           => p n -> a -> m (MVector n (PrimState m) a)
+replicate' = VGM.replicate'
+{-# inline replicate' #-}
+
+-- | Create a mutable vector where the length is inferred from the type and
+-- fill it with values produced by repeatedly executing the monadic action.
+replicateM :: forall n m a. (KnownNat n, PrimMonad m, Prim a)
+           => m a -> m (MVector n (PrimState m) a)
+replicateM = VGM.replicateM
+{-# inline replicateM #-}
+
+-- | Create a mutable vector where the length is given explicitly as
+-- a 'Proxy' argument and fill it with values produced by repeatedly
+-- executing the monadic action.
+replicateM' :: forall n m a p. (KnownNat n, PrimMonad m, Prim a)
+           => p n -> m a -> m (MVector n (PrimState m) a)
+replicateM' = VGM.replicateM'
+{-# inline replicateM' #-}
+
+-- | Create a copy of a mutable vector.
+clone :: forall n m a. (PrimMonad m, Prim a)
+      => MVector n (PrimState m) a -> m (MVector n (PrimState m) a)
+clone = VGM.clone
+{-# inline clone #-}
+
+-- ** Growing
+
+-- | Grow a mutable vector by an amount given explicitly as a 'Proxy'
+-- argument.
+grow :: forall n k m a p. (KnownNat k, PrimMonad m, Prim a)
+      => p k -> MVector n (PrimState m) a -> m (MVector (n + k) (PrimState m) a)
+grow = VGM.grow
+{-# inline grow #-}
+
+-- | Grow a mutable vector (from the front) by an amount given explicitly
+-- as a 'Proxy' argument.
+growFront :: forall n k m a p. (KnownNat k, PrimMonad m, Prim a)
+      => p k -> MVector n (PrimState m) a -> m (MVector (n + k) (PrimState m) a)
+growFront = VGM.growFront
+{-# inline growFront #-}
+
+-- ** Restricting memory usage
+
+-- | Reset all elements of the vector to some undefined value, clearing all
+-- references to external objects.
+clear :: (PrimMonad m, Prim a) => MVector n (PrimState m) a -> m ()
+clear = VGM.clear
+{-# inline clear #-}
+
+-- * Accessing individual elements
+
+-- | /O(1)/ Yield the element at a given type-safe position using 'Finite'.
+read :: forall n m a. (PrimMonad m, Prim a)
+      => MVector n (PrimState m) a -> Finite n -> m a
+read = VGM.read
+{-# inline read #-}
+
+-- | /O(1)/ Yield the element at a given type-safe position using 'Proxy'.
+read' :: forall n k a m p. (KnownNat k, PrimMonad m, Prim a)
+       => MVector (n+k+1) (PrimState m) a -> p k -> m a
+read' = VGM.read'
+{-# inline read' #-}
+
+-- | /O(1)/ Yield the element at a given 'Int' position without bounds
+-- checking.
+unsafeRead :: forall n a m. (PrimMonad m, Prim a)
+           => MVector n (PrimState m) a -> Int -> m a
+unsafeRead = VGM.unsafeRead
+{-# inline unsafeRead #-}
+
+-- | /O(1)/ Replace the element at a given type-safe position using 'Finite'.
+write :: forall n m a. (PrimMonad m, Prim a)
+      => MVector n (PrimState m) a -> Finite n -> a -> m ()
+write = VGM.write
+{-# inline write #-}
+
+-- | /O(1)/ Replace the element at a given type-safe position using 'Proxy'.
+write' :: forall n k a m p. (KnownNat k, PrimMonad m, Prim a)
+       => MVector (n+k+1) (PrimState m) a -> p k -> a -> m ()
+write' = VGM.write'
+{-# inline write' #-}
+
+-- | /O(1)/ Replace the element at a given 'Int' position without bounds
+-- checking.
+unsafeWrite :: forall n m a. (PrimMonad m, Prim a)
+      => MVector n (PrimState m) a -> Int -> a -> m ()
+unsafeWrite = VGM.unsafeWrite
+{-# inline unsafeWrite #-}
+
+-- | /O(1)/ Modify the element at a given type-safe position using 'Finite'.
+modify :: forall n m a. (PrimMonad m, Prim a)
+       => MVector n (PrimState m) a -> (a -> a) -> Finite n -> m ()
+modify = VGM.modify
+{-# inline modify #-}
+
+-- | /O(1)/ Modify the element at a given type-safe position using 'Proxy'.
+modify' :: forall n k a m p. (KnownNat k, PrimMonad m, Prim a)
+        => MVector (n+k+1) (PrimState m) a -> (a -> a) -> p k -> m ()
+modify' = VGM.modify'
+{-# inline modify' #-}
+
+-- | /O(1)/ Modify the element at a given 'Int' position without bounds
+-- checking.
+unsafeModify :: forall n m a. (PrimMonad m, Prim a)
+       => MVector n (PrimState m) a -> (a -> a) -> Int -> m ()
+unsafeModify = VGM.unsafeModify
+{-# inline unsafeModify #-}
+
+-- | /O(1)/ Swap the elements at the given type-safe positions using 'Finite's.
+swap :: forall n m a. (PrimMonad m, Prim a)
+     => MVector n (PrimState m) a -> Finite n -> Finite n -> m ()
+swap = VGM.swap
+{-# inline swap #-}
+
+-- | /O(1)/ Swap the elements at the given 'Int' positions without bounds
+-- checking.
+unsafeSwap :: forall n m a. (PrimMonad m, Prim a)
+           => MVector n (PrimState m) a -> Int -> Int -> m ()
+unsafeSwap = VGM.unsafeSwap
+{-# inline unsafeSwap #-}
+
+-- | /O(1)/ Replace the element at a given type-safe position and return
+-- the old element, using 'Finite'.
+exchange :: forall n m a. (PrimMonad m, Prim a)
+         => MVector n (PrimState m) a -> Finite n -> a -> m a
+exchange = VGM.exchange
+{-# inline exchange #-}
+
+-- | /O(1)/ Replace the element at a given type-safe position and return
+-- the old element, using 'Finite'.
+exchange' :: forall n k a m p. (KnownNat k, PrimMonad m, Prim a)
+          => MVector (n+k+1) (PrimState m) a -> p k -> a -> m a
+exchange' = VGM.exchange'
+{-# inline exchange' #-}
+
+-- | /O(1)/ Replace the element at a given 'Int' position and return
+-- the old element. No bounds checks are performed.
+unsafeExchange :: forall n m a. (PrimMonad m, Prim a)
+         => MVector n (PrimState m) a -> Int -> a -> m a
+unsafeExchange = VGM.unsafeExchange
+{-# inline unsafeExchange #-}
+
+#if MIN_VERSION_vector(0,12,0)
+-- * Modifying vectors
+
+-- | Compute the next permutation (lexicographically) of a given vector
+-- in-place.  Returns 'False' when the input is the last permutation.
+nextPermutation :: forall n e m. (Ord e, PrimMonad m, Prim e)
+                => MVector n (PrimState m) e -> m Bool
+nextPermutation = VGM.nextPermutation
+{-# inline nextPermutation #-}
+#endif
+
+-- ** Filling and copying
+
+-- | Set all elements of the vector to the given value.
+set :: (PrimMonad m, Prim a) => MVector n (PrimState m) a -> a -> m ()
+set = VGM.set
+{-# inline set #-}
+
+-- | Copy a vector. The two vectors may not overlap.
+copy :: (PrimMonad m, Prim a)
+     => MVector n (PrimState m) a       -- ^ target
+     -> MVector n (PrimState m) a       -- ^ source
+     -> m ()
+copy = VGM.copy
+{-# inline copy #-}
+
+-- * Conversions
+
+-- ** Unsized Mutable Vectors
+
+-- | Copy a vector. The two vectors may not overlap. This is not checked.
+unsafeCopy :: (PrimMonad m, Prim a)
+           => MVector n (PrimState m) a       -- ^ target
+           -> MVector n (PrimState m) a       -- ^ source
+           -> m ()
+unsafeCopy = VGM.unsafeCopy
+{-# inline unsafeCopy #-}
+
+-- | Move the contents of a vector.  If the two vectors do not overlap,
+-- this is equivalent to 'copy'.  Otherwise, the copying is performed as if
+-- the source vector were copied to a temporary vector and then the
+-- temporary vector was copied to the target vector.
+move :: (PrimMonad m, Prim a)
+     => MVector n (PrimState m) a       -- ^ target
+     -> MVector n (PrimState m) a       -- ^ source
+     -> m ()
+move = VGM.move
+{-# inline move #-}
+
+-- | Convert a 'Data.Vector.Primitive.Mutable.MVector' into
+-- a 'Data.Vector.Primitive.Mutable.Sized.MVector' if it has the correct
+-- size, otherwise return Nothing.
+--
+-- Note that this does no copying; the returned 'MVector' is a reference to
+-- the exact same vector in memory as the given one, and any modifications
+-- to it are also reflected in the given
+-- 'Data.Vector.Primitive.Mutable.MVector'.
+toSized :: forall n a s. (KnownNat n, Prim a)
+        => VSM.MVector s a -> Maybe (MVector n s a)
+toSized = VGM.toSized
+{-# inline toSized #-}
+
+-- | Takes a 'Data.Vector.Primitive.Mutable.MVector' and returns
+-- a continuation providing a 'Data.Vector.Primitive.Mutable.Sized.MVector'
+-- with a size parameter @n@ that is determined at runtime based on the
+-- length of the input vector.
+--
+-- Essentially converts a 'Data.Vector.Primitive.Mutable.MVector' into
+-- a 'Data.Vector.Primitive.Sized.MVector' with the correct size parameter
+-- @n@.
+--
+-- Note that this does no copying; the returned 'MVector' is a reference to
+-- the exact same vector in memory as the given one, and any modifications
+-- to it are also reflected in the given
+-- 'Data.Vector.Primitive.Mutable.MVector'.
+withSized :: forall s a r. Prim a
+          => VSM.MVector s a -> (forall n. KnownNat n => MVector n s a -> r) -> r
+withSized = VGM.withSized
+{-# inline withSized #-}
+
+-- | Convert a 'Data.Vector.Primitive.Mutable.Sized.MVector' into a
+-- 'Data.Vector.Primitive.Mutable.MVector'.
+--
+-- Note that this does no copying; the returned
+-- 'Data.Vector.Primitive.Mutable.MVector' is a reference to the exact same
+-- vector in memory as the given one, and any modifications to it are also
+-- reflected in the given 'MVector'.
+fromSized :: MVector n s a -> VSM.MVector s a
+fromSized = VGM.fromSized
+{-# inline fromSized #-}
diff --git a/src/Data/Vector/Primitive/Sized.hs b/src/Data/Vector/Primitive/Sized.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Primitive/Sized.hs
@@ -0,0 +1,1513 @@
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators       #-}
+{-# LANGUAGE PatternSynonyms     #-}
+{-# LANGUAGE CPP                 #-}
+
+#if MIN_VERSION_base(4,12,0)
+{-# LANGUAGE NoStarIsType #-}
+#endif
+
+{-|
+This module re-exports the functionality in 'Data.Vector.Generic.Sized'
+ specialized to 'Data.Vector.Primitive'.
+
+Functions returning a vector determine the size from the type context unless
+they have a @'@ suffix in which case they take an explicit 'Proxy' argument.
+
+Functions where the resulting vector size is not known until runtime are
+not exported.
+-}
+
+module Data.Vector.Primitive.Sized
+ ( Vector
+  , pattern SomeSized
+  , VSM.MVector
+   -- * Accessors
+   -- ** Length information
+  , length
+  , length'
+  , knownLength
+  , knownLength'
+    -- ** Indexing
+  , index
+  , index'
+  , unsafeIndex
+  , head
+  , last
+    -- ** Monadic indexing
+  , indexM
+  , indexM'
+  , unsafeIndexM
+  , headM
+  , lastM
+    -- ** Extracting subvectors (slicing)
+  , slice
+  , slice'
+  , init
+  , tail
+  , take
+  , take'
+  , drop
+  , drop'
+  , splitAt
+  , splitAt'
+    -- * Construction
+    -- ** Initialization
+  , empty
+  , singleton
+  , fromTuple
+  , replicate
+  , replicate'
+  , generate
+  , generate'
+  , iterateN
+  , iterateN'
+    -- ** Monadic initialization
+  , replicateM
+  , replicateM'
+  , generateM
+  , generateM'
+    -- ** Unfolding
+  , unfoldrN
+  , unfoldrN'
+    -- ** Enumeration
+  , enumFromN
+  , enumFromN'
+  , enumFromStepN
+  , enumFromStepN'
+    -- ** Concatenation
+  , cons
+  , snoc
+  , (++)
+    -- ** Restricting memory usage
+  , force
+    -- * Modifying vectors
+    -- ** Bulk updates
+  , (//)
+  , update_
+  , unsafeUpd
+  , unsafeUpdate_
+    -- ** Accumulations
+  , accum
+  , accumulate_
+  , unsafeAccum
+  , unsafeAccumulate_
+    -- ** Permutations
+  , reverse
+  , backpermute
+  , unsafeBackpermute
+    -- * Lenses
+  , ix
+  , _head
+  , _last
+    -- * Elementwise operations
+    -- ** Mapping
+  , map
+  , imap
+  , concatMap
+    -- ** Monadic mapping
+  , mapM
+  , imapM
+  , mapM_
+  , imapM_
+  , forM
+  , forM_
+    -- ** Zipping
+  , zipWith
+  , zipWith3
+  , zipWith4
+  , zipWith5
+  , zipWith6
+  , izipWith
+  , izipWith3
+  , izipWith4
+  , izipWith5
+  , izipWith6
+    -- ** Monadic zipping
+  , zipWithM
+  , izipWithM
+  , zipWithM_
+  , izipWithM_
+    -- * Working with predicates
+    -- ** Searching
+  , elem
+  , notElem
+  , find
+  , findIndex
+  , elemIndex
+    -- * Folding
+  , foldl
+  , foldl1
+  , foldl'
+  , foldl1'
+  , foldr
+  , foldr1
+  , foldr'
+  , foldr1'
+  , ifoldl
+  , ifoldl'
+  , ifoldr
+  , ifoldr'
+    -- ** Specialised folds
+  , all
+  , any
+  , sum
+  , product
+  , maximum
+  , maximumBy
+  , minimum
+  , minimumBy
+  , maxIndex
+  , maxIndexBy
+  , minIndex
+  , minIndexBy
+    -- ** Monadic folds
+  , foldM
+  , ifoldM
+  , fold1M
+  , foldM'
+  , ifoldM'
+  , fold1M'
+  , foldM_
+  , ifoldM_
+  , fold1M_
+  , foldM'_
+  , ifoldM'_
+  , fold1M'_
+    -- * Prefix sums (scans)
+  , prescanl
+  , prescanl'
+  , postscanl
+  , postscanl'
+  , scanl
+  , scanl'
+  , scanl1
+  , scanl1'
+  , prescanr
+  , prescanr'
+  , postscanr
+  , postscanr'
+  , scanr
+  , scanr'
+  , scanr1
+  , scanr1'
+    -- * Conversions
+    -- ** Lists
+  , toList
+  , fromList
+  , fromListN
+  , fromListN'
+  , withSizedList
+    -- ** Mutable vectors
+  , freeze
+  , thaw
+  , copy
+  , unsafeFreeze
+  , unsafeThaw
+    -- ** Unsized Vectors
+  , toSized
+  , withSized
+  , fromSized
+  , withVectorUnsafe
+  ) where
+
+import qualified Data.Vector.Generic.Sized as V
+import qualified Data.Vector.Primitive as VS
+import Data.IndexedListLiterals (IndexedListLiterals)
+import qualified Data.Vector.Primitive.Mutable.Sized as VSM
+import GHC.TypeLits
+import Data.Finite
+import Data.Primitive (Prim)
+import Data.Proxy
+import Control.Monad.Primitive
+import Prelude hiding ( length, null,
+                        replicate, (++), concat,
+                        head, last,
+                        init, tail, take, drop, splitAt, reverse,
+                        map, concat, concatMap,
+                        zipWith, zipWith3, zip, zip3, unzip, unzip3,
+                        filter, takeWhile, dropWhile, span, break,
+                        elem, notElem,
+                        foldl, foldl1, foldr, foldr1,
+                        all, any, and, or, sum, product, maximum, minimum,
+                        scanl, scanl1, scanr, scanr1,
+                        enumFromTo, enumFromThenTo,
+                        mapM, mapM_, sequence, sequence_,
+                        showsPrec )
+
+-- | 'Data.Vector.Generic.Sized.Vector' specialized to use
+-- 'Data.Vector.Primitive'.
+type Vector = V.Vector VS.Vector
+
+-- | /O(1)/ Yield the length of the vector as an 'Int'. This is more like
+-- 'natVal' than 'Data.Vector.length', extracting the value from the 'KnownNat'
+-- instance and not looking at the vector itself.
+length :: forall n a. KnownNat n
+       => Vector n a -> Int
+length = V.length
+{-# inline length #-}
+
+-- | /O(1)/ Yield the length of the vector as a 'Proxy'. This function
+-- doesn't /do/ anything; it merely allows the size parameter of the vector
+-- to be passed around as a 'Proxy'.
+length' :: forall n a.
+           Vector n a -> Proxy n
+length' = V.length'
+{-# inline length' #-}
+
+-- | /O(1)/ Reveal a 'KnownNat' instance for a vector's length, determined
+-- at runtime.
+knownLength :: forall n a r. Prim a
+            => Vector n a -- ^ a vector of some (potentially unknown) length
+            -> (KnownNat n => r) -- ^ a value that depends on knowing the vector's length
+            -> r -- ^ the value computed with the length
+knownLength = V.knownLength
+
+-- | /O(1)/ Reveal a 'KnownNat' instance and 'Proxy' for a vector's length,
+-- determined at runtime.
+knownLength' :: forall n a r. Prim a
+             => Vector n a -- ^ a vector of some (potentially unknown) length
+             -> (KnownNat n => Proxy n -> r) -- ^ a value that depends on knowing the vector's length, which is given as a 'Proxy'
+             -> r -- ^ the value computed with the length
+knownLength' = V.knownLength'
+
+-- | /O(1)/ Safe indexing using a 'Finite'.
+index :: forall n a. Prim a
+      => Vector n a -> Finite n -> a
+index = V.index
+{-# inline index #-}
+
+-- | /O(1)/ Safe indexing using a 'Proxy'.
+index' :: forall n m a p. (KnownNat n, Prim a)
+       => Vector (n+m+1) a -> p n -> a
+index' = V.index'
+{-# inline index' #-}
+
+-- | /O(1)/ Indexing using an 'Int' without bounds checking.
+unsafeIndex :: forall n a. Prim a
+      => Vector n a -> Int -> a
+unsafeIndex = V.unsafeIndex
+{-# inline unsafeIndex #-}
+
+-- | /O(1)/ Yield the first element of a non-empty vector.
+head :: forall n a. (Prim a)
+     => Vector (1+n) a -> a
+head = V.head
+{-# inline head #-}
+
+-- | /O(1)/ Yield the last element of a non-empty vector.
+last :: forall n a. (Prim a)
+     => Vector (n+1) a -> a
+last = V.last
+{-# inline last #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) an arbitrary element by its index.
+ix :: forall n a f. (Prim a, Functor f)
+   => Finite n -> (a -> f a) -> Vector n a -> f (Vector n a)
+ix = V.ix
+{-# inline ix #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) the first element of a non-empty vector.
+_head :: forall n a f. (Prim a, Functor f)
+      => (a -> f a) -> Vector (1+n) a -> f (Vector (1+n) a)
+_head = V._head
+{-# inline _head #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) the last element of a non-empty vector.
+_last :: forall n a f. (Prim a, Functor f)
+       => (a -> f a) -> Vector (n+1) a -> f (Vector (n+1) a)
+_last = V._last
+{-# inline _last #-}
+
+
+-- | /O(1)/ Safe indexing in a monad. See the documentation for 'Data.Vector.Generic.Sized.indexM' for
+-- an explanation of why this is useful.
+indexM :: forall n a m. (Prim a, Monad m)
+      => Vector n a -> Finite n -> m a
+indexM = V.indexM
+{-# inline indexM #-}
+
+-- | /O(1)/ Safe indexing in a monad using a 'Proxy'. See the documentation for
+-- 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
+indexM' :: forall n k a m p. (KnownNat n, Prim a, Monad m)
+      => Vector (n+k) a -> p n -> m a
+indexM' = V.indexM'
+{-# inline indexM' #-}
+
+-- | /O(1)/ Indexing using an 'Int' without bounds checking. See the
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
+unsafeIndexM :: forall n a m. (Prim a, Monad m)
+      => Vector n a -> Int -> m a
+unsafeIndexM = V.unsafeIndexM
+{-# inline unsafeIndexM #-}
+
+-- | /O(1)/ Yield the first element of a non-empty vector in a monad. See the
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
+headM :: forall n a m. (Prim a, Monad m)
+      => Vector (1+n) a -> m a
+headM = V.headM
+{-# inline headM #-}
+
+-- | /O(1)/ Yield the last element of a non-empty vector in a monad. See the
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
+lastM :: forall n a m. (Prim a, Monad m)
+      => Vector (n+1) a -> m a
+lastM = V.lastM
+{-# inline lastM #-}
+
+-- | /O(1)/ Yield a slice of the vector without copying it with an inferred
+-- length argument.
+slice :: forall i n m a p. (KnownNat i, KnownNat n, Prim a)
+      => p i -- ^ starting index
+      -> Vector (i+n+m) a
+      -> Vector n a
+slice = V.slice
+{-# inline slice #-}
+
+-- | /O(1)/ Yield a slice of the vector without copying it with an explicit
+-- length argument.
+slice' :: forall i n m a p. (KnownNat i, KnownNat n, Prim a)
+       => p i -- ^ starting index
+       -> p n -- ^ length
+       -> Vector (i+n+m) a
+       -> Vector n a
+slice' = V.slice'
+{-# inline slice' #-}
+
+-- | /O(1)/ Yield all but the last element of a non-empty vector without
+-- copying.
+init :: forall n a. (Prim a)
+     => Vector (n+1) a -> Vector n a
+init = V.init
+{-# inline init #-}
+
+-- | /O(1)/ Yield all but the first element of a non-empty vector without
+-- copying.
+tail :: forall n a. (Prim a)
+     => Vector (1+n) a -> Vector n a
+tail = V.tail
+{-# inline tail #-}
+
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is inferred from the
+-- type.
+take :: forall n m a. (KnownNat n, Prim a)
+     => Vector (n+m) a -> Vector n a
+take = V.take
+{-# inline take #-}
+
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is given explicitly
+-- as a 'Proxy' argument.
+take' :: forall n m a p. (KnownNat n, Prim a)
+      => p n -> Vector (n+m) a -> Vector n a
+take' = V.take'
+{-# inline take' #-}
+
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
+-- inferred from the type.
+drop :: forall n m a. (KnownNat n, Prim a)
+     => Vector (n+m) a -> Vector m a
+drop = V.drop
+{-# inline drop #-}
+
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
+-- givel explicitly as a 'Proxy' argument.
+drop' :: forall n m a p. (KnownNat n, Prim a)
+      => p n -> Vector (n+m) a -> Vector m a
+drop' = V.drop'
+{-# inline drop' #-}
+
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.
+-- The lengths of the resulting vectors are inferred from the type.
+splitAt :: forall n m a. (KnownNat n, Prim a)
+        => Vector (n+m) a -> (Vector n a, Vector m a)
+splitAt = V.splitAt
+{-# inline splitAt #-}
+
+-- | /O(1)/ Yield the first @n@ elements paired with the remainder without
+-- copying. The length of the first resulting vector is passed explicitly as a
+-- 'Proxy' argument.
+splitAt' :: forall n m a p. (KnownNat n, Prim a)
+         => p n -> Vector (n+m) a -> (Vector n a, Vector m a)
+splitAt' = V.splitAt'
+{-# inline splitAt' #-}
+
+--------------------------------------------------------------------------------
+-- * Construction
+--------------------------------------------------------------------------------
+
+--
+-- ** Initialization
+--
+
+-- | /O(1)/ Empty vector.
+empty :: forall a. (Prim a)
+      => Vector 0 a
+empty = V.empty
+{-# inline empty #-}
+
+-- | /O(1)/ Vector with exactly one element.
+singleton :: forall a. (Prim a)
+           => a -> Vector 1 a
+singleton = V.singleton
+{-# inline singleton #-}
+
+-- | /O(n)/ Construct a vector in a type safe manner
+-- @
+--   fromTuple (1,2) :: Vector 2 Int
+--   fromTuple ("hey", "what's", "going", "on") :: Vector 4 String
+-- @
+fromTuple :: forall a input length.
+             (Prim a, IndexedListLiterals input length a, KnownNat length)
+          => input -> Vector length a
+fromTuple = V.fromTuple
+{-# inline fromTuple #-}
+
+-- | /O(n)/ Construct a vector with the same element in each position where the
+-- length is inferred from the type.
+replicate :: forall n a. (KnownNat n, Prim a)
+          => a -> Vector n a
+replicate = V.replicate
+{-# inline replicate #-}
+
+-- | /O(n)/ Construct a vector with the same element in each position where the
+-- length is given explicitly as a 'Proxy' argument.
+replicate' :: forall n a p. (KnownNat n, Prim a)
+           => p n -> a -> Vector n a
+replicate' = V.replicate'
+{-# inline replicate' #-}
+
+-- | /O(n)/ construct a vector of the given length by applying the function to
+-- each index where the length is inferred from the type.
+generate :: forall n a. (KnownNat n, Prim a)
+         => (Finite n -> a) -> Vector n a
+generate = V.generate
+{-# inline generate #-}
+
+-- | /O(n)/ construct a vector of the given length by applying the function to
+-- each index where the length is given explicitly as a 'Proxy' argument.
+generate' :: forall n a p. (KnownNat n, Prim a)
+          => p n -> (Finite n -> a) -> Vector n a
+generate' = V.generate'
+{-# inline generate' #-}
+
+-- | /O(n)/ Apply function @n@ times to value. Zeroth element is original value.
+-- The length is inferred from the type.
+iterateN :: forall n a. (KnownNat n, Prim a)
+         => (a -> a) -> a -> Vector n a
+iterateN = V.iterateN
+{-# inline iterateN #-}
+
+-- | /O(n)/ Apply function @n@ times to value. Zeroth element is original value.
+-- The length is given explicitly as a 'Proxy' argument.
+iterateN' :: forall n a p. (KnownNat n, Prim a)
+          => p n -> (a -> a) -> a -> Vector n a
+iterateN' = V.iterateN'
+{-# inline iterateN' #-}
+
+--
+-- ** Monadic initialisation
+--
+
+-- | /O(n)/ Execute the monadic action @n@ times and store the results in a
+-- vector where @n@ is inferred from the type.
+replicateM :: forall n m a. (KnownNat n, Prim a, Monad m)
+           => m a -> m (Vector n a)
+replicateM = V.replicateM
+{-# inline replicateM #-}
+
+-- | /O(n)/ Execute the monadic action @n@ times and store the results in a
+-- vector where @n@ is given explicitly as a 'Proxy' argument.
+replicateM' :: forall n m a p. (KnownNat n, Prim a, Monad m)
+            => p n -> m a -> m (Vector n a)
+replicateM' = V.replicateM'
+{-# inline replicateM' #-}
+
+-- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
+-- each index where @n@ is inferred from the type.
+generateM :: forall n m a. (KnownNat n, Prim a, Monad m)
+          => (Finite n -> m a) -> m (Vector n a)
+generateM = V.generateM
+{-# inline generateM #-}
+
+-- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
+-- each index where @n@ is given explicitly as a 'Proxy' argument.
+generateM' :: forall n m a p. (KnownNat n, Prim a, Monad m)
+           => p n -> (Finite n -> m a) -> m (Vector n a)
+generateM' = V.generateM'
+{-# inline generateM' #-}
+
+--
+-- ** Unfolding
+--
+
+-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
+-- the generator function to the a seed. The length is inferred from the
+-- type.
+unfoldrN :: forall n a b. (KnownNat n, Prim a)
+         => (b -> (a, b)) -> b -> Vector n a
+unfoldrN = V.unfoldrN
+{-# inline unfoldrN #-}
+
+-- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
+-- the generator function to the a seed. The length is given explicitly
+-- as a 'Proxy' argument.
+unfoldrN' :: forall n a b p. (KnownNat n, Prim a)
+          => p n -> (b -> (a, b)) -> b -> Vector n a
+unfoldrN' = V.unfoldrN'
+{-# inline unfoldrN' #-}
+
+--
+-- ** Enumeration
+--
+
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@, ...,
+-- @x + (n - 1)@. The length is inferred from the type.
+enumFromN :: forall n a. (KnownNat n, Prim a, Num a)
+          => a -> Vector n a
+enumFromN = V.enumFromN
+{-# inline enumFromN #-}
+
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@, ...,
+-- @x + (n - 1)@. The length is given explicitly as a 'Proxy' argument.
+enumFromN' :: forall n a p. (KnownNat n, Prim a, Num a)
+           => a -> p n -> Vector n a
+enumFromN' = V.enumFromN'
+{-# inline enumFromN' #-}
+
+-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
+-- @x+2y@, ..., @x + (n - 1)y@. The length is inferred from the type.
+enumFromStepN :: forall n a. (KnownNat n, Prim a, Num a)
+          => a -> a -> Vector n a
+enumFromStepN = V.enumFromStepN
+{-# inline enumFromStepN #-}
+
+-- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
+-- @x+2y@, ..., @x + (n - 1)y@. The length is given explicitly as a 'Proxy' argument.
+enumFromStepN' :: forall n a p. (KnownNat n, Prim a, Num a)
+               => a -> a -> p n -> Vector n a
+enumFromStepN' = V.enumFromStepN'
+{-# inline enumFromStepN' #-}
+
+--
+-- ** Concatenation
+--
+
+-- | /O(n)/ Prepend an element.
+cons :: forall n a. Prim a
+     => a -> Vector n a -> Vector (1+n) a
+cons = V.cons
+{-# inline cons #-}
+
+-- | /O(n)/ Append an element.
+snoc :: forall n a. Prim a
+     => Vector n a -> a -> Vector (n+1) a
+snoc = V.snoc
+{-# inline snoc #-}
+
+-- | /O(m+n)/ Concatenate two vectors.
+(++) :: forall n m a. Prim a
+     => Vector n a -> Vector m a -> Vector (n+m) a
+(++) = (V.++)
+{-# inline (++) #-}
+
+--
+-- ** Restricting memory usage
+--
+
+-- | /O(n)/ Yield the argument but force it not to retain any extra memory,
+-- possibly by copying it.
+--
+-- This is especially useful when dealing with slices. For example:
+--
+-- > force (slice 0 2 <huge vector>)
+--
+-- Here, the slice retains a reference to the huge vector. Forcing it creates
+-- a copy of just the elements that belong to the slice and allows the huge
+-- vector to be garbage collected.
+force :: Prim a => Vector n a -> Vector n a
+force = V.force
+{-# inline force #-}
+
+
+--------------------------------------------------------------------------------
+-- * Modifying vectors
+--------------------------------------------------------------------------------
+
+--
+-- ** Bulk updates
+--
+
+-- | /O(m+n)/ For each pair @(i,a)@ from the list, replace the vector
+-- element at position @i@ by @a@.
+--
+-- > <5,9,2,7> // [(2,1),(0,3),(2,8)] = <3,9,8,7>
+--
+(//) :: (Prim a)
+     => Vector m a      -- ^ initial vector (of length @m@)
+     -> [(Finite m, a)] -- ^ list of index/value pairs (of length @n@)
+     -> Vector m a
+(//) = (V.//)
+{-# inline (//) #-}
+
+-- | /O(m+n)/ For each index @i@ from the index vector and the
+-- corresponding value @a@ from the value vector, replace the element of the
+-- initial vector at position @i@ by @a@.
+--
+-- > update_ <5,9,2,7>  <2,0,2> <1,3,8> = <3,9,8,7>
+--
+-- This function is useful for instances of 'Vector' that cannot store pairs.
+-- Otherwise, 'update' is probably more convenient.
+--
+-- @
+-- update_ xs is ys = 'update' xs ('zip' is ys)
+-- @
+update_ :: Prim a
+        => Vector m a   -- ^ initial vector (of length @m@)
+        -> Vector n Int -- ^ index vector (of length @n@)
+        -> Vector n a   -- ^ value vector (of length @n@)
+        -> Vector m a
+update_ = V.update_
+{-# inline update_ #-}
+
+-- | Same as ('//') but without bounds checking.
+unsafeUpd :: (Prim a)
+          => Vector m a -- ^ initial vector (of length @m@)
+          -> [(Int, a)]   -- ^ list of index/value pairs (of length @n@)
+          -> Vector m a
+unsafeUpd = V.unsafeUpd
+{-# inline unsafeUpd #-}
+
+-- | Same as 'update_' but without bounds checking.
+unsafeUpdate_ :: Prim a
+              => Vector m a   -- ^ initial vector (of length @m@)
+              -> Vector n Int -- ^ index vector (of length @n@)
+              -> Vector n a   -- ^ value vector (of length @n@)
+              -> Vector m a
+unsafeUpdate_ = V.unsafeUpdate_
+{-# inline unsafeUpdate_ #-}
+
+--
+-- ** Accumulations
+--
+
+-- | /O(m+n)/ For each pair @(i,b)@ from the list, replace the vector element
+-- @a@ at position @i@ by @f a b@.
+--
+-- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4>
+accum :: Prim a
+      => (a -> b -> a) -- ^ accumulating function @f@
+      -> Vector m a  -- ^ initial vector (of length @m@)
+      -> [(Int,b)]     -- ^ list of index/value pairs (of length @n@)
+      -> Vector m a
+accum = V.accum
+{-# inline accum #-}
+
+-- | /O(m+n)/ For each index @i@ from the index vector and the
+-- corresponding value @b@ from the the value vector,
+-- replace the element of the initial vector at
+-- position @i@ by @f a b@.
+--
+-- > accumulate_ (+) <5,9,2> <2,1,0,1> <4,6,3,7> = <5+3, 9+6+7, 2+4>
+--
+-- This function is useful for instances of 'Vector' that cannot store pairs.
+-- Otherwise, 'accumulate' is probably more convenient:
+--
+-- @
+-- accumulate_ f as is bs = 'accumulate' f as ('zip' is bs)
+-- @
+accumulate_ :: (Prim a, Prim b)
+            => (a -> b -> a)  -- ^ accumulating function @f@
+            -> Vector m a   -- ^ initial vector (of length @m@)
+            -> Vector n Int -- ^ index vector (of length @n@)
+            -> Vector n b   -- ^ value vector (of length @n@)
+            -> Vector m a
+accumulate_ = V.accumulate_
+{-# inline accumulate_ #-}
+
+-- | Same as 'accum' but without bounds checking.
+unsafeAccum :: Prim a
+            => (a -> b -> a) -- ^ accumulating function @f@
+            -> Vector m a  -- ^ initial vector (of length @m@)
+            -> [(Int,b)]     -- ^ list of index/value pairs (of length @n@)
+            -> Vector m a
+unsafeAccum = V.unsafeAccum
+{-# inline unsafeAccum #-}
+
+-- | Same as 'accumulate_' but without bounds checking.
+unsafeAccumulate_ :: (Prim a, Prim b)
+            => (a -> b -> a)  -- ^ accumulating function @f@
+            -> Vector m a   -- ^ initial vector (of length @m@)
+            -> Vector n Int -- ^ index vector (of length @n@)
+            -> Vector n b   -- ^ value vector (of length @n@)
+            -> Vector m a
+unsafeAccumulate_ = V.unsafeAccumulate_
+{-# inline unsafeAccumulate_ #-}
+
+--
+-- ** Permutations
+--
+
+-- | /O(n)/ Reverse a vector.
+reverse :: (Prim a) => Vector n a -> Vector n a
+reverse = V.reverse
+{-# inline reverse #-}
+
+-- | /O(n)/ Yield the vector obtained by replacing each element @i@ of the
+-- index vector by @xs'!'i@. This is equivalent to @'map' (xs'!') is@ but is
+-- often much more efficient.
+--
+-- > backpermute <a,b,c,d> <0,3,2,3,1,0> = <a,d,c,d,b,a>
+backpermute :: Prim a
+            => Vector m a   -- ^ @xs@ value vector
+            -> Vector n Int -- ^ @is@ index vector (of length @n@)
+            -> Vector n a
+backpermute = V.backpermute
+{-# inline backpermute #-}
+
+-- | Same as 'backpermute' but without bounds checking.
+unsafeBackpermute :: Prim a
+                  => Vector m a   -- ^ @xs@ value vector
+                  -> Vector n Int -- ^ @is@ index vector (of length @n@)
+                  -> Vector n a
+unsafeBackpermute = V.unsafeBackpermute
+{-# inline unsafeBackpermute #-}
+
+--------------------------------------------------------------------------------
+-- * Elementwise Operations
+--------------------------------------------------------------------------------
+
+--
+-- ** Mapping
+--
+
+-- | /O(n)/ Map a function over a vector.
+map :: (Prim a, Prim b)
+    => (a -> b) -> Vector n a -> Vector n b
+map = V.map
+{-# inline map #-}
+
+-- | /O(n)/ Apply a function to every element of a vector and its index.
+imap :: (Prim a, Prim b)
+     => (Finite n -> a -> b) -> Vector n a -> Vector n b
+imap = V.imap
+{-# inline imap #-}
+
+-- | /O(n*m)/ Map a function over a vector and concatenate the results. The
+-- function is required to always return the same length vector.
+concatMap :: (Prim a, Prim b)
+          => (a -> Vector m b) -> Vector n a -> Vector (n*m) b
+concatMap = V.concatMap
+{-# inline concatMap #-}
+
+--
+-- ** Monadic mapping
+--
+
+-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a
+-- vector of results.
+mapM :: (Monad m, Prim a, Prim b)
+      => (a -> m b) -> Vector n a -> m (Vector n b)
+mapM = V.mapM
+{-# inline mapM #-}
+
+-- | /O(n)/ Apply the monadic action to every element of a vector and its
+-- index, yielding a vector of results.
+imapM :: (Monad m, Prim a, Prim b)
+      => (Finite n -> a -> m b) -> Vector n a -> m (Vector n b)
+imapM = V.imapM
+{-# inline imapM #-}
+
+-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the
+-- results.
+mapM_ :: (Monad m, Prim a) => (a -> m b) -> Vector n a -> m ()
+mapM_ = V.mapM_
+{-# inline mapM_ #-}
+
+-- | /O(n)/ Apply the monadic action to every element of a vector and its
+-- index, ignoring the results.
+imapM_ :: (Monad m, Prim a) => (Finite n -> a -> m b) -> Vector n a -> m ()
+imapM_ = V.imapM_
+{-# inline imapM_ #-}
+
+-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a
+-- vector of results. Equvalent to @flip 'mapM'@.
+forM :: (Monad m, Prim a, Prim b)
+     => Vector n a -> (a -> m b) -> m (Vector n b)
+forM = V.forM
+{-# inline forM #-}
+
+-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the
+-- results. Equivalent to @flip 'mapM_'@.
+forM_ :: (Monad m, Prim a) => Vector n a -> (a -> m b) -> m ()
+forM_ = V.forM_
+{-# inline forM_ #-}
+
+--
+-- ** Zipping
+--
+
+-- | /O(n)/ Zip two vectors of the same length with the given function.
+zipWith :: (Prim a, Prim b, Prim c)
+        => (a -> b -> c) -> Vector n a -> Vector n b -> Vector n c
+zipWith = V.zipWith
+{-# inline zipWith #-}
+
+-- | Zip three vectors with the given function.
+zipWith3 :: (Prim a, Prim b, Prim c, Prim d)
+         => (a -> b -> c -> d) -> Vector n a -> Vector n b -> Vector n c -> Vector n d
+zipWith3 = V.zipWith3
+{-# inline zipWith3 #-}
+
+zipWith4 :: (Prim a,Prim b,Prim c,Prim d,Prim e)
+         => (a -> b -> c -> d -> e)
+         -> Vector n a
+         -> Vector n b
+         -> Vector n c
+         -> Vector n d
+         -> Vector n e
+zipWith4 = V.zipWith4
+{-# inline zipWith4 #-}
+
+zipWith5 :: (Prim a,Prim b,Prim c,Prim d,Prim e,Prim f)
+         => (a -> b -> c -> d -> e -> f)
+         -> Vector n a
+         -> Vector n b
+         -> Vector n c
+         -> Vector n d
+         -> Vector n e
+         -> Vector n f
+zipWith5 = V.zipWith5
+{-# inline zipWith5 #-}
+
+zipWith6 :: (Prim a,Prim b,Prim c,Prim d,Prim e,Prim f,Prim g)
+         => (a -> b -> c -> d -> e -> f -> g)
+         -> Vector n a
+         -> Vector n b
+         -> Vector n c
+         -> Vector n d
+         -> Vector n e
+         -> Vector n f
+         -> Vector n g
+zipWith6 = V.zipWith6
+{-# inline zipWith6 #-}
+
+-- | /O(n)/ Zip two vectors of the same length with a function that also takes
+-- the elements' indices).
+izipWith :: (Prim a,Prim b,Prim c)
+         => (Finite n -> a -> b -> c)
+         -> Vector n a
+         -> Vector n b
+         -> Vector n c
+izipWith = V.izipWith
+{-# inline izipWith #-}
+
+izipWith3 :: (Prim a,Prim b,Prim c,Prim d)
+          => (Finite n -> a -> b -> c -> d)
+          -> Vector n a
+          -> Vector n b
+          -> Vector n c
+          -> Vector n d
+izipWith3 = V.izipWith3
+{-# inline izipWith3 #-}
+
+izipWith4 :: (Prim a,Prim b,Prim c,Prim d,Prim e)
+          => (Finite n -> a -> b -> c -> d -> e)
+          -> Vector n a
+          -> Vector n b
+          -> Vector n c
+          -> Vector n d
+          -> Vector n e
+izipWith4 = V.izipWith4
+{-# inline izipWith4 #-}
+
+izipWith5 :: (Prim a,Prim b,Prim c,Prim d,Prim e,Prim f)
+          => (Finite n -> a -> b -> c -> d -> e -> f)
+          -> Vector n a
+          -> Vector n b
+          -> Vector n c
+          -> Vector n d
+          -> Vector n e
+          -> Vector n f
+izipWith5 = V.izipWith5
+{-# inline izipWith5 #-}
+
+izipWith6 :: (Prim a,Prim b,Prim c,Prim d,Prim e,Prim f,Prim g)
+          => (Finite n -> a -> b -> c -> d -> e -> f -> g)
+          -> Vector n a
+          -> Vector n b
+          -> Vector n c
+          -> Vector n d
+          -> Vector n e
+          -> Vector n f
+          -> Vector n g
+izipWith6 = V.izipWith6
+{-# inline izipWith6 #-}
+
+--
+-- ** Monadic zipping
+--
+
+-- | /O(n)/ Zip the two vectors of the same length with the monadic action and
+-- yield a vector of results.
+zipWithM :: (Monad m, Prim a, Prim b, Prim c)
+         => (a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)
+zipWithM = V.zipWithM
+{-# inline zipWithM #-}
+
+-- | /O(n)/ Zip the two vectors with a monadic action that also takes the
+-- element index and yield a vector of results.
+izipWithM :: (Monad m, Prim a, Prim b, Prim c)
+         => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)
+izipWithM = V.izipWithM
+{-# inline izipWithM #-}
+
+-- | /O(n)/ Zip the two vectors with the monadic action and ignore the results.
+zipWithM_ :: (Monad m, Prim a, Prim b)
+          => (a -> b -> m c) -> Vector n a -> Vector n b -> m ()
+zipWithM_ = V.zipWithM_
+{-# inline zipWithM_ #-}
+
+-- | /O(n)/ Zip the two vectors with a monadic action that also takes
+-- the element index and ignore the results.
+izipWithM_ :: (Monad m, Prim a, Prim b)
+           => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m ()
+izipWithM_ = V.izipWithM_
+{-# inline izipWithM_ #-}
+
+--------------------------------------------------------------------------------
+-- * Working with predicates
+--------------------------------------------------------------------------------
+
+--
+-- ** Searching
+--
+
+
+infix 4 `elem`
+-- | /O(n)/ Check if the vector contains an element.
+elem :: (Prim a, Eq a) => a -> Vector n a -> Bool
+elem = V.elem
+{-# inline elem #-}
+
+infix 4 `notElem`
+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem').
+notElem :: (Prim a, Eq a) => a -> Vector n a -> Bool
+notElem = V.notElem
+{-# inline notElem #-}
+
+-- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing'
+-- if no such element exists.
+find :: Prim a => (a -> Bool) -> Vector n a -> Maybe a
+find = V.find
+{-# inline find #-}
+
+-- | /O(n)/ Yield 'Just' the index of the first element matching the predicate
+-- or 'Nothing' if no such element exists.
+findIndex :: Prim a => (a -> Bool) -> Vector n a -> Maybe (Finite n)
+findIndex = V.findIndex
+{-# inline findIndex #-}
+
+-- | /O(n)/ Yield 'Just' the index of the first occurence of the given element or
+-- 'Nothing' if the vector does not contain the element. This is a specialised
+-- version of 'findIndex'.
+elemIndex :: (Prim a, Eq a) => a -> Vector n a -> Maybe (Finite n)
+elemIndex = V.elemIndex
+{-# inline elemIndex #-}
+
+--------------------------------------------------------------------------------
+-- * Folding
+--------------------------------------------------------------------------------
+
+-- | /O(n)/ Left fold.
+foldl :: Prim b => (a -> b -> a) -> a -> Vector n b -> a
+foldl = V.foldl
+{-# inline foldl #-}
+
+-- | /O(n)/ Left fold on non-empty vectors.
+foldl1 :: Prim a => (a -> a -> a) -> Vector (1+n) a -> a
+foldl1 = V.foldl1
+{-# inline foldl1 #-}
+
+-- | /O(n)/ Left fold with strict accumulator.
+foldl' :: Prim b => (a -> b -> a) -> a -> Vector n b -> a
+foldl' = V.foldl'
+{-# inline foldl' #-}
+
+-- | /O(n)/ Left fold on non-empty vectors with strict accumulator.
+foldl1' :: Prim a => (a -> a -> a) -> Vector (1+n) a -> a
+foldl1' = V.foldl1'
+{-# inline foldl1' #-}
+
+-- | /O(n)/ Right fold.
+foldr :: Prim a => (a -> b -> b) -> b -> Vector n a -> b
+foldr = V.foldr
+{-# inline foldr #-}
+
+-- | /O(n)/ Right fold on non-empty vectors.
+foldr1 :: Prim a => (a -> a -> a) -> Vector (n+1) a -> a
+foldr1 = V.foldr1
+{-# inline foldr1 #-}
+
+-- | /O(n)/ Right fold with a strict accumulator.
+foldr' :: Prim a => (a -> b -> b) -> b -> Vector n a -> b
+foldr' = V.foldr'
+{-# inline foldr' #-}
+
+-- | /O(n)/ Right fold on non-empty vectors with strict accumulator.
+foldr1' :: Prim a => (a -> a -> a) -> Vector (n+1) a -> a
+foldr1' = V.foldr1'
+{-# inline foldr1' #-}
+
+-- | /O(n)/ Left fold (function applied to each element and its index).
+ifoldl :: Prim b => (a -> Finite n -> b -> a) -> a -> Vector n b -> a
+ifoldl = V.ifoldl
+{-# inline ifoldl #-}
+
+-- | /O(n)/ Left fold with strict accumulator (function applied to each element
+-- and its index).
+ifoldl' :: Prim b => (a -> Finite n -> b -> a) -> a -> Vector n b -> a
+ifoldl' = V.ifoldl'
+{-# inline ifoldl' #-}
+
+-- | /O(n)/ Right fold (function applied to each element and its index).
+ifoldr :: Prim a => (Finite n -> a -> b -> b) -> b -> Vector n a -> b
+ifoldr = V.ifoldr
+{-# inline ifoldr #-}
+
+-- | /O(n)/ Right fold with strict accumulator (function applied to each
+-- element and its index).
+ifoldr' :: Prim a => (Finite n -> a -> b -> b) -> b -> Vector n a -> b
+ifoldr' = V.ifoldr'
+{-# inline ifoldr' #-}
+
+-- ** Specialised folds
+
+-- | /O(n)/ Check if all elements satisfy the predicate.
+all :: Prim a => (a -> Bool) -> Vector n a -> Bool
+all = V.all
+{-# inline all #-}
+
+-- | /O(n)/ Check if any element satisfies the predicate.
+any :: Prim a => (a -> Bool) -> Vector n a -> Bool
+any = V.any
+{-# inline any #-}
+
+-- | /O(n)/ Compute the sum of the elements.
+sum :: (Prim a, Num a) => Vector n a -> a
+sum = V.sum
+{-# inline sum #-}
+
+-- | /O(n)/ Compute the product of the elements.
+product :: (Prim a, Num a) => Vector n a -> a
+product = V.product
+{-# inline product #-}
+
+-- | /O(n)/ Yield the maximum element of the non-empty vector.
+maximum :: (Prim a, Ord a) => Vector (n+1) a -> a
+maximum = V.maximum
+{-# inline maximum #-}
+
+-- | /O(n)/ Yield the maximum element of the non-empty vector according to the
+-- given comparison function.
+maximumBy :: Prim a
+          => (a -> a -> Ordering) -> Vector (n+1) a -> a
+maximumBy = V.maximumBy
+{-# inline maximumBy #-}
+
+-- | /O(n)/ Yield the minimum element of the non-empty vector.
+minimum :: (Prim a, Ord a) => Vector (n+1) a -> a
+minimum = V.minimum
+{-# inline minimum #-}
+
+-- | /O(n)/ Yield the minimum element of the non-empty vector according to the
+-- given comparison function.
+minimumBy :: Prim a
+          => (a -> a -> Ordering) -> Vector (n+1) a -> a
+minimumBy = V.minimumBy
+{-# inline minimumBy #-}
+
+-- | /O(n)/ Yield the index of the maximum element of the non-empty vector.
+maxIndex :: (Prim a, Ord a) => Vector (n+1) a -> Finite (n + 1)
+maxIndex = V.maxIndex
+{-# inline maxIndex #-}
+
+-- | /O(n)/ Yield the index of the maximum element of the non-empty vector
+-- according to the given comparison function.
+maxIndexBy :: Prim a
+           => (a -> a -> Ordering) -> Vector (n+1) a -> Finite (n + 1)
+maxIndexBy = V.maxIndexBy
+{-# inline maxIndexBy #-}
+
+-- | /O(n)/ Yield the index of the minimum element of the non-empty vector.
+minIndex :: (Prim a, Ord a) => Vector (n+1) a -> Finite (n + 1)
+minIndex = V.minIndex
+{-# inline minIndex #-}
+
+-- | /O(n)/ Yield the index of the minimum element of the non-empty vector
+-- according to the given comparison function.
+minIndexBy :: Prim a
+           => (a -> a -> Ordering) -> Vector (n+1) a -> Finite (n + 1)
+minIndexBy = V.minIndexBy
+{-# inline minIndexBy #-}
+
+-- ** Monadic folds
+
+-- | /O(n)/ Monadic fold.
+foldM :: (Monad m, Prim b) => (a -> b -> m a) -> a -> Vector n b -> m a
+foldM = V.foldM
+{-# inline foldM #-}
+
+-- | /O(n)/ Monadic fold (action applied to each element and its index).
+ifoldM :: (Monad m, Prim b) => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a
+ifoldM = V.ifoldM
+{-# inline ifoldM #-}
+
+-- | /O(n)/ Monadic fold over non-empty vectors.
+fold1M :: (Monad m, Prim a)
+       => (a -> a -> m a) -> Vector (1+n) a -> m a
+fold1M = V.fold1M
+{-# inline fold1M #-}
+
+-- | /O(n)/ Monadic fold with strict accumulator.
+foldM' :: (Monad m, Prim b) => (a -> b -> m a) -> a -> Vector n b -> m a
+foldM' = V.foldM'
+{-# inline foldM' #-}
+
+-- | /O(n)/ Monadic fold with strict accumulator (action applied to each
+-- element and its index).
+ifoldM' :: (Monad m, Prim b)
+        => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a
+ifoldM' = V.ifoldM'
+{-# inline ifoldM' #-}
+
+-- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator.
+fold1M' :: (Monad m, Prim a)
+        => (a -> a -> m a) -> Vector (n+1) a -> m a
+fold1M' = V.fold1M'
+{-# inline fold1M' #-}
+
+-- | /O(n)/ Monadic fold that discards the result.
+foldM_ :: (Monad m, Prim b)
+       => (a -> b -> m a) -> a -> Vector n b -> m ()
+foldM_ = V.foldM_
+{-# inline foldM_ #-}
+
+-- | /O(n)/ Monadic fold that discards the result (action applied to
+-- each element and its index).
+ifoldM_ :: (Monad m, Prim b)
+        => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()
+ifoldM_ = V.ifoldM_
+{-# inline ifoldM_ #-}
+
+-- | /O(n)/ Monadic fold over non-empty vectors that discards the result.
+fold1M_ :: (Monad m, Prim a)
+        => (a -> a -> m a) -> Vector (n+1) a -> m ()
+fold1M_ = V.fold1M_
+{-# inline fold1M_ #-}
+
+-- | /O(n)/ Monadic fold with strict accumulator that discards the result.
+foldM'_ :: (Monad m, Prim b)
+        => (a -> b -> m a) -> a -> Vector n b -> m ()
+foldM'_ = V.foldM'_
+{-# inline foldM'_ #-}
+
+-- | /O(n)/ Monadic fold with strict accumulator that discards the result
+-- (action applied to each element and its index).
+ifoldM'_ :: (Monad m, Prim b)
+         => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()
+ifoldM'_ = V.ifoldM'_
+{-# inline ifoldM'_ #-}
+
+-- | /O(n)/ Monad fold over non-empty vectors with strict accumulator
+-- that discards the result.
+fold1M'_ :: (Monad m, Prim a)
+         => (a -> a -> m a) -> Vector (n+1) a -> m ()
+fold1M'_ = V.fold1M'_
+{-# inline fold1M'_ #-}
+
+--------------------------------------------------------------------------------
+-- * Prefix sums (scans)
+--------------------------------------------------------------------------------
+
+-- | /O(n)/ Prescan.
+--
+-- @
+-- prescanl f z = 'init' . 'scanl' f z
+-- @
+--
+-- Example: @prescanl (+) 0 \<1,2,3,4\> = \<0,1,3,6\>@
+--
+prescanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
+prescanl = V.prescanl
+{-# inline prescanl #-}
+
+-- | /O(n)/ Prescan with strict accumulator.
+prescanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
+prescanl' = V.prescanl'
+{-# inline prescanl' #-}
+
+-- | /O(n)/ Scan.
+postscanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
+postscanl = V.postscanl
+{-# inline postscanl #-}
+
+-- | /O(n)/ Scan with strict accumulator.
+postscanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
+postscanl' = V.postscanl'
+{-# inline postscanl' #-}
+
+-- | /O(n)/ Haskell-style scan.
+scanl :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector (1+n) a
+scanl = V.scanl
+{-# inline scanl #-}
+
+-- | /O(n)/ Haskell-style scan with strict accumulator.
+scanl' :: (Prim a, Prim b) => (a -> b -> a) -> a -> Vector n b -> Vector (1+n) a
+scanl' = V.scanl'
+{-# inline scanl' #-}
+
+-- | /O(n)/ Scan over a non-empty vector.
+scanl1 :: Prim a => (a -> a -> a) -> Vector (1+n) a -> Vector (2+n) a
+scanl1 = V.scanl1
+{-# inline scanl1 #-}
+
+-- | /O(n)/ Scan over a non-empty vector with a strict accumulator.
+scanl1' :: Prim a => (a -> a -> a) -> Vector (1+n) a -> Vector (2+n) a
+scanl1' = V.scanl1'
+{-# inline scanl1' #-}
+
+-- | /O(n)/ Right-to-left prescan.
+prescanr :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
+prescanr = V.prescanr
+{-# inline prescanr #-}
+
+-- | /O(n)/ Right-to-left prescan with strict accumulator.
+prescanr' :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
+prescanr' = V.prescanr'
+{-# inline prescanr' #-}
+
+-- | /O(n)/ Right-to-left scan.
+postscanr :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
+postscanr = V.postscanr
+{-# inline postscanr #-}
+
+-- | /O(n)/ Right-to-left scan with strict accumulator.
+postscanr' :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
+postscanr' = V.postscanr'
+{-# inline postscanr' #-}
+
+-- | /O(n)/ Right-to-left Haskell-style scan.
+scanr :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector (n+1) b
+scanr = V.scanr
+{-# inline scanr #-}
+
+-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator.
+scanr' :: (Prim a, Prim b) => (a -> b -> b) -> b -> Vector n a -> Vector (n+1) b
+scanr' = V.scanr'
+{-# inline scanr' #-}
+
+-- | /O(n)/ Right-to-left scan over a non-empty vector.
+scanr1 :: Prim a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+2) a
+scanr1 = V.scanr1
+{-# inline scanr1 #-}
+
+-- | /O(n)/ Right-to-left scan over a non-empty vector with a strict
+-- accumulator.
+scanr1' :: Prim a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+2) a
+scanr1' = V.scanr1'
+{-# inline scanr1' #-}
+
+
+-- * Conversions
+
+-- ** Lists
+
+-- | /O(n)/ Convert a vector to a list.
+toList :: Prim a => Vector n a -> [a]
+toList = V.toList
+{-# inline toList #-}
+
+-- | /O(n)/ Convert a list to a vector.
+fromList :: (Prim a, KnownNat n) => [a] -> Maybe (Vector n a)
+fromList = V.fromList
+{-# inline fromList #-}
+
+-- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
+-- the resulting vector is inferred from the type.
+fromListN :: forall n a. (Prim a, KnownNat n)
+          => [a] -> Maybe (Vector n a)
+fromListN = V.fromListN
+{-# inline fromListN #-}
+
+-- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
+-- the resulting vector is given explicitly as a 'Proxy' argument.
+fromListN' :: forall n a p. (Prim a, KnownNat n)
+           => p n -> [a] -> Maybe (Vector n a)
+fromListN' = V.fromListN'
+{-# inline fromListN' #-}
+
+-- | /O(n)/ Takes a list and returns a continuation providing a vector with
+-- a size parameter corresponding to the length of the list.
+--
+-- Essentially converts a list into a vector with the proper size
+-- parameter, determined at runtime.
+--
+-- See 'withSized'
+withSizedList :: forall a r. Prim a
+              => [a] -> (forall n. KnownNat n => Vector n a -> r) -> r
+withSizedList xs = withSized (VS.fromList xs)
+{-# inline withSizedList #-}
+
+-- ** Mutable vectors
+
+-- | /O(n)/ Yield an immutable copy of the mutable vector.
+freeze :: (PrimMonad m, Prim a)
+       => VSM.MVector n (PrimState m) a
+       -> m (Vector n a)
+freeze = V.freeze
+
+-- | /O(1)/ Unsafely convert a mutable vector to an immutable one withouy
+-- copying. The mutable vector may not be used after this operation.
+unsafeFreeze :: (PrimMonad m, Prim a)
+             => VSM.MVector n (PrimState m) a
+             -> m (Vector n a)
+unsafeFreeze = V.unsafeFreeze
+
+-- | /O(n)/ Yield a mutable copy of the immutable vector.
+thaw :: (PrimMonad m, Prim a)
+     => Vector n a
+     -> m (VSM.MVector n (PrimState m) a)
+thaw = V.thaw
+
+-- | /O(n)/ Unsafely convert an immutable vector to a mutable one without
+-- copying. The immutable vector may not be used after this operation.
+unsafeThaw :: (PrimMonad m, Prim a)
+           => Vector n a
+           -> m (VSM.MVector n (PrimState m) a)
+unsafeThaw = V.unsafeThaw
+
+-- | /O(n)/ Copy an immutable vector into a mutable one.
+copy :: (PrimMonad m, Prim a)
+     => VSM.MVector n (PrimState m) a
+     -> Vector n a
+     -> m ()
+copy = V.copy
+
+-- ** Unsized vectors
+
+-- | Convert a 'Data.Vector.Generic.Vector' into a
+-- 'Data.Vector.Generic.Sized.Vector' if it has the correct size, otherwise
+-- return 'Nothing'.
+toSized :: forall n a. (Prim a, KnownNat n)
+        => VS.Vector a -> Maybe (Vector n a)
+toSized = V.toSized
+{-# inline toSized #-}
+
+-- | Takes a 'Data.Vector.Primitive.Vector' and returns a continuation
+-- providing a 'Data.Vector.Primitive.Sized.Vector' with a size parameter
+-- @n@ that is determined at runtime based on the length of the input
+-- vector.
+--
+-- Essentially converts a 'Data.Vector.Primitive.Vector' into
+-- a 'Data.Vector.Primitive.Sized.Vector' with the correct size parameter
+-- @n@.
+withSized :: forall a r. Prim a
+          => VS.Vector a -> (forall n. KnownNat n => Vector n a -> r) -> r
+withSized = V.withSized
+{-# inline withSized #-}
+
+fromSized :: Vector n a -> VS.Vector a
+fromSized = V.fromSized
+{-# inline fromSized #-}
+
+-- | Apply a function on unsized vectors to a sized vector. The function must
+-- preserve the size of the vector, this is not checked.
+withVectorUnsafe :: forall a b (n :: Nat). ()
+                 => (VS.Vector a -> VS.Vector b) -> Vector n a -> Vector n b
+withVectorUnsafe = V.withVectorUnsafe
+{-# inline withVectorUnsafe #-}
+
+-- | Pattern synonym that lets you treat an unsized vector as if it
+-- "contained" a sized vector.  If you pattern match on an unsized vector,
+-- its contents will be the /sized/ vector counterpart.
+--
+-- @
+-- testFunc :: Unsized.Vector Int -> Int
+-- testFunc ('SomeSized' v) =
+--     'sum' ('zipWith' (+) v ('replicate' 1))
+--         -- ^ here, v is `Sized.Vector n Int`, and we have
+--                     `'KnownNat' n`
+-- @
+--
+-- The @n@ type variable will be properly instantiated to whatever the
+-- length of the vector is, and you will also have a @'KnownNat' n@
+-- instance available.  You can get @n@ in scope by turning on
+-- ScopedTypeVariables and matching on @'SomeSized' (v :: Sized.Vector
+-- n Int)@.
+--
+-- Without this, you would otherwise have to use 'withSized' to do the same
+-- thing:
+--
+-- @
+-- testFunc :: Unsized.Vector Int -> Int
+-- testFunc u = 'withSized' u $ \\v ->
+--     'sum' ('zipWith' (+) v ('replicate' 1))
+-- @
+--
+-- Remember that the type of final result of your function (the @Int@,
+-- here) must /not/ depend on @n@.  However, the types of the intermediate
+-- values are allowed to depend on @n@.
+--
+-- This is /especially/ useful in do blocks, where you can pattern match on
+-- the unsized results of actions, to use the sized vector in the rest of
+-- the do block.  You also get a @'KnownNat' n@ constraint for the
+-- remainder of the do block.
+--
+-- @
+-- -- If you had:
+-- getAVector :: IO (Unsized.Vector Int)
+--
+-- main :: IO ()
+-- main = do
+--     SomeSized v <- getAVector -- v is `Sized.Vector n Int`
+--     -- get n in scope
+--     SomeSized (v :: Sized.Vector n Int) <- getAVector
+--     print v
+-- @
+--
+-- Remember that the final type of the result of the do block ('()', here)
+-- must not depend on @n@.  However, the
+--
+-- Also useful in ghci, where you can pattern match to get sized vectors
+-- from unsized vectors.
+--
+-- @
+-- ghci> SomeSized v <- pure (myUnsizedVector :: Unsized.Vector Int)
+--              -- ^ v is `Sized.Vector n Int`
+-- @
+--
+-- This enables interactive exploration with sized vectors in ghci, and is
+-- useful for using with other libraries and functions that expect sized
+-- vectors in an interactive setting.
+--
+-- (Note that as of GHC 8.6, you cannot get the @n@ in scope in your ghci
+-- session using ScopedTypeVariables, like you can with do blocks)
+--
+-- You can also use this as a constructor, to take a sized vector and
+-- "hide" the size, to produce an unsized vector:
+--
+-- @
+-- SomeSized :: Sized.Vector n a -> Unsized.Vector a
+-- @
+pattern SomeSized :: Prim a => KnownNat n => Vector n a -> VS.Vector a
+pattern SomeSized v = V.SomeSized v
+{-# complete SomeSized #-}
diff --git a/vector-sized.cabal b/vector-sized.cabal
--- a/vector-sized.cabal
+++ b/vector-sized.cabal
@@ -1,13 +1,11 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.33.0.
+-- This file has been generated from package.yaml by hpack version 0.34.2.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: ee1654a35ad22a0b6764be7fe44e3e0c7b29dbf714956529471c549c06bfa011
 
 name:           vector-sized
-version:        1.4.2
+version:        1.4.3
 synopsis:       Size tagged vectors
 description:    Please see README.md
 category:       Data
@@ -20,10 +18,10 @@
 license-file:   LICENSE
 build-type:     Simple
 extra-source-files:
+    package.yaml
     readme.md
     changelog.md
     default.nix
-    shell.nix
 
 source-repository head
   type: git
@@ -31,16 +29,18 @@
 
 library
   exposed-modules:
-      Data.Vector.Sized
+      Data.Vector.Generic.Mutable.Sized
+      Data.Vector.Generic.Mutable.Sized.Internal
       Data.Vector.Generic.Sized
       Data.Vector.Generic.Sized.Internal
-      Data.Vector.Storable.Sized
       Data.Vector.Mutable.Sized
-      Data.Vector.Generic.Mutable.Sized
+      Data.Vector.Primitive.Mutable.Sized
+      Data.Vector.Primitive.Sized
+      Data.Vector.Sized
       Data.Vector.Storable.Mutable.Sized
-      Data.Vector.Generic.Mutable.Sized.Internal
-      Data.Vector.Unboxed.Sized
+      Data.Vector.Storable.Sized
       Data.Vector.Unboxed.Mutable.Sized
+      Data.Vector.Unboxed.Sized
   other-modules:
       Paths_vector_sized
   hs-source-dirs:
