diff --git a/src-imp/EmptyPrimArray.hs b/src-imp/EmptyPrimArray.hs
--- a/src-imp/EmptyPrimArray.hs
+++ b/src-imp/EmptyPrimArray.hs
@@ -1,10 +1,12 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language ScopedTypeVariables #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module EmptyPrimArray
diff --git a/src-imp/Int.hs b/src-imp/Int.hs
--- a/src-imp/Int.hs
+++ b/src-imp/Int.hs
@@ -1,10 +1,11 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module Int
@@ -30,9 +31,10 @@
   , gt#
   , eq#
   , max
+  , min
   ) where
 
-import Prelude hiding (max)
+import Prelude hiding (max,min)
 
 import GHC.Exts
 import Data.Kind (Type)
@@ -48,6 +50,10 @@
 max :: forall (a :: TYPE R). a -> a -> a
 {-# inline max #-}
 max x y = if gt x y then x else y
+
+min :: forall (a :: TYPE R). a -> a -> a
+{-# inline min #-}
+min x y = if gt x y then y else x
 
 lt :: forall (a :: TYPE R). a -> a -> Bool
 {-# inline lt #-}
diff --git a/src-imp/Int16.hs b/src-imp/Int16.hs
--- a/src-imp/Int16.hs
+++ b/src-imp/Int16.hs
@@ -1,10 +1,11 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module Int16
@@ -30,9 +31,10 @@
   , gt#
   , eq#
   , max
+  , min
   ) where
 
-import Prelude hiding (max)
+import Prelude hiding (max,min)
 
 import GHC.Exts
 import Data.Kind (Type)
@@ -154,6 +156,10 @@
 max :: forall (a :: TYPE R). a -> a -> a
 {-# inline max #-}
 max x y = if gt x y then x else y
+
+min :: forall (a :: TYPE R). a -> a -> a
+{-# inline min #-}
+min x y = if gt x y then y else x
 
 lt :: forall (a :: TYPE R). a -> a -> Bool
 {-# inline lt #-}
diff --git a/src-imp/Int32.hs b/src-imp/Int32.hs
--- a/src-imp/Int32.hs
+++ b/src-imp/Int32.hs
@@ -1,10 +1,11 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module Int32
@@ -29,12 +30,13 @@
   , gt#
   , eq#
   , max
+  , min
   , freeze#
     -- Metadata
   , size
   ) where
 
-import Prelude hiding (max)
+import Prelude hiding (max,min)
 
 import GHC.Exts
 import Data.Kind (Type)
@@ -64,6 +66,10 @@
 max :: forall (a :: TYPE R). a -> a -> a
 {-# inline max #-}
 max x y = if gt x y then x else y
+
+min :: forall (a :: TYPE R). a -> a -> a
+{-# inline min #-}
+min x y = if gt x y then y else x
 
 lt :: forall (a :: TYPE R). a -> a -> Bool
 {-# inline lt #-}
diff --git a/src-imp/Int64.hs b/src-imp/Int64.hs
--- a/src-imp/Int64.hs
+++ b/src-imp/Int64.hs
@@ -1,10 +1,11 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module Int64
@@ -30,11 +31,12 @@
   , gt#
   , eq#
   , max
+  , min
     -- Metadata
   , size
   ) where
 
-import Prelude hiding (max)
+import Prelude hiding (max,min)
 
 import GHC.Exts
 import Data.Kind (Type)
@@ -50,6 +52,10 @@
 max :: forall (a :: TYPE R). a -> a -> a
 {-# inline max #-}
 max x y = if gt x y then x else y
+
+min :: forall (a :: TYPE R). a -> a -> a
+{-# inline min #-}
+min x y = if gt x y then y else x
 
 lt :: forall (a :: TYPE R). a -> a -> Bool
 {-# inline lt #-}
diff --git a/src-imp/Int8.hs b/src-imp/Int8.hs
--- a/src-imp/Int8.hs
+++ b/src-imp/Int8.hs
@@ -1,9 +1,11 @@
+{-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module Int8
@@ -29,11 +31,12 @@
   , gt#
   , eq#
   , max
+  , min
     -- Metadata
   , size
   ) where
 
-import Prelude hiding (max)
+import Prelude hiding (max,min)
 
 import GHC.Exts
 import Data.Kind (Type)
@@ -142,6 +145,10 @@
 max :: forall (a :: TYPE R). a -> a -> a
 {-# inline max #-}
 max x y = if gt x y then x else y
+
+min :: forall (a :: TYPE R). a -> a -> a
+{-# inline min #-}
+min x y = if gt x y then y else x
 
 lt :: forall (a :: TYPE R). a -> a -> Bool
 {-# inline lt #-}
diff --git a/src-imp/Lifted.hs b/src-imp/Lifted.hs
--- a/src-imp/Lifted.hs
+++ b/src-imp/Lifted.hs
@@ -1,11 +1,12 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
-{-# language TypeApplications #-}
-{-# language TypeFamilies #-}
-{-# language TypeInType #-}
 {-# language ScopedTypeVariables #-}
 {-# language StandaloneKindSignatures #-}
+{-# language TypeApplications #-}
+{-# language TypeFamilies #-}
 {-# language UnboxedTuples #-}
 
 module Lifted
diff --git a/src-imp/Unlifted.hs b/src-imp/Unlifted.hs
--- a/src-imp/Unlifted.hs
+++ b/src-imp/Unlifted.hs
@@ -1,12 +1,13 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language GADTSyntax #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
 {-# language ScopedTypeVariables #-}
 {-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
 {-# language UnboxedTuples #-}
 {-# language UnliftedNewtypes #-}
 
diff --git a/src-imp/Word.hs b/src-imp/Word.hs
--- a/src-imp/Word.hs
+++ b/src-imp/Word.hs
@@ -1,10 +1,11 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module Word
diff --git a/src-imp/Word1.hs b/src-imp/Word1.hs
--- a/src-imp/Word1.hs
+++ b/src-imp/Word1.hs
@@ -1,10 +1,12 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language ScopedTypeVariables #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 -- Note: In this module, we assume that Word is a 64-bit number.
diff --git a/src-imp/Word128.hs b/src-imp/Word128.hs
--- a/src-imp/Word128.hs
+++ b/src-imp/Word128.hs
@@ -1,11 +1,12 @@
-{-# language CPP #-}
 {-# language BangPatterns #-}
+{-# language CPP #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module Word128
diff --git a/src-imp/Word16.hs b/src-imp/Word16.hs
--- a/src-imp/Word16.hs
+++ b/src-imp/Word16.hs
@@ -1,10 +1,11 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module Word16
@@ -30,11 +31,12 @@
   , gt#
   , eq#
   , max
+  , min
     -- Metadata
   , size
   ) where
 
-import Prelude hiding (max)
+import Prelude hiding (max,min)
 
 import GHC.Exts
 import Data.Kind (Type)
@@ -156,6 +158,10 @@
 max :: forall (a :: TYPE R). a -> a -> a
 {-# inline max #-}
 max x y = if gt x y then x else y
+
+min :: forall (a :: TYPE R). a -> a -> a
+{-# inline min #-}
+min x y = if gt x y then y else x
 
 lt :: forall (a :: TYPE R). a -> a -> Bool
 {-# inline lt #-}
diff --git a/src-imp/Word32.hs b/src-imp/Word32.hs
--- a/src-imp/Word32.hs
+++ b/src-imp/Word32.hs
@@ -1,10 +1,11 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module Word32
@@ -30,11 +31,12 @@
   , gt#
   , eq#
   , max
+  , min
     -- Metadata
   , size
   ) where
 
-import Prelude hiding (max)
+import Prelude hiding (max,min)
 
 import GHC.Exts
 import Data.Kind (Type)
@@ -156,6 +158,10 @@
 max :: forall (a :: TYPE R). a -> a -> a
 {-# inline max #-}
 max x y = if gt x y then x else y
+
+min :: forall (a :: TYPE R). a -> a -> a
+{-# inline min #-}
+min x y = if gt x y then y else x
 
 lt :: forall (a :: TYPE R). a -> a -> Bool
 {-# inline lt #-}
diff --git a/src-imp/Word64.hs b/src-imp/Word64.hs
--- a/src-imp/Word64.hs
+++ b/src-imp/Word64.hs
@@ -1,10 +1,11 @@
 {-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module Word64
@@ -30,11 +31,12 @@
   , gt#
   , eq#
   , max
+  , min
     -- Metadata
   , size
   ) where
 
-import Prelude hiding (max)
+import Prelude hiding (max,min)
 
 import GHC.Exts
 import Data.Kind (Type)
@@ -160,6 +162,10 @@
 max :: forall (a :: TYPE R). a -> a -> a
 {-# inline max #-}
 max x y = if gt x y then x else y
+
+min :: forall (a :: TYPE R). a -> a -> a
+{-# inline min #-}
+min x y = if gt x y then y else x
 
 lt :: forall (a :: TYPE R). a -> a -> Bool
 {-# inline lt #-}
diff --git a/src-imp/Word8.hs b/src-imp/Word8.hs
--- a/src-imp/Word8.hs
+++ b/src-imp/Word8.hs
@@ -1,9 +1,11 @@
+{-# language BangPatterns #-}
+{-# language DataKinds #-}
 {-# language MagicHash #-}
+{-# language PolyKinds #-}
 {-# language RankNTypes #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
 {-# language TypeFamilies #-}
-{-# language TypeInType #-}
-{-# language StandaloneKindSignatures #-}
 {-# language UnboxedTuples #-}
 
 module Word8
@@ -29,11 +31,12 @@
   , gt#
   , eq#
   , max
+  , min
     -- Metadata
   , size
   ) where
 
-import Prelude hiding (max)
+import Prelude hiding (max,min)
 
 import GHC.Exts
 import Data.Kind (Type)
@@ -142,6 +145,10 @@
 max :: forall (a :: TYPE R). a -> a -> a
 {-# inline max #-}
 max x y = if gt x y then x else y
+
+min :: forall (a :: TYPE R). a -> a -> a
+{-# inline min #-}
+min x y = if gt x y then y else x
 
 lt :: forall (a :: TYPE R). a -> a -> Bool
 {-# inline lt #-}
diff --git a/src-indef/Core.hs b/src-indef/Core.hs
--- a/src-indef/Core.hs
+++ b/src-indef/Core.hs
@@ -49,12 +49,14 @@
   , write#
   , write
   , initialized
+  , initialized#
   , empty#
   , empty
   , unsafeShrinkFreeze
   , copySlice
   , setSlice
   , freezeSlice
+  , freezeSlice#
   , unsafeFreeze
   , unsafeFreeze#
   , thawSlice
@@ -62,6 +64,7 @@
   , unsafeCoerceVector
   , unsafeCoerceVector#
   , substitute
+  , substitute#
   , expose
   , expose#
   ) where
@@ -149,6 +152,14 @@
 initialized !(Nat# n) a = ST $ \s0 -> case A.initialized# n a s0 of
   (# s1, x #) -> (# s1, MutableVector (MutableVector# x) #)
 
+initialized# :: forall (s :: Type) (n :: GHC.Nat) (a :: TYPE R).
+     Nat# n
+  -> a
+  -> State# s
+  -> (# State# s, MutableVector# s n a #)
+initialized# !(Nat# n) a s0 = case A.initialized# n a s0 of
+  (# s1, x #) -> (# s1, MutableVector# x #)
+
 write :: forall (s :: Type) (n :: GHC.Nat) (a :: TYPE R).
      MutableVector s n a
   -> Fin# n -- index
@@ -173,10 +184,23 @@
   -> Nat# i
   -> Nat# n
   -> ST s (Vector n a)
+{-# inline freezeSlice #-}
 freezeSlice _ (MutableVector (MutableVector# m)) (Nat# off) (Nat# len) =
   ST \s -> case A.freeze# m off len s of
     (# s', y #) -> (# s', Vector (Vector# y) #)
 
+freezeSlice# ::
+     (i + n <=# m)
+  -> MutableVector# s m a
+  -> Nat# i
+  -> Nat# n
+  -> State# s
+  -> (# State# s, Vector# n a #)
+{-# inline freezeSlice# #-}
+freezeSlice# _ (MutableVector# m) (Nat# off) (Nat# len) s =
+  case A.freeze# m off len s of
+    (# s', y #) -> (# s', Vector# y #)
+
 unsafeFreeze :: forall (s :: Type) (n :: GHC.Nat) (a :: TYPE R).
   MutableVector s n a -> ST s (Vector n a)
 unsafeFreeze (MutableVector (MutableVector# m)) =
@@ -213,7 +237,12 @@
     (# s1, mv #) -> (# s1, MutableVector (MutableVector# mv) #)
 
 substitute :: (m :=:# n) -> Vector m a -> Vector n a
-substitute !_ (Vector (Vector# x)) = Vector (Vector# x)
+{-# inline substitute #-}
+substitute _ (Vector (Vector# x)) = Vector (Vector# x)
+
+substitute# :: (m :=:# n) -> Vector# m a -> Vector# n a
+{-# inline substitute# #-}
+substitute# _ (Vector# x) = Vector# x
 
 -- | Tell the type system that a vector has a certain length
 --   without proving it.
diff --git a/src-indef/Vector.hs b/src-indef/Vector.hs
--- a/src-indef/Vector.hs
+++ b/src-indef/Vector.hs
@@ -1,18 +1,20 @@
 {-# language BangPatterns #-}
-{-# language PatternSynonyms #-}
 {-# language BlockArguments #-}
 {-# language DataKinds #-}
 {-# language ExplicitNamespaces #-}
 {-# language GADTs #-}
 {-# language KindSignatures #-}
 {-# language MagicHash #-}
-{-# language UnliftedNewtypes #-}
+{-# language PatternSynonyms #-}
 {-# language RankNTypes #-}
 {-# language ScopedTypeVariables #-}
+{-# language StandaloneKindSignatures #-}
 {-# language TypeApplications #-}
+{-# language TypeFamilies #-}
 {-# language TypeOperators #-}
-{-# language UnboxedTuples #-}
 {-# language UnboxedSums #-}
+{-# language UnboxedTuples #-}
+{-# language UnliftedNewtypes #-}
 
 -- The only operatations defined in this module are those
 -- that are considered primitive. That is, they cannot be
@@ -26,6 +28,7 @@
   , C.MutableVector#
   , Bounded(..)
   , Vector_(..)
+  , FromMutability#
   , vector_
     -- * Primitives
   , C.write#
@@ -35,7 +38,9 @@
   , C.index
   , unlift
   , C.substitute
+  , C.substitute#
   , C.initialized
+  , C.initialized#
   , C.empty#
   , C.empty
   , C.unsafeCoerceLength
@@ -44,6 +49,7 @@
   , C.expose
   , C.expose#
   , C.freezeSlice
+  , C.freezeSlice#
     -- * Ranges
   , set
   , C.setSlice
@@ -51,10 +57,15 @@
   , C.unsafeShrinkFreeze
   , C.unsafeFreeze
   , freeze
+  , freeze#
     -- * Copy
   , thaw
   , C.thawSlice
     -- * Composite
+  , tail
+  , cons
+  , snoc
+  , replaceAt
   , empty_
   , map
   , all
@@ -62,6 +73,7 @@
   , findIndex
   , traverse_
   , traverseZip_
+  , traverseST#
   , itraverse_
   , itraverse_#
   , foldlM
@@ -92,6 +104,7 @@
   , append
   , clone
   , cloneSlice
+  , C.copySlice
     -- * Index
   , index0
   , index1
@@ -104,13 +117,14 @@
   , index8
   ) where
 
-import Prelude hiding (read,map,Bounded,replicate,all,any,foldr)
+import Prelude hiding (read,map,Bounded,replicate,all,any,foldr,tail,head,init)
 
+import Types (Mutability(Mutable,Immutable))
 import Core (Vector(..),Vector#,MutableVector(..),unsafeFreeze,index,write)
 import Data.Unlifted (Maybe#(..))
 import Rep (R)
 import Element (A#,M#)
-import GHC.Exts (Int(I#),RuntimeRep)
+import GHC.Exts (Int(I#),RuntimeRep(BoxedRep),Levity(Unlifted))
 import GHC.ST (ST,runST)
 import Data.Kind (Type)
 import GHC.Exts (TYPE,State#,Int#,(*#))
@@ -150,6 +164,13 @@
     -> (Vector# n a)
     -> Vector_ a
 
+-- | A type family that helps the user define data types that support
+-- both mutable and immutable vectors.
+type FromMutability# :: Mutability -> (GHC.Nat -> TYPE R -> TYPE ('BoxedRep 'Unlifted))
+type family FromMutability# m :: (GHC.Nat -> TYPE R -> TYPE ('BoxedRep 'Unlifted)) where
+  FromMutability# 'Immutable = C.Vector#
+  FromMutability# ('Mutable s) = C.MutableVector# s
+
 ifoldlSlice' :: forall (i :: GHC.Nat) (m :: GHC.Nat) (n :: GHC.Nat) (a :: TYPE R) (b :: Type).
      (i + n <= m)
   -> (b -> Fin# (i + n) -> a -> b)
@@ -227,6 +248,26 @@
   (\fin -> f (index v fin) (index w fin)
   )
 
+traverseST# :: forall (n :: GHC.Nat) (s :: Type) (a :: TYPE R) (b :: TYPE R).
+     (a -> State# s -> (# State# s, b #))
+  -> Nat# n
+  -> Vector# n a
+  -> State# s
+  -> (# State# s, Vector# n b #)
+{-# inline traverseST# #-}
+traverseST# f n v s0 = case Nat.testZero# n of
+  LeftVoid# zeq -> (# s0, C.substitute# zeq (C.empty# (# #)) #)
+  RightVoid# zlt ->
+    let !(# s1, b0 #) = f (C.index# v (Fin.construct# zlt Nat.N0#)) s0 in
+    let !(# s2, dst #) = C.initialized# n b0 s1 in
+    let go :: forall p. Nat# p -> State# s -> (# State# s, Vector# n b #)
+        go m t0 = case m <?# n of
+          JustVoid# lt -> case f (C.index# v (Fin.construct# lt m)) t0 of
+            (# t1, e #) -> case C.write# dst (Fin.construct# lt m) e t1 of
+              t2 -> go (Nat.succ# m) t2
+          _ -> C.unsafeFreeze# dst t0
+     in go Nat.N1# s2
+
 itraverse_ :: forall (n :: GHC.Nat) (m :: Type -> Type) (a :: TYPE R) (b :: Type).
      Monad m
   => (Fin# n -> a -> m b)
@@ -299,6 +340,14 @@
 {-# inline freeze #-}
 freeze n mv = C.freezeSlice (Lte.reflexive# (# #)) mv (Nat.zero# (# #)) n
 
+freeze# :: 
+     Nat# n -- ^ Mutable vector length
+  -> C.MutableVector# s n a -- ^ Mutable vector
+  -> State# s
+  -> (# State# s, Vector# n a #)
+{-# inline freeze# #-}
+freeze# n mv = C.freezeSlice# (Lte.reflexive# (# #)) mv (Nat.zero# (# #)) n
+
 thaw :: 
      Nat# n -- ^ Vector length
   -> Vector n a -- ^ Mutable vector
@@ -515,3 +564,30 @@
             then MaybeFinJust# fin
             else go (Nat.succ# ix)
     _ -> MaybeFinNothing#
+
+replaceAt :: Nat# n -> Vector n a -> Fin# n -> a -> Vector n a
+{-# inline replaceAt #-}
+replaceAt n !v ix a = runST $ do
+  dst <- thaw n v
+  write dst ix a
+  unsafeFreeze dst
+
+cons :: forall n a. Nat# n -> Vector n a -> a -> Vector (n + 1) a
+{-# inline cons #-}
+cons n !v a = runST $ do
+  dst <- C.initialized (Nat.succ# n) a
+  C.copySlice (Lte.substituteL# (Plus.commutative# @n @1 (# #)) (Lte.reflexive# @(n + 1) (# #))) (Lte.reflexive# (# #)) dst N1# v N0# n
+  unsafeFreeze dst
+
+snoc :: forall n a. Nat# n -> Vector n a -> a -> Vector (n + 1) a
+{-# inline snoc #-}
+snoc n !v a = runST $ do
+  dst <- C.initialized (Nat.succ# n) a
+  C.copySlice (Lte.weakenR# @1 (Lte.reflexive# @n (# #))) (Lte.reflexive# @n (# #)) dst N0# v N0# n
+  unsafeFreeze dst
+
+tail :: forall n a. Nat# n -> Vector (n + 1) a -> Vector n a
+{-# inline tail #-}
+tail n v = runST $ do
+  dst <- C.thawSlice (Lte.substituteL# (Plus.commutative# @n @1 (# #)) (Lte.reflexive# @(n + 1) (# #))) v N1# n
+  unsafeFreeze dst
diff --git a/src-ord-indef/OrdVector.hs b/src-ord-indef/OrdVector.hs
--- a/src-ord-indef/OrdVector.hs
+++ b/src-ord-indef/OrdVector.hs
@@ -24,16 +24,20 @@
   , maximum
   , maximumSlice
   , maximumSliceInitial
+    -- * Minimum
+  , minimum
+  , minimumSlice
+  , minimumSliceInitial
     -- * Bubble Sort
   , bubbleSort
   , bubbleSortSlice
   , bubbleSortSliceInPlace
   ) where
 
-import Prelude hiding (Bounded,max,min,maximum)
+import Prelude hiding (Bounded,max,min,maximum,minimum)
 
 import EqVector (equals)
-import Rep (R,eq,max)
+import Rep (R,eq,max,min)
 import Vector (MutableVector(MutableVector),MutableVector#,Vector,Bounded(Bounded),index,write,write#,thaw,read#,unsafeShrinkFreeze,unsafeFreeze,thawSlice)
 import GHC.ST (ST(ST),runST)
 import Arithmetic.Types (type (<),Fin(Fin),Nat#)
@@ -90,6 +94,13 @@
   -> a
 maximum n lt v = maximumSlice (Lte.reflexive# (# #)) lt v (Nat.zero# (# #)) n
 
+minimum :: forall (n :: GHC.Nat) (a :: TYPE R).
+     Nat# n
+  -> (0 <# n)
+  -> Vector n a
+  -> a
+minimum n lt v = minimumSlice (Lte.reflexive# (# #)) lt v (Nat.zero# (# #)) n
+
 -- | Take the maximum element in a slice. The slice must not be empty.
 -- This is enforced by the type system.
 maximumSlice :: forall (i :: GHC.Nat) (m :: GHC.Nat) (n :: GHC.Nat) (a :: TYPE R).
@@ -103,6 +114,19 @@
   (index v (Fin.construct# (Lt.transitiveNonstrictR# zlt (Lte.decrementL# @i (Lte.weakenL# @i lte))) (Nat.zero# (# #))))
   v off0 n
 
+-- | Take the minimum element in a slice. The slice must not be empty.
+-- This is enforced by the type system.
+minimumSlice :: forall (i :: GHC.Nat) (m :: GHC.Nat) (n :: GHC.Nat) (a :: TYPE R).
+     (i + n <=# m)
+  -> (0 <# n)
+  -> Vector m a
+  -> Nat# i
+  -> Nat# n
+  -> a
+minimumSlice lte zlt v off0 n = minimumSliceInitial lte
+  (index v (Fin.construct# (Lt.transitiveNonstrictR# zlt (Lte.decrementL# @i (Lte.weakenL# @i lte))) (Nat.zero# (# #))))
+  v off0 n
+
 -- | Take the maximum element in a slice. This does not require
 -- the slice to be non-null. It takes an additional argument to
 -- use as the initial accumulator.
@@ -125,6 +149,29 @@
     Just lt -> go
       (Nat.succ# m)
       (max b (index v (Fin.construct# (Lt.transitiveNonstrictR# (Lt.unlift lt) lte) m)))
+
+-- | Take the minimum element in a slice. This does not require
+-- the slice to be non-null. It takes an additional argument to
+-- use as the initial accumulator.
+minimumSliceInitial :: forall (i :: GHC.Nat) (m :: GHC.Nat) (n :: GHC.Nat) (a :: TYPE R).
+     (i + n <=# m)
+  -> a -- initial minimum element
+  -> Vector m a
+  -> Nat# i
+  -> Nat# n
+  -> a
+{-# noinline minimumSliceInitial #-}
+minimumSliceInitial lte b0 !v off0 n = go off0 b0
+  where
+  end :: Nat# (i + n)
+  end = Nat.plus# off0 n
+  go :: forall k. Nat# k -> a -> a
+  {-# noinline go #-}
+  go !m !b = case Nat.lift m <? Nat.lift end of
+    Nothing -> b
+    Just lt -> go
+      (Nat.succ# m)
+      (min b (index v (Fin.construct# (Lt.transitiveNonstrictR# (Lt.unlift lt) lte) m)))
 
 bubbleSort ::
      Nat# n
diff --git a/src-ord-indef/Rep.hsig b/src-ord-indef/Rep.hsig
--- a/src-ord-indef/Rep.hsig
+++ b/src-ord-indef/Rep.hsig
@@ -13,3 +13,4 @@
 lt# :: forall (a :: TYPE R). a -> a -> Int#
 gt# :: forall (a :: TYPE R). a -> a -> Int#
 max :: forall (a :: TYPE R). a -> a -> a
+min :: forall (a :: TYPE R). a -> a -> a
diff --git a/src-types/Types.hs b/src-types/Types.hs
new file mode 100644
--- /dev/null
+++ b/src-types/Types.hs
@@ -0,0 +1,7 @@
+module Types
+  ( Mutability(..)
+  ) where
+
+import Data.Kind (Type)
+
+data Mutability = Mutable Type | Immutable
diff --git a/src/Vector/Bit.hs b/src/Vector/Bit.hs
--- a/src/Vector/Bit.hs
+++ b/src/Vector/Bit.hs
@@ -19,7 +19,9 @@
   , index
   , unlift
   , substitute
+  , substitute#
   , initialized
+  , initialized#
   , unsafeCoerceLength
   , expose
   , expose#
@@ -31,10 +33,16 @@
   , unsafeFreeze
   , freeze
   , freezeSlice
+  , freeze#
+  , freezeSlice#
     -- * Copy
   , thaw
     -- * Composite
   , map
+  , traverse_
+  , itraverse_
+  , itraverse_#
+  , traverseST#
   , ifoldl'
   , ifoldlSlice'
   , construct1
diff --git a/src/Vector/Int.hs b/src/Vector/Int.hs
--- a/src/Vector/Int.hs
+++ b/src/Vector/Int.hs
@@ -1,3 +1,4 @@
+{-# language BangPatterns #-}
 {-# language MagicHash #-}
 {-# language RankNTypes #-}
 
@@ -30,6 +31,11 @@
     -- * Copy
   , thaw
     -- * Composite
+  , tail
+  , cons
+  , snoc
+  , replaceAt
+  , findIndex
   , map
   , all
   , any
@@ -83,14 +89,24 @@
   , unsafeCoerceVector
     -- * Hide Length
   , vector_
+    -- * Recover Length
+  , length
   ) where
 
-import Prelude ()
+import Prelude (undefined)
 
-import Vector.Std.Int
-import Vector.Ord.Int
-import Vector.Eq.Int
-import Data.Primitive (SmallArray(SmallArray))
 import Arithmetic.Unsafe (Nat#(Nat#))
+import Data.Unlifted (PrimArray#(PrimArray#))
+import Foreign.Storable (sizeOf)
+import GHC.Int (Int)
+import Vector.Eq.Int
+import Vector.Ord.Int
+import Vector.Std.Int
 
 import qualified GHC.Exts as Exts
+
+length :: Vector n a -> Nat# n
+{-# inline length #-}
+length !v = case expose v of
+  PrimArray# x -> case (sizeOf (undefined :: Int)) of
+    Exts.I# i -> Nat# (Exts.quotInt# (Exts.sizeofByteArray# x) i)
diff --git a/src/Vector/Int16.hs b/src/Vector/Int16.hs
--- a/src/Vector/Int16.hs
+++ b/src/Vector/Int16.hs
@@ -13,6 +13,7 @@
   , MutableVector#
   , Bounded(..)
   , Vector_(..)
+  , FromMutability#
     -- * Primitives
   , write#
   , write
@@ -21,7 +22,9 @@
   , index
   , unlift
   , substitute
+  , substitute#
   , initialized
+  , initialized#
   , unsafeCoerceLength
   , expose
   , expose#
@@ -33,10 +36,16 @@
   , unsafeFreeze
   , freeze
   , freezeSlice
+  , freeze#
+  , freezeSlice#
     -- * Copy
   , thaw
     -- * Composite
   , map
+  , traverse_
+  , itraverse_
+  , itraverse_#
+  , traverseST#
   , ifoldl'
   , ifoldlSlice'
   , replicate
diff --git a/src/Vector/Int32.hs b/src/Vector/Int32.hs
--- a/src/Vector/Int32.hs
+++ b/src/Vector/Int32.hs
@@ -13,6 +13,7 @@
   , MutableVector#
   , Bounded(..)
   , Vector_(..)
+  , FromMutability#
     -- * Primitives
   , write#
   , write
@@ -21,7 +22,9 @@
   , index
   , unlift
   , substitute
+  , substitute#
   , initialized
+  , initialized#
   , unsafeCoerceLength
   , expose
   , expose#
@@ -33,10 +36,16 @@
   , unsafeFreeze
   , freeze
   , freezeSlice
+  , freeze#
+  , freezeSlice#
     -- * Copy
   , thaw
     -- * Composite
   , map
+  , traverse_
+  , itraverse_
+  , itraverse_#
+  , traverseST#
   , ifoldl'
   , ifoldlSlice'
   , replicate
@@ -52,6 +61,7 @@
   , append
   , clone
   , cloneSlice
+  , copySlice
     -- * Index
   , index0
   , index1
@@ -71,6 +81,7 @@
     -- * Custom
   , cumulativeSum1
   , toFins
+  , weakenFins
     -- * Show
   , show
     -- * Interop with primitive
@@ -87,7 +98,7 @@
 import GHC.Exts (Int32#)
 import GHC.Int (Int(I#),Int32(I32#),Int64(I64#))
 import GHC.TypeNats (type (+))
-import Arithmetic.Types (Nat#,Fin32#)
+import Arithmetic.Types (Nat#,Fin32#,type (<=#))
 import Data.Primitive (ByteArray(ByteArray))
 import Data.Unlifted (PrimArray#(PrimArray#))
 
@@ -126,6 +137,14 @@
 toFins m n !v = if all (\v# -> let w = I32# v# in w >= 0 && fromIntegral @Int32 @Int w < I# (Nat.demote# m)) n v
   then Just (unsafeCoerceVector v)
   else Nothing
+
+weakenFins ::
+     (a <=# b)
+  -> Vector n (Fin32# a)
+  -> Vector n (Fin32# b)
+{-# inline weakenFins #-}
+weakenFins _ (Vector x) = case expose# x of
+  PrimArray# z -> Vector (unsafeConstruct# (PrimArray# z))
 
 -- | Crashes the program if the range is out of bounds. That is,
 -- behavior is always well defined.
diff --git a/src/Vector/Int64.hs b/src/Vector/Int64.hs
--- a/src/Vector/Int64.hs
+++ b/src/Vector/Int64.hs
@@ -12,6 +12,8 @@
   , MutableVector(..)
   , MutableVector#
   , Bounded(..)
+  , Vector_(..)
+  , FromMutability#
     -- * Primitives
   , write#
   , write
@@ -20,7 +22,9 @@
   , index
   , unlift
   , substitute
+  , substitute#
   , initialized
+  , initialized#
   , unsafeCoerceLength
   , expose
   , expose#
@@ -32,15 +36,19 @@
   , unsafeFreeze
   , freeze
   , freezeSlice
+  , freeze#
+  , freezeSlice#
     -- * Copy
   , thaw
     -- * Composite
   , map
+  , traverse_
+  , itraverse_
+  , itraverse_#
+  , traverseST#
   , foldr
   , ifoldl'
   , ifoldlSlice'
-  , traverse_
-  , itraverse_
   , replicate
   , empty
   , empty_
@@ -60,6 +68,9 @@
   , maximum
   , maximumSlice
   , maximumSliceInitial
+  , minimum
+  , minimumSlice
+  , minimumSliceInitial
   , bubbleSort
   , bubbleSortSlice
   , bubbleSortSliceInPlace
@@ -70,7 +81,7 @@
   , cloneFromByteArray
   ) where
 
-import Prelude hiding (replicate,map,maximum,Bounded,all,foldr,show)
+import Prelude hiding (replicate,map,maximum,Bounded,all,foldr,show,minimum)
 
 import Arithmetic.Types (Nat#)
 import Data.Primitive (ByteArray)
diff --git a/src/Vector/Int8.hs b/src/Vector/Int8.hs
--- a/src/Vector/Int8.hs
+++ b/src/Vector/Int8.hs
@@ -13,6 +13,7 @@
   , MutableVector#
   , Bounded(..)
   , Vector_(..)
+  , FromMutability#
     -- * Primitives
   , write#
   , write
@@ -21,7 +22,9 @@
   , index
   , unlift
   , substitute
+  , substitute#
   , initialized
+  , initialized#
   , unsafeCoerceLength
   , expose
   , expose#
@@ -33,12 +36,18 @@
   , unsafeFreeze
   , freeze
   , freezeSlice
+  , freeze#
+  , freezeSlice#
     -- * Copy
   , thaw
     -- * Composite
   , any
   , all
   , map
+  , traverse_
+  , itraverse_
+  , itraverse_#
+  , traverseST#
   , ifoldl'
   , ifoldlSlice'
   , replicate
diff --git a/src/Vector/Lifted.hs b/src/Vector/Lifted.hs
--- a/src/Vector/Lifted.hs
+++ b/src/Vector/Lifted.hs
@@ -13,6 +13,7 @@
   , MutableVector#
   , Bounded(..)
   , Vector_(..)
+  , FromMutability#
     -- * Primitives
   , write#
   , write
@@ -22,7 +23,9 @@
   , index
   , unlift
   , substitute
+  , substitute#
   , initialized
+  , initialized#
   , unsafeCoerceLength
     -- * Ranges
   , set
@@ -32,9 +35,15 @@
   , unsafeFreeze
   , freeze
   , freezeSlice
+  , freeze#
+  , freezeSlice#
     -- * Copy
   , thaw
     -- * Composite
+  , tail
+  , cons
+  , snoc
+  , replaceAt
   , any
   , all
   , findIndex
@@ -42,6 +51,7 @@
   , traverse_
   , traverseZip_
   , itraverse_
+  , traverseST#
   , foldlM
   , ifoldl'
   , ifoldlSlice'
@@ -85,9 +95,11 @@
   , toList
     -- * Hide Length
   , vector_
+    -- * Recover Length
+  , length
   ) where
 
-import Prelude hiding (replicate,map,all,any,read,Bounded,foldr)
+import Prelude hiding (replicate,map,all,any,read,Bounded,foldr,length,tail,init,head)
 import Vector.Std.Lifted
 
 import Control.Monad.Trans.Class (lift)
@@ -102,6 +114,7 @@
 import GHC.ST (ST(ST))
 import Arithmetic.Nat (pattern N0#)
 
+import qualified Prelude
 import qualified GHC.Exts as Exts
 import qualified GHC.TypeNats as GHC
 import qualified Arithmetic.Nat as Nat
@@ -119,6 +132,10 @@
 {-# inline toSmallArray #-}
 toSmallArray !v = SmallArray (expose v)
 
+length :: Vector n a -> Nat# n
+{-# inline length #-}
+length !v = Nat# (Exts.sizeofSmallArray# (expose v))
+
 toList :: Vector n a -> [a]
 {-# inline toList #-}
 toList = Exts.toList . toSmallArray
@@ -154,7 +171,7 @@
 fromList xs0 = case xs0 of
   [] -> empty_
   a0 : _ -> runST $ do
-    let !(I# len) = length xs0
+    let !(I# len) = Prelude.length xs0
     Nat.with# len $ \sz -> do
       dst <- initialized sz a0
       _ <- Fin.ascendM# sz xs0 $ \ix payload -> case payload of
diff --git a/src/Vector/Types.hs b/src/Vector/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Vector/Types.hs
@@ -0,0 +1,5 @@
+module Vector.Types
+  ( Mutability(..)
+  ) where
+
+import Types
diff --git a/src/Vector/Unlifted.hs b/src/Vector/Unlifted.hs
--- a/src/Vector/Unlifted.hs
+++ b/src/Vector/Unlifted.hs
@@ -8,6 +8,7 @@
   , MutableVector(..)
   , MutableVector#
   , Bounded(..)
+  , FromMutability#
     -- * Primitives
   , write#
   , write
@@ -16,9 +17,10 @@
   , index
   , unlift
   , substitute
+  , substitute#
   , initialized
+  , initialized#
   , unsafeCoerceLength
-  , empty#
     -- * Ranges
   , set
   , setSlice
@@ -27,6 +29,8 @@
   , unsafeFreeze
   , freeze
   , freezeSlice
+  , freeze#
+  , freezeSlice#
     -- * Copy
   , thaw
     -- * Composite
@@ -34,8 +38,10 @@
   , traverse_
   , itraverse_
   , itraverse_#
+  , traverseST#
   , foldlM
   , foldr
+  , foldrZip
   , ifoldl'
   , ifoldlSlice'
   , replicate
@@ -46,6 +52,8 @@
   , construct3
   , construct4
   , construct5
+  , construct6
+  , construct7
   , construct1#
   , construct2#
   , construct3#
diff --git a/src/Vector/Word16.hs b/src/Vector/Word16.hs
--- a/src/Vector/Word16.hs
+++ b/src/Vector/Word16.hs
@@ -13,6 +13,7 @@
   , MutableVector#
   , Bounded(..)
   , Vector_(..)
+  , FromMutability#
     -- * Primitives
   , write#
   , write
@@ -21,7 +22,9 @@
   , index
   , unlift
   , substitute
+  , substitute#
   , initialized
+  , initialized#
   , unsafeCoerceLength
   , expose
   , expose#
@@ -33,12 +36,17 @@
   , unsafeFreeze
   , freeze
   , freezeSlice
+  , freeze#
+  , freezeSlice#
     -- * Copy
   , thaw
     -- * Composite
   , any
   , all
   , map
+  , traverse_
+  , traverseZip_
+  , traverseST#
   , ifoldl'
   , ifoldlSlice'
   , replicate
diff --git a/src/Vector/Word32.hs b/src/Vector/Word32.hs
--- a/src/Vector/Word32.hs
+++ b/src/Vector/Word32.hs
@@ -13,6 +13,7 @@
   , MutableVector#
   , Bounded(..)
   , Vector_(..)
+  , FromMutability#
     -- * Primitives
   , write#
   , write
@@ -21,7 +22,9 @@
   , index
   , unlift
   , substitute
+  , substitute#
   , initialized
+  , initialized#
   , unsafeCoerceLength
   , expose
   , expose#
@@ -33,12 +36,17 @@
   , unsafeFreeze
   , freeze
   , freezeSlice
+  , freeze#
+  , freezeSlice#
     -- * Copy
   , thaw
     -- * Composite
   , any
   , all
   , map
+  , traverse_
+  , traverseZip_
+  , traverseST#
   , ifoldl'
   , ifoldlSlice'
   , replicate
@@ -66,6 +74,9 @@
   , maximum
   , maximumSlice
   , maximumSliceInitial
+  , minimum
+  , minimumSlice
+  , minimumSliceInitial
   , bubbleSort
   , bubbleSortSlice
   , bubbleSortSliceInPlace
@@ -76,7 +87,7 @@
   , cloneFromByteArray
   ) where
 
-import Prelude hiding (replicate,map,maximum,Bounded,all,any,elem,show)
+import Prelude hiding (replicate,map,maximum,Bounded,all,any,elem,show,minimum)
 
 import Arithmetic.Types (Nat#)
 import Data.Primitive (ByteArray)
diff --git a/src/Vector/Word64.hs b/src/Vector/Word64.hs
--- a/src/Vector/Word64.hs
+++ b/src/Vector/Word64.hs
@@ -1,7 +1,8 @@
+{-# language BangPatterns #-}
 {-# language DataKinds #-}
 {-# language MagicHash #-}
 {-# language NumericUnderscores #-}
-{-# language BangPatterns #-}
+{-# language ScopedTypeVariables #-}
 {-# language TypeApplications #-}
 {-# language TypeOperators #-}
 
@@ -13,6 +14,7 @@
   , MutableVector#
   , Bounded(..)
   , Vector_(..)
+  , FromMutability#
     -- * Primitives
   , write#
   , write
@@ -21,7 +23,9 @@
   , index
   , unlift
   , substitute
+  , substitute#
   , initialized
+  , initialized#
   , unsafeCoerceLength
   , expose
   , expose#
@@ -33,10 +37,15 @@
   , unsafeFreeze
   , freeze
   , freezeSlice
+  , freeze#
+  , freezeSlice#
     -- * Copy
   , thaw
     -- * Composite
   , map
+  , traverse_
+  , traverseZip_
+  , traverseST#
   , ifoldl'
   , ifoldlSlice'
   , replicate
@@ -47,6 +56,7 @@
   , append
   , clone
   , cloneSlice
+  , sum
     -- * Index
   , index0
   , index1
@@ -70,7 +80,7 @@
   , cloneFromByteArray
   ) where
 
-import Prelude hiding (replicate,map,maximum,Bounded,all,elem,show)
+import Prelude hiding (replicate,map,maximum,Bounded,all,elem,show,sum)
 
 import Arithmetic.Types (Nat#)
 import Data.Primitive (ByteArray)
@@ -81,6 +91,7 @@
 import Vector.Eq.Word64
 import Vector.Ord.Word64
 
+import qualified GHC.Exts as Exts
 import qualified Vector.Prim.Word64
 
 -- | Crashes the program if the range is out of bounds. That is,
@@ -96,3 +107,13 @@
 
 show :: Nat# n -> Vector n Word64# -> String
 show n v = liftShows (\i s -> shows (W64# i) s) n v ""
+
+sum :: Nat# n -> Vector n Word64# -> Word64#
+{-# noinline sum #-}
+sum n !v =
+  let !(W64# result) = ifoldl'
+        (\(W64# acc) _ (x :: Word64#) -> W64# (Exts.plusWord64# acc x))
+        (W64# (Exts.wordToWord64# 0##))
+        n
+        v
+   in result
diff --git a/src/Vector/Word8.hs b/src/Vector/Word8.hs
--- a/src/Vector/Word8.hs
+++ b/src/Vector/Word8.hs
@@ -13,6 +13,7 @@
   , MutableVector#
   , Bounded(..)
   , Vector_(..)
+  , FromMutability#
     -- * Primitives
   , write#
   , write
@@ -21,7 +22,9 @@
   , index
   , unlift
   , substitute
+  , substitute#
   , initialized
+  , initialized#
   , unsafeCoerceLength
   , expose
   , expose#
@@ -33,14 +36,24 @@
   , unsafeFreeze
   , freeze
   , freezeSlice
+  , freeze#
+  , freezeSlice#
     -- * Copy
   , thaw
     -- * Composite
   , any
   , all
   , map
+  , traverse_
+  , traverseZip_
+  , traverseST#
+  , itraverse_
+  , foldlM
   , ifoldl'
   , ifoldlSlice'
+  , ifoldr
+  , foldr
+  , foldrZip
   , replicate
   , empty
   , empty_
@@ -81,14 +94,19 @@
   , show
     -- * Interop with primitive
   , cloneFromByteArray
+    -- * Interop with bytes
+  , fromByteArrayN
+  , toByteArrayN
   ) where
 
-import Prelude hiding (replicate,map,maximum,Bounded,all,any,elem,show)
+import Prelude hiding (replicate,map,maximum,Bounded,all,any,elem,show,foldr)
 
 import Arithmetic.Types (Nat#)
-import Data.Primitive (ByteArray)
+import Data.Primitive (ByteArray(ByteArray))
+import Data.Bytes.Types (ByteArrayN(ByteArrayN))
 import GHC.Exts (Word8#)
 import GHC.Word (Word8(W8#))
+import Data.Unlifted (PrimArray#(PrimArray#))
 
 import Vector.Std.Word8
 import Vector.Ord.Word8
@@ -109,3 +127,10 @@
 
 show :: Nat# n -> Vector n Word8# -> String
 show n v = liftShows (\i s -> shows (W8# i) s) n v ""
+
+fromByteArrayN :: ByteArrayN n -> Vector n Word8#
+fromByteArrayN (ByteArrayN (ByteArray x)) = Vector (unsafeConstruct# (PrimArray# x))
+
+toByteArrayN :: Vector n Word8# -> ByteArrayN n
+toByteArrayN (Vector x) = case expose# x of
+  PrimArray# y -> ByteArrayN (ByteArray y)
diff --git a/vext.cabal b/vext.cabal
--- a/vext.cabal
+++ b/vext.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.4
 name: vext
-version: 0.1.7.0
+version: 0.1.8.0
 synopsis: Array library monomorphized with backpack
 bug-reports: https://github.com/andrewthad/vex-unified/issues
 license: BSD-3-Clause
@@ -10,6 +10,15 @@
 copyright: 2019 Andrew Martin
 category: Data
 
+library types
+  exposed-modules:
+    Types
+  build-depends:
+    , base >=4.12.0.0 && <5
+  hs-source-dirs: src-types
+  default-language: Haskell2010
+  ghc-options: -O2 -Wall
+
 library indef
   exposed-modules:
     Vector
@@ -20,8 +29,9 @@
     Rep
   build-depends:
     , base >=4.12.0.0 && <5
-    , natural-arithmetic
+    , natural-arithmetic >=0.2.3
     , unlifted
+    , vext:types
   hs-source-dirs: src-indef
   default-language: Haskell2010
   ghc-options: -O2 -Wall
@@ -31,7 +41,7 @@
     PrimVector
   build-depends:
     , base >=4.12.0.0 && <5
-    , natural-arithmetic
+    , natural-arithmetic >=0.2.3
     , unlifted
     , primitive >=0.9
     , vext:indef
@@ -47,7 +57,7 @@
     MapVector
   build-depends:
     , base >=4.12.0.0 && <5
-    , natural-arithmetic
+    , natural-arithmetic >=0.2.3
     , unlifted
     , vext:indef
   mixins:
@@ -64,7 +74,7 @@
     ZipVector
   build-depends:
     , base >=4.12.0.0 && <5
-    , natural-arithmetic
+    , natural-arithmetic >=0.2.3
     , unlifted
     , vext:indef
   mixins:
@@ -87,7 +97,7 @@
     Type
   build-depends:
     , base >=4.12.0.0 && <5
-    , natural-arithmetic
+    , natural-arithmetic >=0.2.3
     , unlifted
     , vext:indef
   hs-source-dirs: src-type-eq-indef
@@ -102,7 +112,7 @@
     Rep
   build-depends:
     , base >=4.12.0.0 && <5
-    , natural-arithmetic
+    , natural-arithmetic >=0.2.3
     , unlifted
     , vext:indef
   hs-source-dirs: src-rep-eq-indef
@@ -117,7 +127,7 @@
     Rep
   build-depends:
     , base >=4.12.0.0 && <5
-    , natural-arithmetic
+    , natural-arithmetic >=0.2.3
     , unlifted
     , vext:indef
     , vext:inst-bit
@@ -134,7 +144,7 @@
     Rep
   build-depends:
     , base >=4.12.0.0 && <5
-    , natural-arithmetic
+    , natural-arithmetic >=0.2.3
     , unlifted
     , vext:indef
     , vext:inst-bit
@@ -153,7 +163,7 @@
     FinType
   build-depends:
     , base >=4.12.0.0 && <5
-    , natural-arithmetic
+    , natural-arithmetic >=0.2.3
     , unlifted
     , vext:indef
     , vext:inst
@@ -248,11 +258,14 @@
     , Vector.Map.Word8.Lifted
     , Vector.Map.Word16.Lifted
     , Vector.Map.Word32.Lifted
+    , Vector.Map.Word32.Int64
     , Vector.Map.Word64.Lifted
+    , Vector.Map.Int.Int
     , Vector.Map.Int8.Lifted
     , Vector.Map.Int16.Lifted
     , Vector.Map.Int32.Lifted
     , Vector.Map.Int64.Lifted
+    , Vector.Map.Int64.Word32
     , Vector.Map.Unlifted.Lifted
     , Vector.Map.Lifted.Int32
     , Vector.Map.Lifted.Int64
@@ -261,7 +274,13 @@
     , Vector.Zip.Unlifted.Word32.Lifted
     , Vector.Zip.Unlifted.Lifted.Lifted
     , Vector.Zip.Word16.Lifted.Lifted
+    , Vector.Zip.Lifted.Lifted.Lifted
+    , Vector.Zip.Lifted.Word64.Lifted
+    , Vector.Zip.Lifted.Word32.Lifted
     , Vector.Zip.Lifted.Word16.Lifted
+    , Vector.Zip.Lifted.Word8.Lifted
+    , Vector.Zip.Lifted.Int8.Lifted
+    , Vector.Zip.Lifted.Int64.Lifted
     , Vector.Zip.Bit.Bit.Bit
     , Vector.Prim.Int8
     , Vector.Prim.Int32
@@ -299,8 +318,20 @@
     vext:mask-indef (MaskVector as Vector.Masked.Unlifted) requires (Element as Unlifted, Rep as Unlifted),
     vext:zip-indef (ZipVector as Vector.Zip.Bit.Bit.Bit) requires
       (ElementA as Word1, RepA as Word1, ElementB as Word1, RepB as Word1, ElementC as Word1, RepC as Word1),
+    vext:zip-indef (ZipVector as Vector.Zip.Lifted.Int8.Lifted) requires
+      (ElementA as Lifted, RepA as Lifted, ElementB as Int8, RepB as Int8, ElementC as Lifted, RepC as Lifted),
+    vext:zip-indef (ZipVector as Vector.Zip.Lifted.Int64.Lifted) requires
+      (ElementA as Lifted, RepA as Lifted, ElementB as Int64, RepB as Int64, ElementC as Lifted, RepC as Lifted),
+    vext:zip-indef (ZipVector as Vector.Zip.Lifted.Word8.Lifted) requires
+      (ElementA as Lifted, RepA as Lifted, ElementB as Word8, RepB as Word8, ElementC as Lifted, RepC as Lifted),
     vext:zip-indef (ZipVector as Vector.Zip.Lifted.Word16.Lifted) requires
       (ElementA as Lifted, RepA as Lifted, ElementB as Word16, RepB as Word16, ElementC as Lifted, RepC as Lifted),
+    vext:zip-indef (ZipVector as Vector.Zip.Lifted.Lifted.Lifted) requires
+      (ElementA as Lifted, RepA as Lifted, ElementB as Lifted, RepB as Lifted, ElementC as Lifted, RepC as Lifted),
+    vext:zip-indef (ZipVector as Vector.Zip.Lifted.Word32.Lifted) requires
+      (ElementA as Lifted, RepA as Lifted, ElementB as Word32, RepB as Word32, ElementC as Lifted, RepC as Lifted),
+    vext:zip-indef (ZipVector as Vector.Zip.Lifted.Word64.Lifted) requires
+      (ElementA as Lifted, RepA as Lifted, ElementB as Word64, RepB as Word64, ElementC as Lifted, RepC as Lifted),
     vext:zip-indef (ZipVector as Vector.Zip.Unlifted.Word32.Lifted) requires
       (ElementA as Unlifted, RepA as Unlifted, ElementB as Word32, RepB as Word32, ElementC as Lifted, RepC as Lifted),
     vext:zip-indef (ZipVector as Vector.Zip.Unlifted.Lifted.Lifted) requires
@@ -325,16 +356,22 @@
       (ElementA as Word16, RepA as Word16, ElementB as Lifted, RepB as Lifted),
     vext:map-indef (MapVector as Vector.Map.Word32.Lifted) requires
       (ElementA as Word32, RepA as Word32, ElementB as Lifted, RepB as Lifted),
+    vext:map-indef (MapVector as Vector.Map.Word32.Int64) requires
+      (ElementA as Word32, RepA as Word32, ElementB as Int64, RepB as Int64),
     vext:map-indef (MapVector as Vector.Map.Word64.Lifted) requires
       (ElementA as Word64, RepA as Word64, ElementB as Lifted, RepB as Lifted),
     vext:map-indef (MapVector as Vector.Map.Int64.Lifted) requires
       (ElementA as Int64, RepA as Int64, ElementB as Lifted, RepB as Lifted),
+    vext:map-indef (MapVector as Vector.Map.Int64.Word32) requires
+      (ElementA as Int64, RepA as Int64, ElementB as Word32, RepB as Word32),
     vext:map-indef (MapVector as Vector.Map.Int32.Lifted) requires
       (ElementA as Int32, RepA as Int32, ElementB as Lifted, RepB as Lifted),
     vext:map-indef (MapVector as Vector.Map.Int16.Lifted) requires
       (ElementA as Int16, RepA as Int16, ElementB as Lifted, RepB as Lifted),
     vext:map-indef (MapVector as Vector.Map.Int8.Lifted) requires
       (ElementA as Int8, RepA as Int8, ElementB as Lifted, RepB as Lifted),
+    vext:map-indef (MapVector as Vector.Map.Int.Int) requires
+      (ElementA as Int, RepA as Int, ElementB as Int, RepB as Int),
     vext:indef (Vector as Vector.Std.Lifted) requires (Element as Lifted, Rep as Lifted),
     vext:indef (Vector as Vector.Std.Unlifted) requires (Element as Unlifted, Rep as Unlifted),
     vext:type-eq-indef (TypeEqVector as Vector.Std.Unlifted.Eq.ShortText)
@@ -450,16 +487,25 @@
     , Vector.Map.Word8.Lifted
     , Vector.Map.Word16.Lifted
     , Vector.Map.Word32.Lifted
+    , Vector.Map.Word32.Int64
     , Vector.Map.Word64.Lifted
+    , Vector.Map.Int.Int
     , Vector.Map.Int8.Lifted
     , Vector.Map.Int16.Lifted
     , Vector.Map.Int32.Lifted
     , Vector.Map.Int64.Lifted
+    , Vector.Map.Int64.Word32
     , Vector.Map.Unlifted.Lifted
     , Vector.Zip.Unlifted.Word32.Lifted
     , Vector.Zip.Unlifted.Lifted.Lifted
     , Vector.Zip.Word16.Lifted.Lifted
+    , Vector.Zip.Lifted.Lifted.Lifted
+    , Vector.Zip.Lifted.Int8.Lifted
+    , Vector.Zip.Lifted.Int64.Lifted
+    , Vector.Zip.Lifted.Word8.Lifted
     , Vector.Zip.Lifted.Word16.Lifted
+    , Vector.Zip.Lifted.Word32.Lifted
+    , Vector.Zip.Lifted.Word64.Lifted
   exposed-modules:
     Vector.Bit
     Vector.Word
@@ -481,16 +527,19 @@
     Vector.Unlifted.ByteArray
     Vector.Unlifted.ShortText
     Vector.Unlifted.Masked
+    Vector.Types
   build-depends:
     , base >=4.12.0.0 && <5 
-    , vext:inst
-    , vext:pair-inst
-    , vext:inst-bit
-    , natural-arithmetic
+    , natural-arithmetic >=0.2.3
     , primitive >=0.8
     , run-st >=0.1.3
     , transformers >=0.6.1
     , unlifted
+    , byteslice >=0.2.14
+    , vext:inst
+    , vext:inst-bit
+    , vext:pair-inst
+    , vext:types
 
 test-suite test 
   default-language: Haskell2010
@@ -504,5 +553,5 @@
     , vext
     , tasty >=1.2.3
     , tasty-quickcheck >=0.10
-    , natural-arithmetic
+    , natural-arithmetic >=0.2.3
     , unlifted
