diff --git a/examples/sorting.hs b/examples/sorting.hs
--- a/examples/sorting.hs
+++ b/examples/sorting.hs
@@ -14,7 +14,7 @@
 import Data.Proxy (Proxy(Proxy))
 import Lens.Micro ((^.))
 import Data.Vector.Vinyl.TypeLevel (ListAll)
-import qualified Data.Vector.Vinyl.Default as V
+import qualified Data.Vector.Vinyl.Default.Empty.Monomorphic as V
 import qualified Data.Vector.Algorithms.Intro as Intro
 import qualified Data.Vector.Algorithms.Merge as Merge
 
diff --git a/src/Data/Vector/Vinyl/Default.hs b/src/Data/Vector/Vinyl/Default.hs
deleted file mode 100644
--- a/src/Data/Vector/Vinyl/Default.hs
+++ /dev/null
@@ -1,1313 +0,0 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE KindSignatures #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE Rank2Types #-}
------------------------------------------------------------------------------
--- |
--- Copyright   :  Andrew Martin
--- License     :  BSD-style (see the file LICENSE)
---
--- Maintainer  :  Andrew Martin <andrew.thaddeus@gmail.com>
--- Stability   :  experimental
--- Portability :  non-portable
---
--- There are two vector types provided by this module: 'Vector' and
--- 'MVector'. They must be parameterized over a type that unifies
--- with 'Rec Identity rs'. An example would be:
---
--- > foo :: Vector (Rec Identity '[Int,Char,Bool])
--- 
--- This vector stores records that have an 'Int', a 'Char', and a 'Bool'.
------------------------------------------------------------------------------
-module Data.Vector.Vinyl.Default
-  ( Vector, MVector
-
-  -- * Accessors
-
-  -- ** Length information
-  , length, null
-
-  -- ** Indexing
-  , (!), (!?), head, last
-  , unsafeIndex, unsafeHead, unsafeLast
-
-  -- ** Monadic indexing
-  , indexM, headM, lastM
-  , unsafeIndexM, unsafeHeadM, unsafeLastM
-
-  -- ** Extracting subvectors (slicing)
-  , slice, init, tail, take, drop, splitAt
-  , unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop
-
-  -- * Construction
-
-  -- ** Initialisation
-  , empty, singleton, replicate, generate, iterateN
-
-  -- ** Monadic initialisation
-  , replicateM, generateM, create
-
-  -- ** Unfolding
-  , unfoldr, unfoldrN
-  , constructN, constructrN
-
-  -- -- ** Enumeration
-  -- , enumFromN, enumFromStepN, enumFromTo, enumFromThenTo
-
-  -- ** Concatenation
-  , cons, snoc, (++), concat
-
-  -- ** Restricting memory usage
-  , force
-
-  -- * Modifying vectors
-
-  -- ** Bulk updates
-  , (//)
-  , unsafeUpd
-  -- , update_, unsafeUpdate_
-
-  -- ** Accumulations
-  , accum, unsafeAccum
-  -- , accumulate_, unsafeAccumulate_
-
-  -- ** Permutations
-  , reverse
-  -- , backpermute, unsafeBackpermute
-
-  -- ** Safe destructive updates
-  , modify
-
-  -- * Elementwise operations
-
-  -- ** Mapping
-  , map, imap, concatMap
-
-  -- ** Monadic mapping
-  , mapM, mapM_, forM, forM_
-
-  -- ** Zipping - Omitted due to me being lazy
-  -- , zipWith, zipWith3, zipWith4, zipWith5, zipWith6
-  -- , izipWith, izipWith3, izipWith4, izipWith5, izipWith6
-
-  -- ** Monadic zipping
-  , zipWithM, zipWithM_
-
-  -- * Working with predicates
-
-  -- ** Filtering
-  , filter, ifilter, filterM
-  , takeWhile, dropWhile
-
-  -- ** Partitioning
-  , partition, unstablePartition, span, break
-
-  -- ** Searching
-  , elem, notElem, find, findIndex
-  , elemIndex
-  -- , findIndices, elemIndices
-
-  -- * Folding
-  , foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1'
-  , ifoldl, ifoldl', ifoldr, ifoldr'
-
-  -- ** Specialised folds
-  , all, any
-  -- , sum, product
-  , maximum, maximumBy, minimum, minimumBy
-  , minIndex, minIndexBy, maxIndex, maxIndexBy
-
-  -- ** Monadic folds
-  , foldM, foldM', fold1M, fold1M'
-  , foldM_, foldM'_, fold1M_, fold1M'_
-
-  -- * Prefix sums (scans)
-  , prescanl, prescanl'
-  , postscanl, postscanl'
-  , scanl, scanl', scanl1, scanl1'
-  , prescanr, prescanr'
-  , postscanr, postscanr'
-  , scanr, scanr', scanr1, scanr1'
-
-  -- ** Lists
-  , toList, fromList, fromListN
-
-  -- ** Other vector types
-  , G.convert
-
-  -- ** Mutable vectors
-  , freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy
-  ) where
-
-import Control.Monad.Primitive
-import Control.Monad.ST
-import Data.Vector.Vinyl.Default.Internal
-import Data.Vinyl.Core
-import Data.Vinyl.Functor (Identity(..))
-import qualified Data.Vector.Generic as G
-import Prelude hiding ( length, null,
-                        replicate, (++), concat,
-                        head, last,
-                        init, tail, take, drop, splitAt, reverse,
-                        map, concatMap,
-                        zipWith, zipWith3, zip, zip3, unzip, unzip3,
-                        filter, takeWhile, dropWhile, span, break,
-                        elem, notElem,
-                        foldl, foldl1, foldr, foldr1,
-                        all, any, sum, product, minimum, maximum,
-                        scanl, scanl1, scanr, scanr1,
-                        enumFromTo, enumFromThenTo,
-                        mapM, mapM_ )
-
-
--- Length
--- ------
-
--- | /O(1)/ Yield the length of the vector.
-length :: Vector (Rec Identity rs) -> Int
-length (V i _) = i
-{-# INLINE length #-}
-
--- | /O(1)/ Test whether a vector if empty
-null :: Vector (Rec Identity rs) -> Bool
-null (V i _) = i == 0
-{-# INLINE null #-}
-
-
--- Indexing
--- --------
-
--- | O(1) Indexing
-(!) :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Int -> Rec Identity rs
-(!) = (G.!)
-{-# INLINE (!) #-}
-
--- | O(1) Safe indexing
-(!?) :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Int -> Maybe (Rec Identity rs)
-(!?) = (G.!?)
-{-# INLINE (!?) #-}
-
--- | /O(1)/ First element
-head :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Rec Identity rs
-head = G.head
-{-# INLINE head #-}
-
--- | /O(1)/ Last element
-last :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Rec Identity rs
-last = G.last
-{-# INLINE last #-}
-
-
--- | /O(1)/ Unsafe indexing without bounds checking
-unsafeIndex :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Int -> Rec Identity rs
-{-# INLINE unsafeIndex #-}
-unsafeIndex = G.unsafeIndex
-
--- | /O(1)/ First element without checking if the vector is empty
-unsafeHead :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Rec Identity rs
-{-# INLINE unsafeHead #-}
-unsafeHead = G.unsafeHead
-
--- | /O(1)/ Last element without checking if the vector is empty
-unsafeLast :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Rec Identity rs
-{-# INLINE unsafeLast #-}
-unsafeLast = G.unsafeLast
-
--- Monadic indexing
--- ----------------
-
--- | /O(1)/ Indexing in a monad.
---
--- The monad allows operations to be strict in the vector when necessary.
--- Suppose vector copying is implemented like this:
---
--- > copy mv v = ... write mv i (v ! i) ...
---
--- For lazy vectors, @v ! i@ would not be evaluated which means that @mv@
--- would unnecessarily retain a reference to @v@ in each element written.
---
--- With 'indexM', copying can be implemented like this instead:
---
--- > copy mv v = ... do
--- >                   x <- indexM v i
--- >                   write mv i x
---
--- Here, no references to @v@ are retained because indexing (but /not/ the
--- elements) is evaluated eagerly.
---
-indexM :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => Vector (Rec Identity rs) -> Int -> m (Rec Identity rs)
-indexM = G.indexM
-{-# INLINE indexM #-}
-
--- | /O(1)/ First element of a vector in a monad. See 'indexM' for an
--- explanation of why this is useful.
-headM :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => Vector (Rec Identity rs) -> m (Rec Identity rs)
-headM = G.headM
-{-# INLINE headM #-}
-
--- | /O(1)/ Last element of a vector in a monad. See 'indexM' for an
--- explanation of why this is useful.
-lastM :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => Vector (Rec Identity rs) -> m (Rec Identity rs)
-lastM = G.lastM
-{-# INLINE lastM #-}
-
--- | /O(1)/ Indexing in a monad without bounds checks. See 'indexM' for an
--- explanation of why this is useful.
-unsafeIndexM :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => Vector (Rec Identity rs) -> Int -> m (Rec Identity rs)
-unsafeIndexM = G.unsafeIndexM
-{-# INLINE unsafeIndexM #-}
-
--- | /O(1)/ First element in a monad without checking for empty vectors.
--- See 'indexM' for an explanation of why this is useful.
-unsafeHeadM :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => Vector (Rec Identity rs) -> m (Rec Identity rs)
-unsafeHeadM = G.unsafeHeadM
-{-# INLINE unsafeHeadM #-}
-
--- | /O(1)/ Last element in a monad without checking for empty vectors.
--- See 'indexM' for an explanation of why this is useful.
-unsafeLastM :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => Vector (Rec Identity rs) -> m (Rec Identity rs)
-unsafeLastM = G.unsafeLastM
-{-# INLINE unsafeLastM #-}
-
--- Extracting subvectors (slicing)
--- -------------------------------
-
--- | /O(1)/ Yield a slice of the vector without copying it. The vector must
--- contain at least @i+n@ elements.
-slice :: G.Vector Vector (Rec Identity rs)
-      => Int   -- ^ @i@ starting index
-      -> Int   -- ^ @n@ length
-      -> Vector (Rec Identity rs)
-      -> Vector (Rec Identity rs)
-slice = G.slice
-{-# INLINE slice #-}
-
--- | /O(1)/ Yield all but the last element without copying. The vector may not
--- be empty.
-init :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-init = G.init
-{-# INLINE init #-}
-
--- | /O(1)/ Yield all but the first element without copying. The vector may not
--- be empty.
-tail :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-tail = G.tail
-{-# INLINE tail #-}
-
--- | /O(1)/ Yield at the first @n@ elements without copying. The vector may
--- contain less than @n@ elements in which case it is returned unchanged.
-take :: G.Vector Vector (Rec Identity rs)
-  => Int -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-take = G.take
-{-# INLINE take #-}
-
--- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may
--- contain less than @n@ elements in which case an empty vector is returned.
-drop :: G.Vector Vector (Rec Identity rs)
-  => Int -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-drop = G.drop
-{-# INLINE drop #-}
-
--- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying.
---
--- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@
--- but slightly more efficient.
-splitAt :: G.Vector Vector (Rec Identity rs)
-  => Int -> Vector (Rec Identity rs) -> (Vector (Rec Identity rs), Vector (Rec Identity rs))
-splitAt = G.splitAt
-{-# INLINE splitAt #-}
-
--- | /O(1)/ Yield a slice of the vector without copying. The vector must
--- contain at least @i+n@ elements but this is not checked.
-unsafeSlice :: G.Vector Vector (Rec Identity rs)
-  => Int   -- ^ @i@ starting index
-                       -> Int   -- ^ @n@ length
-                       -> Vector (Rec Identity rs)
-                       -> Vector (Rec Identity rs)
-unsafeSlice = G.unsafeSlice
-{-# INLINE unsafeSlice #-}
-
--- | /O(1)/ Yield all but the last element without copying. The vector may not
--- be empty but this is not checked.
-unsafeInit :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-unsafeInit = G.unsafeInit
-{-# INLINE unsafeInit #-}
-
--- | /O(1)/ Yield all but the first element without copying. The vector may not
--- be empty but this is not checked.
-unsafeTail :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-unsafeTail = G.unsafeTail
-{-# INLINE unsafeTail #-}
-
--- | /O(1)/ Yield the first @n@ elements without copying. The vector must
--- contain at least @n@ elements but this is not checked.
-unsafeTake :: G.Vector Vector (Rec Identity rs)
-  => Int -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-unsafeTake = G.unsafeTake
-{-# INLINE unsafeTake #-}
-
--- | /O(1)/ Yield all but the first @n@ elements without copying. The vector
--- must contain at least @n@ elements but this is not checked.
-unsafeDrop :: G.Vector Vector (Rec Identity rs)
-  => Int -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-unsafeDrop = G.unsafeDrop
-{-# INLINE unsafeDrop #-}
-
--- Initialisation
--- --------------
-
--- | /O(1)/ Empty vector
-empty :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs)
-empty = G.empty
-{-# INLINE empty #-}
-
--- | /O(1)/ Vector with exactly one element
-singleton :: G.Vector Vector (Rec Identity rs)
-  => Rec Identity rs -> Vector (Rec Identity rs)
-singleton = G.singleton
-{-# INLINE singleton #-}
-
--- | /O(n)/ Vector of the given length with the same value in each position
-replicate :: G.Vector Vector (Rec Identity rs)
-  => Int -> Rec Identity rs -> Vector (Rec Identity rs)
-replicate = G.replicate
-{-# INLINE replicate #-}
-
--- | /O(n)/ Construct a vector of the given length by applying the function to
--- each index
-generate :: G.Vector Vector (Rec Identity rs)
-  => Int -> (Int -> Rec Identity rs) -> Vector (Rec Identity rs)
-generate = G.generate
-{-# INLINE generate #-}
-
--- | /O(n)/ Apply function n times to value. Zeroth element is original value.
-iterateN :: G.Vector Vector (Rec Identity rs)
-  => Int -> (Rec Identity rs -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity rs)
-iterateN = G.iterateN
-{-# INLINE iterateN #-}
-
--- Unfolding
--- ---------
-
--- | /O(n)/ Construct a vector by repeatedly applying the generator function
--- to a seed. The generator function yields 'Just' the next element and the
--- new seed or 'Nothing' if there are no more elements.
---
--- > unfoldr (\n -> if n == 0 then Nothing else Just (n,n-1)) 10
--- >  = <10,9,8,7,6,5,4,3,2,1>
-unfoldr :: G.Vector Vector (Rec Identity rs)
-  => (c -> Maybe (Rec Identity rs, c)) -> c -> Vector (Rec Identity rs)
-unfoldr = G.unfoldr
-{-# INLINE unfoldr #-}
-
--- | /O(n)/ Construct a vector with at most @n@ by repeatedly applying the
--- generator function to the a seed. The generator function yields 'Just' the
--- next element and the new seed or 'Nothing' if there are no more elements.
---
--- > unfoldrN 3 (\n -> Just (n,n-1)) 10 = <10,9,8>
-unfoldrN :: G.Vector Vector (Rec Identity rs)
-  => Int -> (c -> Maybe (Rec Identity rs, c)) -> c -> Vector (Rec Identity rs)
-unfoldrN = G.unfoldrN
-{-# INLINE unfoldrN #-}
-
--- | /O(n)/ Construct a vector with @n@ elements by repeatedly applying the
--- generator function to the already constructed part of the vector.
---
--- > constructN 3 f = let a = f <> ; b = f <a> ; c = f <a,b> in f <a,b,c>
---
-constructN :: G.Vector Vector (Rec Identity rs)
-  => Int -> (Vector (Rec Identity rs) -> Rec Identity rs) -> Vector (Rec Identity rs)
-constructN = G.constructN
-{-# INLINE constructN #-}
-
--- | /O(n)/ Construct a vector with @n@ elements from right to left by
--- repeatedly applying the generator function to the already constructed part
--- of the vector.
---
--- > constructrN 3 f = let a = f <> ; b = f<a> ; c = f <b,a> in f <c,b,a>
---
-constructrN :: G.Vector Vector (Rec Identity rs)
-  => Int -> (Vector (Rec Identity rs) -> Rec Identity rs) -> Vector (Rec Identity rs)
-constructrN = G.constructrN
-{-# INLINE constructrN #-}
-
--- Concatenation
--- -------------
-
--- | /O(n)/ Prepend an element
-cons :: G.Vector Vector (Rec Identity rs)
-  => Rec Identity rs -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-{-# INLINE cons #-}
-cons = G.cons
-
--- | /O(n)/ Append an element
-snoc :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity rs)
-{-# INLINE snoc #-}
-snoc = G.snoc
-
-infixr 5 ++
--- | /O(m+n)/ Concatenate two vectors
-(++) :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-{-# INLINE (++) #-}
-(++) = (G.++)
-
--- | /O(n)/ Concatenate all vectors in the list
-concat :: G.Vector Vector (Rec Identity rs)
-  => [Vector (Rec Identity rs)] -> Vector (Rec Identity rs)
-{-# INLINE concat #-}
-concat = G.concat
-
--- Monadic initialisation
--- ----------------------
-
--- | /O(n)/ Execute the monadic action the given number of times and store the
--- results in a vector.
-replicateM :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => Int -> m (Rec Identity rs) -> m (Vector (Rec Identity rs))
-replicateM = G.replicateM
-{-# INLINE replicateM #-}
-
--- | /O(n)/ Construct a vector of the given length by applying the monadic
--- action to each index
-generateM :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => Int -> (Int -> m (Rec Identity rs)) -> m (Vector (Rec Identity rs))
-generateM = G.generateM
-{-# INLINE generateM #-}
-
--- | Execute the monadic action and freeze the resulting vector.
---
--- @
--- create (do { v \<- new 2; write v 0 \'a\'; write v 1 \'b\'; return v }) = \<'a','b'\>
--- @
-create :: G.Vector Vector (Rec Identity rs)
-  => (forall s. ST s (G.Mutable Vector s (Rec Identity rs))) -> Vector (Rec Identity rs)
--- NOTE: eta-expanded due to http://hackage.haskell.org/trac/ghc/ticket/4120
-create p = G.create p
-{-# INLINE create #-}
-
--- 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 :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-force = G.force
-{-# INLINE force #-}
-
--- 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>
---
-(//) :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs)   -- ^ initial vector (of length @m@)
-                -> [(Int, Rec Identity rs)]                          -- ^ list of index/value pairs (of length @n@)
-                -> Vector (Rec Identity rs)
-(//) = (G.//)
-{-# INLINE (//) #-}
-
--- | Same as ('//') but without bounds checking.
-unsafeUpd :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> [(Int, Rec Identity rs)] -> Vector (Rec Identity rs)
-unsafeUpd = G.unsafeUpd
-{-# INLINE unsafeUpd #-}
-
--- Accumulations
--- -------------
-
--- | /O(m+n)/ For each pair @(i,c)@ from the list, replace the vector element
--- @a@ at position @i@ by @f a c@.
---
--- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4>
-accum :: G.Vector Vector (Rec Identity rs)
-      => (Rec Identity rs -> c -> Rec Identity rs) -- ^ accumulating function @f@
-      -> Vector (Rec Identity rs)       -- ^ initial vector (of length @m@)
-      -> [(Int,c)]               -- ^ list of index/value pairs (of length @n@)
-      -> Vector (Rec Identity rs)
-accum = G.accum
-{-# INLINE accum #-}
-
--- | Same as 'accum' but without bounds checking.
-unsafeAccum :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> c -> Rec Identity rs) -> Vector (Rec Identity rs) -> [(Int,c)] -> Vector (Rec Identity rs)
-unsafeAccum = G.unsafeAccum
-{-# INLINE unsafeAccum #-}
-
-
--- Permutations
--- ------------
-
--- | /O(n)/ Reverse a vector
-reverse :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-{-# INLINE reverse #-}
-reverse = G.reverse
-
--- Safe destructive updates
--- ------------------------
-
--- | Apply a destructive operation to a vector. The operation will be
--- performed in place if it is safe to do so and will modify a copy of the
--- vector otherwise.
---
--- @
--- modify (\\v -> write v 0 \'x\') ('replicate' 3 \'a\') = \<\'x\',\'a\',\'a\'\>
--- @
-modify :: (G.Vector Vector (Rec Identity rs))
-       => (forall s. G.Mutable Vector s (Rec Identity rs) -> ST s ())
-       -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-{-# INLINE modify #-}
-modify p = G.modify p
-
--- Mapping
--- -------
-
--- | /O(n)/ Map a function over a vector
-map :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-    => (Rec Identity rs -> Rec Identity ss) -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
-map = G.map
-{-# INLINE map #-}
-
--- | /O(n)/ Apply a function to every element of a vector and its index
-imap :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-     => (Int -> Rec Identity rs -> Rec Identity ss)
-     -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
-imap = G.imap
-{-# INLINE imap #-}
-
--- | Map a function over a vector and concatenate the results.
-concatMap :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-          => (Rec Identity rs -> Vector (Rec Identity ss)) -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
-concatMap = G.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, G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> m (Rec Identity ss)) -> Vector (Rec Identity rs) -> m (Vector (Rec Identity ss))
-mapM = G.mapM
-{-# INLINE mapM #-}
-
--- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the
--- results
-mapM_ :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => (Rec Identity rs -> m b) -> Vector (Rec Identity rs) -> m ()
-mapM_ = G.mapM_
-{-# INLINE mapM_ #-}
-
--- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a
--- vector of results. Equvalent to @flip 'mapM'@.
-forM :: (Monad m, G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => Vector (Rec Identity rs) -> (Rec Identity rs -> m (Rec Identity ss)) -> m (Vector (Rec Identity ss))
-forM = G.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, G.Vector Vector (Rec Identity rs))
-  => Vector (Rec Identity rs) -> (Rec Identity rs -> m b) -> m ()
-forM_ = G.forM_
-{-# INLINE forM_ #-}
-
--- Zipping
--- -------
-
---   -- | /O(min(m,n))/ Zip two vectors with the given function.
---   zipWith :: ( G.Vector u a, G.Vector v a'
---              , G.Vector u b, G.Vector v b'
---              , G.Vector u c, G.Vector v c'
---              ) => ((a,a') -> (b,b') -> (c,c'))
---                -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c')
---   zipWith = G.zipWith
---   {-# INLINE zipWith #-}
---   
---   -- | Zip three vectors with the given function.
---   
---   zipWith3 :: ( G.Vector u a, G.Vector v a'
---               , G.Vector u b, G.Vector v b'
---               , G.Vector u c, G.Vector v c'
---               , G.Vector u d, G.Vector v d'
---               ) => ((a,a') -> (b,b') -> (c,c') -> (d, d'))
---                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d')
---   zipWith3 = G.zipWith3
---   {-# INLINE zipWith3 #-}
---   
---   zipWith4 :: ( G.Vector u a, G.Vector v a'
---               , G.Vector u b, G.Vector v b'
---               , G.Vector u c, G.Vector v c'
---               , G.Vector u d, G.Vector v d'
---               , G.Vector u e, G.Vector v e'
---               ) => ((a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e'))
---                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e')
---   zipWith4 = G.zipWith4
---   {-# INLINE zipWith4 #-}
---   
---   zipWith5 :: ( G.Vector u a, G.Vector v a'
---               , G.Vector u b, G.Vector v b'
---               , G.Vector u c, G.Vector v c'
---               , G.Vector u d, G.Vector v d'
---               , G.Vector u e, G.Vector v e'
---               , G.Vector u f, G.Vector v f'
---               ) => ((a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f'))
---                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f')
---   zipWith5 = G.zipWith5
---   {-# INLINE zipWith5 #-}
---   
---   zipWith6 :: ( G.Vector u a, G.Vector v a'
---               , G.Vector u b, G.Vector v b'
---               , G.Vector u c, G.Vector v c'
---               , G.Vector u d, G.Vector v d'
---               , G.Vector u e, G.Vector v e'
---               , G.Vector u f, G.Vector v f'
---               , G.Vector u g, G.Vector v g'
---               ) => ((a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f') -> (g,g'))
---                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f') -> Vector u v (g,g')
---   zipWith6 = G.zipWith6
---   {-# INLINE zipWith6 #-}
---   
---   -- | /O(min(m,n))/ Zip two vectors with a function that also takes the
---   -- elements' indices.
---   izipWith :: ( G.Vector u a, G.Vector v a'
---               , G.Vector u b, G.Vector v b'
---               , G.Vector u c, G.Vector v c'
---               ) => (Int -> (a,a') -> (b,b') -> (c,c'))
---                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c')
---   izipWith = G.izipWith
---   {-# INLINE izipWith #-}
---   
---   -- | Zip three vectors and their indices with the given function.
---   izipWith3 :: ( G.Vector u a, G.Vector v a'
---               , G.Vector u b, G.Vector v b'
---               , G.Vector u c, G.Vector v c'
---               , G.Vector u d, G.Vector v d'
---               ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d'))
---                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d')
---   izipWith3 = G.izipWith3
---   {-# INLINE izipWith3 #-}
---   
---   izipWith4 :: ( G.Vector u a, G.Vector v a'
---               , G.Vector u b, G.Vector v b'
---               , G.Vector u c, G.Vector v c'
---               , G.Vector u d, G.Vector v d'
---               , G.Vector u e, G.Vector v e'
---               ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e'))
---                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e')
---   izipWith4 = G.izipWith4
---   {-# INLINE izipWith4 #-}
---   
---   izipWith5 :: ( G.Vector u a, G.Vector v a'
---               , G.Vector u b, G.Vector v b'
---               , G.Vector u c, G.Vector v c'
---               , G.Vector u d, G.Vector v d'
---               , G.Vector u e, G.Vector v e'
---               , G.Vector u f, G.Vector v f'
---               ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f'))
---                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f')
---   izipWith5 = G.izipWith5
---   {-# INLINE izipWith5 #-}
---   
---   izipWith6 :: ( G.Vector u a, G.Vector v a'
---               , G.Vector u b, G.Vector v b'
---               , G.Vector u c, G.Vector v c'
---               , G.Vector u d, G.Vector v d'
---               , G.Vector u e, G.Vector v e'
---               , G.Vector u f, G.Vector v f'
---               , G.Vector u g, G.Vector v g'
---               ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f') -> (g,g'))
---                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f') -> Vector u v (g,g')
---   izipWith6 = G.izipWith6
---   {-# INLINE izipWith6 #-}
-
--- Monadic zipping
--- ---------------
-
--- | /O(min(m,n))/ Zip the two vectors with the monadic action and yield a
--- vector of results
-zipWithM :: (Monad m, G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss), G.Vector Vector (Rec Identity ts))
-         => (Rec Identity rs -> Rec Identity ss -> m (Rec Identity ts)) -> Vector (Rec Identity rs) -> Vector (Rec Identity ss) -> m (Vector (Rec Identity ts))
-zipWithM = G.zipWithM
-{-# INLINE zipWithM #-}
-
--- | /O(min(m,n))/ Zip the two vectors with the monadic action and ignore the
--- results
-zipWithM_ :: (Monad m, G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-          => (Rec Identity rs -> Rec Identity ss -> m e) -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)-> m ()
-zipWithM_ = G.zipWithM_
-{-# INLINE zipWithM_ #-}
-
--- Filtering
--- ---------
-
--- | /O(n)/ Drop elements that do not satisfy the predicate
-filter :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-filter = G.filter
-{-# INLINE filter #-}
-
--- | /O(n)/ Drop elements that do not satisfy the predicate which is applied to
--- values and their indices
-ifilter :: G.Vector Vector (Rec Identity rs)
-  => (Int -> Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-ifilter = G.ifilter
-{-# INLINE ifilter #-}
-
--- | /O(n)/ Drop elements that do not satisfy the monadic predicate
-filterM :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => (Rec Identity rs -> m Bool) -> Vector (Rec Identity rs) -> m (Vector (Rec Identity rs))
-filterM = G.filterM
-{-# INLINE filterM #-}
-
--- | /O(n)/ Yield the longest prefix of elements satisfying the predicate
--- without copying.
-takeWhile :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-takeWhile = G.takeWhile
-{-# INLINE takeWhile #-}
-
--- | /O(n)/ Drop the longest prefix of elements that satisfy the predicate
--- without copying.
-dropWhile :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-dropWhile = G.dropWhile
-{-# INLINE dropWhile #-}
-
-
--- Parititioning
--- -------------
-
--- | /O(n)/ Split the vector in two parts, the first one containing those
--- elements that satisfy the predicate and the second one those that don't. The
--- relative order of the elements is preserved at the cost of a sometimes
--- reduced performance compared to 'unstablePartition'.
-partition :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> (Vector (Rec Identity rs), Vector (Rec Identity rs))
-{-# INLINE partition #-}
-partition = G.partition
-
--- | /O(n)/ Split the vector in two parts, the first one containing those
--- elements that satisfy the predicate and the second one those that don't.
--- The order of the elements is not preserved but the operation is often
--- faster than 'partition'.
-unstablePartition :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> (Vector (Rec Identity rs), Vector (Rec Identity rs))
-{-# INLINE unstablePartition #-}
-unstablePartition = G.unstablePartition
-
--- | /O(n)/ Split the vector into the longest prefix of elements that satisfy
--- the predicate and the rest without copying.
-span :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> (Vector (Rec Identity rs), Vector (Rec Identity rs))
-{-# INLINE span #-}
-span = G.span
-
--- | /O(n)/ Split the vector into the longest prefix of elements that do not
--- satisfy the predicate and the rest without copying.
-break :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> (Vector (Rec Identity rs), Vector (Rec Identity rs))
-{-# INLINE break #-}
-break = G.break
-
--- Searching
--- ---------
-
-infix 4 `elem`
--- | /O(n)/ Check if the vector contains an element
-elem :: (G.Vector Vector (Rec Identity rs), Eq (Rec Identity rs))
-  => Rec Identity rs -> Vector (Rec Identity rs) -> Bool
-elem = G.elem
-{-# INLINE elem #-}
-
-infix 4 `notElem`
--- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem')
-notElem :: (G.Vector Vector (Rec Identity rs), Eq (Rec Identity rs))
-  => Rec Identity rs -> Vector (Rec Identity rs) -> Bool
-notElem = G.notElem
-{-# INLINE notElem #-}
-
--- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing'
--- if no such element exists.
-find :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Maybe (Rec Identity rs)
-find = G.find
-{-# INLINE find #-}
-
--- | /O(n)/ Yield 'Just' the index of the first element matching the predicate
--- or 'Nothing' if no such element exists.
-findIndex :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Maybe Int
-findIndex = G.findIndex
-{-# INLINE findIndex #-}
-
-{-
--- | /O(n)/ Yield the indices of elements satisfying the predicate in ascending
--- order.
-findIndices :: ((a, b) -> Bool) -> Vector (Rec Identity rs) -> Vector u v Int
-findIndices = G.findIndices
-{-# INLINE findIndices #-}
--}
-
--- | /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 :: (G.Vector Vector (Rec Identity rs), Eq (Rec Identity rs))
-  => Rec Identity rs -> Vector (Rec Identity rs) -> Maybe Int
-elemIndex = G.elemIndex
-{-# INLINE elemIndex #-}
-
-{-
--- | /O(n)/ Yield the indices of all occurences of the given element in
--- ascending order. This is a specialised version of 'findIndices'.
-elemIndices :: (a, b) -> Vector (Rec Identity rs) -> Vector Int
-elemIndices = G.elemIndices
-{-# INLINE elemIndices #-}
--}
-
--- Folding
--- -------
-
--- | /O(n)/ Left fold
-foldl :: G.Vector Vector (Rec Identity rs)
-  => (r -> Rec Identity rs -> r) -> r -> Vector (Rec Identity rs) -> r
-foldl = G.foldl
-{-# INLINE foldl #-}
-
--- | /O(n)/ Left fold on non-empty vectors
-foldl1 :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Rec Identity rs
-foldl1 = G.foldl1
-{-# INLINE foldl1 #-}
-
--- | /O(n)/ Left fold with strict accumulator
-foldl' :: G.Vector Vector (Rec Identity rs)
-  => (r -> Rec Identity rs -> r) -> r -> Vector (Rec Identity rs) -> r
-foldl' = G.foldl'
-{-# INLINE foldl' #-}
-
--- | /O(n)/ Left fold on non-empty vectors with strict accumulator
-foldl1' :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Rec Identity rs
-foldl1' = G.foldl1'
-{-# INLINE foldl1' #-}
-
--- | /O(n)/ Right fold
-foldr :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> r -> r) -> r -> Vector (Rec Identity rs) -> r
-foldr = G.foldr
-{-# INLINE foldr #-}
-
--- | /O(n)/ Right fold on non-empty vectors
-foldr1 :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Rec Identity rs
-foldr1 = G.foldr1
-{-# INLINE foldr1 #-}
-
--- | /O(n)/ Right fold with a strict accumulator
-foldr' :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> r -> r) -> r -> Vector (Rec Identity rs) -> r
-foldr' = G.foldr'
-{-# INLINE foldr' #-}
-
--- | /O(n)/ Right fold on non-empty vectors with strict accumulator
-foldr1' :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Rec Identity rs
-foldr1' = G.foldr1'
-{-# INLINE foldr1' #-}
-
--- | /O(n)/ Left fold (function applied to each element and its index)
-ifoldl :: G.Vector Vector (Rec Identity rs)
-  => (r -> Int -> Rec Identity rs -> r) -> r -> Vector (Rec Identity rs) -> r
-ifoldl = G.ifoldl
-{-# INLINE ifoldl #-}
-
--- | /O(n)/ Left fold with strict accumulator (function applied to each element
--- and its index)
-ifoldl' :: G.Vector Vector (Rec Identity rs)
-  => (r -> Int -> Rec Identity rs -> r) -> r -> Vector (Rec Identity rs) -> r
-ifoldl' = G.ifoldl'
-{-# INLINE ifoldl' #-}
-
--- | /O(n)/ Right fold (function applied to each element and its index)
-ifoldr :: G.Vector Vector (Rec Identity rs)
-  => (Int -> Rec Identity rs -> r -> r) -> r -> Vector (Rec Identity rs) -> r
-ifoldr = G.ifoldr
-{-# INLINE ifoldr #-}
-
--- | /O(n)/ Right fold with strict accumulator (function applied to each
--- element and its index)
-ifoldr' :: G.Vector Vector (Rec Identity rs)
-  => (Int -> Rec Identity rs -> r -> r) -> r -> Vector (Rec Identity rs) -> r
-ifoldr' = G.ifoldr'
-{-# INLINE ifoldr' #-}
-
--- Specialised folds
--- -----------------
-
--- | /O(n)/ Check if all elements satisfy the predicate.
-all :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Bool
-{-# INLINE all #-}
-all = G.all
-
--- | /O(n)/ Check if any element satisfies the predicate.
-any :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Bool
-{-# INLINE any #-}
-any = G.any
-
-{-
--- | /O(n)/ Compute the sum of the elements
-sum :: Vector (Rec Identity rs) -> (a, b)
-{-# INLINE sum #-}
-sum = G.sum
-
--- | /O(n)/ Compute the product of the elements
-product :: Vector (Rec Identity rs) -> (a, b)
-{-# INLINE product #-}
-product = G.product
--}
-
--- | /O(n)/ Yield the maximum element of the vector. The vector may not be
--- empty.
-maximum :: (G.Vector Vector (Rec Identity rs), Ord (Rec Identity rs))
-  => Vector (Rec Identity rs) -> Rec Identity rs
-{-# INLINE maximum #-}
-maximum = G.maximum
-
--- | /O(n)/ Yield the maximum element of the vector according to the given
--- comparison function. The vector may not be empty.
-maximumBy :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Ordering) -> Vector (Rec Identity rs) -> Rec Identity rs
-{-# INLINE maximumBy #-}
-maximumBy = G.maximumBy
-
--- | /O(n)/ Yield the minimum element of the vector. The vector may not be
--- empty.
-minimum :: (G.Vector Vector (Rec Identity rs), Ord (Rec Identity rs))
-  => Vector (Rec Identity rs) -> Rec Identity rs
-{-# INLINE minimum #-}
-minimum = G.minimum
-
--- | /O(n)/ Yield the minimum element of the vector according to the given
--- comparison function. The vector may not be empty.
-minimumBy :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Ordering) -> Vector (Rec Identity rs) -> Rec Identity rs
-{-# INLINE minimumBy #-}
-minimumBy = G.minimumBy
-
--- | /O(n)/ Yield the index of the maximum element of the vector. The vector
--- may not be empty.
-maxIndex :: (G.Vector Vector (Rec Identity rs), Ord (Rec Identity rs))
-  => Vector (Rec Identity rs) -> Int
-{-# INLINE maxIndex #-}
-maxIndex = G.maxIndex
-
--- | /O(n)/ Yield the index of the maximum element of the vector according to
--- the given comparison function. The vector may not be empty.
-maxIndexBy :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Ordering) -> Vector (Rec Identity rs) -> Int
-{-# INLINE maxIndexBy #-}
-maxIndexBy = G.maxIndexBy
-
--- | /O(n)/ Yield the index of the minimum element of the vector. The vector
--- may not be empty.
-minIndex :: (G.Vector Vector (Rec Identity rs), Ord (Rec Identity rs))
-  => Vector (Rec Identity rs) -> Int
-{-# INLINE minIndex #-}
-minIndex = G.minIndex
-
--- | /O(n)/ Yield the index of the minimum element of the vector according to
--- the given comparison function. The vector may not be empty.
-minIndexBy :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Ordering) -> Vector (Rec Identity rs) -> Int
-{-# INLINE minIndexBy #-}
-minIndexBy = G.minIndexBy
-
--- Monadic folds
--- -------------
-
--- | /O(n)/ Monadic fold
-foldM :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => (r -> Rec Identity rs -> m r) -> r -> Vector (Rec Identity rs) -> m r
-foldM = G.foldM
-{-# INLINE foldM #-}
-
--- | /O(n)/ Monadic fold over non-empty vectors
-fold1M :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => (Rec Identity rs -> Rec Identity rs -> m (Rec Identity rs)) -> Vector (Rec Identity rs) -> m (Rec Identity rs)
-{-# INLINE fold1M #-}
-fold1M = G.fold1M
-
--- | /O(n)/ Monadic fold with strict accumulator
-foldM' :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => (r -> Rec Identity rs -> m r) -> r -> Vector (Rec Identity rs) -> m r
-{-# INLINE foldM' #-}
-foldM' = G.foldM'
-
--- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator
-fold1M' :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => (Rec Identity rs -> Rec Identity rs -> m (Rec Identity rs)) -> Vector (Rec Identity rs) -> m (Rec Identity rs)
-{-# INLINE fold1M' #-}
-fold1M' = G.fold1M'
-
--- | /O(n)/ Monadic fold that discards the result
-foldM_ :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => (r -> Rec Identity rs -> m r) -> r -> Vector (Rec Identity rs) -> m ()
-{-# INLINE foldM_ #-}
-foldM_ = G.foldM_
-
--- | /O(n)/ Monadic fold over non-empty vectors that discards the result
-fold1M_ :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => (Rec Identity rs -> Rec Identity rs -> m (Rec Identity rs)) -> Vector (Rec Identity rs) -> m ()
-{-# INLINE fold1M_ #-}
-fold1M_ = G.fold1M_
-
--- | /O(n)/ Monadic fold with strict accumulator that discards the result
-foldM'_ :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => (r -> Rec Identity rs -> m r) -> r -> Vector (Rec Identity rs) -> m ()
-{-# INLINE foldM'_ #-}
-foldM'_ = G.foldM'_
-
--- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator
--- that discards the result
-fold1M'_ :: (Monad m, G.Vector Vector (Rec Identity rs))
-  => (Rec Identity rs -> Rec Identity rs -> m (Rec Identity rs)) -> Vector (Rec Identity rs) -> m ()
-{-# INLINE fold1M'_ #-}
-fold1M'_ = G.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 :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
-prescanl = G.prescanl
-{-# INLINE prescanl #-}
-
--- | /O(n)/ Prescan with strict accumulator
-prescanl' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
-prescanl' = G.prescanl'
-{-# INLINE prescanl' #-}
-
--- | /O(n)/ Scan
---
--- @
--- postscanl f z = 'tail' . 'scanl' f z
--- @
---
--- Example: @postscanl (+) 0 \<1,2,3,4\> = \<1,3,6,10\>@
---
-postscanl :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
-postscanl = G.postscanl
-{-# INLINE postscanl #-}
-
--- | /O(n)/ Scan with strict accumulator
-postscanl' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
-postscanl' = G.postscanl'
-{-# INLINE postscanl' #-}
-
--- | /O(n)/ Haskell-style scan
---
--- > scanl f z <x1,...,xn> = <y1,...,y(n+1)>
--- >   where y1 = z
--- >         yi = f y(i-1) x(i-1)
---
--- Example: @scanl (+) 0 \<1,2,3,4\> = \<0,1,3,6,10\>@
---
-scanl :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
-scanl = G.scanl
-{-# INLINE scanl #-}
-
--- | /O(n)/ Haskell-style scan with strict accumulator
-scanl' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
-scanl' = G.scanl'
-{-# INLINE scanl' #-}
-
--- | /O(n)/ Scan over a non-empty vector
---
--- > scanl f <x1,...,xn> = <y1,...,yn>
--- >   where y1 = x1
--- >         yi = f y(i-1) xi
---
-scanl1 :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-scanl1 = G.scanl1
-{-# INLINE scanl1 #-}
-
--- | /O(n)/ Scan over a non-empty vector with a strict accumulator
-scanl1' :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-scanl1' = G.scanl1'
-{-# INLINE scanl1' #-}
-
--- | /O(n)/ Right-to-left prescan
---
--- @
--- prescanr f z = 'reverse' . 'prescanl' (flip f) z . 'reverse'
--- @
---
-prescanr :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
-{-# INLINE prescanr #-}
-prescanr = G.prescanr
-
--- | /O(n)/ Right-to-left prescan with strict accumulator
-prescanr' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
-prescanr' = G.prescanr'
-{-# INLINE prescanr' #-}
-
--- | /O(n)/ Right-to-left scan
-postscanr :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
-postscanr = G.postscanr
-{-# INLINE postscanr #-}
-
--- | /O(n)/ Right-to-left scan with strict accumulator
-postscanr' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
-postscanr' = G.postscanr'
-{-# INLINE postscanr' #-}
-
--- | /O(n)/ Right-to-left Haskell-style scan
-scanr :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
-scanr = G.scanr
-{-# INLINE scanr #-}
-
--- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator
-scanr' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
-  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
-scanr' = G.scanr'
-{-# INLINE scanr' #-}
-
--- | /O(n)/ Right-to-left scan over a non-empty vector
-scanr1 :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-{-# INLINE scanr1 #-}
-scanr1 = G.scanr1
-
--- | /O(n)/ Right-to-left scan over a non-empty vector with a strict
--- accumulator
-scanr1' :: G.Vector Vector (Rec Identity rs)
-  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
-{-# INLINE scanr1' #-}
-scanr1' = G.scanr1'
-
--- | /O(n)/ Convert a vector to a list
-toList :: G.Vector Vector (Rec Identity rs)
-  => Vector (Rec Identity rs) -> [Rec Identity rs]
-toList = G.toList
-{-# INLINE toList #-}
-
--- | /O(n)/ Convert a list to a vector
-fromList :: G.Vector Vector (Rec Identity rs)
-  => [Rec Identity rs] -> Vector (Rec Identity rs)
-fromList = G.fromList
-{-# INLINE fromList #-}
-
--- | /O(n)/ Convert the first @n@ elements of a list to a vector
---
--- @
--- fromListN n xs = 'fromList' ('take' n xs)
--- @
-fromListN :: G.Vector Vector (Rec Identity rs)
-  => Int -> [Rec Identity rs] -> Vector (Rec Identity rs)
-fromListN = G.fromListN
-{-# INLINE fromListN #-}
-
--- Conversions - Mutable vectors
--- -----------------------------
-
--- | /O(1)/ Unsafe convert a mutable vector to an immutable one without
--- copying. The mutable vector may not be used after this operation.
-unsafeFreeze :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
-             => G.Mutable Vector (PrimState m) (Rec Identity rs) -> m (Vector (Rec Identity rs))
-unsafeFreeze = G.unsafeFreeze
-{-# INLINE unsafeFreeze #-}
-
--- | /O(1)/ Unsafely convert an immutable vector to a mutable one without
--- copying. The immutable vector may not be used after this operation.
-unsafeThaw :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
-           => Vector (Rec Identity rs) -> m (G.Mutable Vector (PrimState m) (Rec Identity rs))
-unsafeThaw = G.unsafeThaw
-{-# INLINE unsafeThaw #-}
-
--- | /O(n)/ Yield a mutable copy of the immutable vector.
-thaw :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
-     => Vector (Rec Identity rs) -> m (G.Mutable Vector (PrimState m) (Rec Identity rs))
-thaw = G.thaw
-{-# INLINE thaw #-}
-
--- | /O(n)/ Yield an immutable copy of the mutable vector.
-freeze :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
-       => G.Mutable Vector (PrimState m) (Rec Identity rs) -> m (Vector (Rec Identity rs))
-freeze = G.freeze
-{-# INLINE freeze #-}
-
--- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must
--- have the same length. This is not checked.
-unsafeCopy :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
-           => G.Mutable Vector (PrimState m) (Rec Identity rs) -> Vector (Rec Identity rs) -> m ()
-unsafeCopy = G.unsafeCopy
-{-# INLINE unsafeCopy #-}
-
--- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must
--- have the same length.
-copy :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
-     => G.Mutable Vector (PrimState m) (Rec Identity rs) -> Vector (Rec Identity rs) -> m ()
-copy = G.copy
-{-# INLINE copy #-}
-
diff --git a/src/Data/Vector/Vinyl/Default/Empty/Monomorphic.hs b/src/Data/Vector/Vinyl/Default/Empty/Monomorphic.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/Empty/Monomorphic.hs
@@ -0,0 +1,1313 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE Rank2Types #-}
+-----------------------------------------------------------------------------
+-- |
+-- Copyright   :  Andrew Martin
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  Andrew Martin <andrew.thaddeus@gmail.com>
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- There are two vector types provided by this module: 'Vector' and
+-- 'MVector'. They must be parameterized over a type that unifies
+-- with 'Rec Identity rs'. An example would be:
+--
+-- > foo :: Vector (Rec Identity '[Int,Char,Bool])
+-- 
+-- This vector stores records that have an 'Int', a 'Char', and a 'Bool'.
+-----------------------------------------------------------------------------
+module Data.Vector.Vinyl.Default.Empty.Monomorphic
+  ( Vector, MVector
+
+  -- * Accessors
+
+  -- ** Length information
+  , length, null
+
+  -- ** Indexing
+  , (!), (!?), head, last
+  , unsafeIndex, unsafeHead, unsafeLast
+
+  -- ** Monadic indexing
+  , indexM, headM, lastM
+  , unsafeIndexM, unsafeHeadM, unsafeLastM
+
+  -- ** Extracting subvectors (slicing)
+  , slice, init, tail, take, drop, splitAt
+  , unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop
+
+  -- * Construction
+
+  -- ** Initialisation
+  , empty, singleton, replicate, generate, iterateN
+
+  -- ** Monadic initialisation
+  , replicateM, generateM, create
+
+  -- ** Unfolding
+  , unfoldr, unfoldrN
+  , constructN, constructrN
+
+  -- -- ** Enumeration
+  -- , enumFromN, enumFromStepN, enumFromTo, enumFromThenTo
+
+  -- ** Concatenation
+  , cons, snoc, (++), concat
+
+  -- ** Restricting memory usage
+  , force
+
+  -- * Modifying vectors
+
+  -- ** Bulk updates
+  , (//)
+  , unsafeUpd
+  -- , update_, unsafeUpdate_
+
+  -- ** Accumulations
+  , accum, unsafeAccum
+  -- , accumulate_, unsafeAccumulate_
+
+  -- ** Permutations
+  , reverse
+  -- , backpermute, unsafeBackpermute
+
+  -- ** Safe destructive updates
+  , modify
+
+  -- * Elementwise operations
+
+  -- ** Mapping
+  , map, imap, concatMap
+
+  -- ** Monadic mapping
+  , mapM, mapM_, forM, forM_
+
+  -- ** Zipping - Omitted due to me being lazy
+  -- , zipWith, zipWith3, zipWith4, zipWith5, zipWith6
+  -- , izipWith, izipWith3, izipWith4, izipWith5, izipWith6
+
+  -- ** Monadic zipping
+  , zipWithM, zipWithM_
+
+  -- * Working with predicates
+
+  -- ** Filtering
+  , filter, ifilter, filterM
+  , takeWhile, dropWhile
+
+  -- ** Partitioning
+  , partition, unstablePartition, span, break
+
+  -- ** Searching
+  , elem, notElem, find, findIndex
+  , elemIndex
+  -- , findIndices, elemIndices
+
+  -- * Folding
+  , foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1'
+  , ifoldl, ifoldl', ifoldr, ifoldr'
+
+  -- ** Specialised folds
+  , all, any
+  -- , sum, product
+  , maximum, maximumBy, minimum, minimumBy
+  , minIndex, minIndexBy, maxIndex, maxIndexBy
+
+  -- ** Monadic folds
+  , foldM, foldM', fold1M, fold1M'
+  , foldM_, foldM'_, fold1M_, fold1M'_
+
+  -- * Prefix sums (scans)
+  , prescanl, prescanl'
+  , postscanl, postscanl'
+  , scanl, scanl', scanl1, scanl1'
+  , prescanr, prescanr'
+  , postscanr, postscanr'
+  , scanr, scanr', scanr1, scanr1'
+
+  -- ** Lists
+  , toList, fromList, fromListN
+
+  -- ** Other vector types
+  , G.convert
+
+  -- ** Mutable vectors
+  , freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy
+  ) where
+
+import Control.Monad.Primitive
+import Control.Monad.ST
+import Data.Vector.Vinyl.Default.Empty.Monomorphic.Internal
+import Data.Vinyl.Core
+import Data.Vinyl.Functor (Identity(..))
+import qualified Data.Vector.Generic as G
+import Prelude hiding ( length, null,
+                        replicate, (++), concat,
+                        head, last,
+                        init, tail, take, drop, splitAt, reverse,
+                        map, concatMap,
+                        zipWith, zipWith3, zip, zip3, unzip, unzip3,
+                        filter, takeWhile, dropWhile, span, break,
+                        elem, notElem,
+                        foldl, foldl1, foldr, foldr1,
+                        all, any, sum, product, minimum, maximum,
+                        scanl, scanl1, scanr, scanr1,
+                        enumFromTo, enumFromThenTo,
+                        mapM, mapM_ )
+
+
+-- Length
+-- ------
+
+-- | /O(1)/ Yield the length of the vector.
+length :: Vector (Rec Identity rs) -> Int
+length (V i _) = i
+{-# INLINE length #-}
+
+-- | /O(1)/ Test whether a vector if empty
+null :: Vector (Rec Identity rs) -> Bool
+null (V i _) = i == 0
+{-# INLINE null #-}
+
+
+-- Indexing
+-- --------
+
+-- | O(1) Indexing
+(!) :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Int -> Rec Identity rs
+(!) = (G.!)
+{-# INLINE (!) #-}
+
+-- | O(1) Safe indexing
+(!?) :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Int -> Maybe (Rec Identity rs)
+(!?) = (G.!?)
+{-# INLINE (!?) #-}
+
+-- | /O(1)/ First element
+head :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Rec Identity rs
+head = G.head
+{-# INLINE head #-}
+
+-- | /O(1)/ Last element
+last :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Rec Identity rs
+last = G.last
+{-# INLINE last #-}
+
+
+-- | /O(1)/ Unsafe indexing without bounds checking
+unsafeIndex :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Int -> Rec Identity rs
+{-# INLINE unsafeIndex #-}
+unsafeIndex = G.unsafeIndex
+
+-- | /O(1)/ First element without checking if the vector is empty
+unsafeHead :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Rec Identity rs
+{-# INLINE unsafeHead #-}
+unsafeHead = G.unsafeHead
+
+-- | /O(1)/ Last element without checking if the vector is empty
+unsafeLast :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Rec Identity rs
+{-# INLINE unsafeLast #-}
+unsafeLast = G.unsafeLast
+
+-- Monadic indexing
+-- ----------------
+
+-- | /O(1)/ Indexing in a monad.
+--
+-- The monad allows operations to be strict in the vector when necessary.
+-- Suppose vector copying is implemented like this:
+--
+-- > copy mv v = ... write mv i (v ! i) ...
+--
+-- For lazy vectors, @v ! i@ would not be evaluated which means that @mv@
+-- would unnecessarily retain a reference to @v@ in each element written.
+--
+-- With 'indexM', copying can be implemented like this instead:
+--
+-- > copy mv v = ... do
+-- >                   x <- indexM v i
+-- >                   write mv i x
+--
+-- Here, no references to @v@ are retained because indexing (but /not/ the
+-- elements) is evaluated eagerly.
+--
+indexM :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => Vector (Rec Identity rs) -> Int -> m (Rec Identity rs)
+indexM = G.indexM
+{-# INLINE indexM #-}
+
+-- | /O(1)/ First element of a vector in a monad. See 'indexM' for an
+-- explanation of why this is useful.
+headM :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => Vector (Rec Identity rs) -> m (Rec Identity rs)
+headM = G.headM
+{-# INLINE headM #-}
+
+-- | /O(1)/ Last element of a vector in a monad. See 'indexM' for an
+-- explanation of why this is useful.
+lastM :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => Vector (Rec Identity rs) -> m (Rec Identity rs)
+lastM = G.lastM
+{-# INLINE lastM #-}
+
+-- | /O(1)/ Indexing in a monad without bounds checks. See 'indexM' for an
+-- explanation of why this is useful.
+unsafeIndexM :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => Vector (Rec Identity rs) -> Int -> m (Rec Identity rs)
+unsafeIndexM = G.unsafeIndexM
+{-# INLINE unsafeIndexM #-}
+
+-- | /O(1)/ First element in a monad without checking for empty vectors.
+-- See 'indexM' for an explanation of why this is useful.
+unsafeHeadM :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => Vector (Rec Identity rs) -> m (Rec Identity rs)
+unsafeHeadM = G.unsafeHeadM
+{-# INLINE unsafeHeadM #-}
+
+-- | /O(1)/ Last element in a monad without checking for empty vectors.
+-- See 'indexM' for an explanation of why this is useful.
+unsafeLastM :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => Vector (Rec Identity rs) -> m (Rec Identity rs)
+unsafeLastM = G.unsafeLastM
+{-# INLINE unsafeLastM #-}
+
+-- Extracting subvectors (slicing)
+-- -------------------------------
+
+-- | /O(1)/ Yield a slice of the vector without copying it. The vector must
+-- contain at least @i+n@ elements.
+slice :: G.Vector Vector (Rec Identity rs)
+      => Int   -- ^ @i@ starting index
+      -> Int   -- ^ @n@ length
+      -> Vector (Rec Identity rs)
+      -> Vector (Rec Identity rs)
+slice = G.slice
+{-# INLINE slice #-}
+
+-- | /O(1)/ Yield all but the last element without copying. The vector may not
+-- be empty.
+init :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+init = G.init
+{-# INLINE init #-}
+
+-- | /O(1)/ Yield all but the first element without copying. The vector may not
+-- be empty.
+tail :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+tail = G.tail
+{-# INLINE tail #-}
+
+-- | /O(1)/ Yield at the first @n@ elements without copying. The vector may
+-- contain less than @n@ elements in which case it is returned unchanged.
+take :: G.Vector Vector (Rec Identity rs)
+  => Int -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+take = G.take
+{-# INLINE take #-}
+
+-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may
+-- contain less than @n@ elements in which case an empty vector is returned.
+drop :: G.Vector Vector (Rec Identity rs)
+  => Int -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+drop = G.drop
+{-# INLINE drop #-}
+
+-- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying.
+--
+-- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@
+-- but slightly more efficient.
+splitAt :: G.Vector Vector (Rec Identity rs)
+  => Int -> Vector (Rec Identity rs) -> (Vector (Rec Identity rs), Vector (Rec Identity rs))
+splitAt = G.splitAt
+{-# INLINE splitAt #-}
+
+-- | /O(1)/ Yield a slice of the vector without copying. The vector must
+-- contain at least @i+n@ elements but this is not checked.
+unsafeSlice :: G.Vector Vector (Rec Identity rs)
+  => Int   -- ^ @i@ starting index
+                       -> Int   -- ^ @n@ length
+                       -> Vector (Rec Identity rs)
+                       -> Vector (Rec Identity rs)
+unsafeSlice = G.unsafeSlice
+{-# INLINE unsafeSlice #-}
+
+-- | /O(1)/ Yield all but the last element without copying. The vector may not
+-- be empty but this is not checked.
+unsafeInit :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+unsafeInit = G.unsafeInit
+{-# INLINE unsafeInit #-}
+
+-- | /O(1)/ Yield all but the first element without copying. The vector may not
+-- be empty but this is not checked.
+unsafeTail :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+unsafeTail = G.unsafeTail
+{-# INLINE unsafeTail #-}
+
+-- | /O(1)/ Yield the first @n@ elements without copying. The vector must
+-- contain at least @n@ elements but this is not checked.
+unsafeTake :: G.Vector Vector (Rec Identity rs)
+  => Int -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+unsafeTake = G.unsafeTake
+{-# INLINE unsafeTake #-}
+
+-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector
+-- must contain at least @n@ elements but this is not checked.
+unsafeDrop :: G.Vector Vector (Rec Identity rs)
+  => Int -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+unsafeDrop = G.unsafeDrop
+{-# INLINE unsafeDrop #-}
+
+-- Initialisation
+-- --------------
+
+-- | /O(1)/ Empty vector
+empty :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs)
+empty = G.empty
+{-# INLINE empty #-}
+
+-- | /O(1)/ Vector with exactly one element
+singleton :: G.Vector Vector (Rec Identity rs)
+  => Rec Identity rs -> Vector (Rec Identity rs)
+singleton = G.singleton
+{-# INLINE singleton #-}
+
+-- | /O(n)/ Vector of the given length with the same value in each position
+replicate :: G.Vector Vector (Rec Identity rs)
+  => Int -> Rec Identity rs -> Vector (Rec Identity rs)
+replicate = G.replicate
+{-# INLINE replicate #-}
+
+-- | /O(n)/ Construct a vector of the given length by applying the function to
+-- each index
+generate :: G.Vector Vector (Rec Identity rs)
+  => Int -> (Int -> Rec Identity rs) -> Vector (Rec Identity rs)
+generate = G.generate
+{-# INLINE generate #-}
+
+-- | /O(n)/ Apply function n times to value. Zeroth element is original value.
+iterateN :: G.Vector Vector (Rec Identity rs)
+  => Int -> (Rec Identity rs -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity rs)
+iterateN = G.iterateN
+{-# INLINE iterateN #-}
+
+-- Unfolding
+-- ---------
+
+-- | /O(n)/ Construct a vector by repeatedly applying the generator function
+-- to a seed. The generator function yields 'Just' the next element and the
+-- new seed or 'Nothing' if there are no more elements.
+--
+-- > unfoldr (\n -> if n == 0 then Nothing else Just (n,n-1)) 10
+-- >  = <10,9,8,7,6,5,4,3,2,1>
+unfoldr :: G.Vector Vector (Rec Identity rs)
+  => (c -> Maybe (Rec Identity rs, c)) -> c -> Vector (Rec Identity rs)
+unfoldr = G.unfoldr
+{-# INLINE unfoldr #-}
+
+-- | /O(n)/ Construct a vector with at most @n@ by repeatedly applying the
+-- generator function to the a seed. The generator function yields 'Just' the
+-- next element and the new seed or 'Nothing' if there are no more elements.
+--
+-- > unfoldrN 3 (\n -> Just (n,n-1)) 10 = <10,9,8>
+unfoldrN :: G.Vector Vector (Rec Identity rs)
+  => Int -> (c -> Maybe (Rec Identity rs, c)) -> c -> Vector (Rec Identity rs)
+unfoldrN = G.unfoldrN
+{-# INLINE unfoldrN #-}
+
+-- | /O(n)/ Construct a vector with @n@ elements by repeatedly applying the
+-- generator function to the already constructed part of the vector.
+--
+-- > constructN 3 f = let a = f <> ; b = f <a> ; c = f <a,b> in f <a,b,c>
+--
+constructN :: G.Vector Vector (Rec Identity rs)
+  => Int -> (Vector (Rec Identity rs) -> Rec Identity rs) -> Vector (Rec Identity rs)
+constructN = G.constructN
+{-# INLINE constructN #-}
+
+-- | /O(n)/ Construct a vector with @n@ elements from right to left by
+-- repeatedly applying the generator function to the already constructed part
+-- of the vector.
+--
+-- > constructrN 3 f = let a = f <> ; b = f<a> ; c = f <b,a> in f <c,b,a>
+--
+constructrN :: G.Vector Vector (Rec Identity rs)
+  => Int -> (Vector (Rec Identity rs) -> Rec Identity rs) -> Vector (Rec Identity rs)
+constructrN = G.constructrN
+{-# INLINE constructrN #-}
+
+-- Concatenation
+-- -------------
+
+-- | /O(n)/ Prepend an element
+cons :: G.Vector Vector (Rec Identity rs)
+  => Rec Identity rs -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+{-# INLINE cons #-}
+cons = G.cons
+
+-- | /O(n)/ Append an element
+snoc :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity rs)
+{-# INLINE snoc #-}
+snoc = G.snoc
+
+infixr 5 ++
+-- | /O(m+n)/ Concatenate two vectors
+(++) :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+{-# INLINE (++) #-}
+(++) = (G.++)
+
+-- | /O(n)/ Concatenate all vectors in the list
+concat :: G.Vector Vector (Rec Identity rs)
+  => [Vector (Rec Identity rs)] -> Vector (Rec Identity rs)
+{-# INLINE concat #-}
+concat = G.concat
+
+-- Monadic initialisation
+-- ----------------------
+
+-- | /O(n)/ Execute the monadic action the given number of times and store the
+-- results in a vector.
+replicateM :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => Int -> m (Rec Identity rs) -> m (Vector (Rec Identity rs))
+replicateM = G.replicateM
+{-# INLINE replicateM #-}
+
+-- | /O(n)/ Construct a vector of the given length by applying the monadic
+-- action to each index
+generateM :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => Int -> (Int -> m (Rec Identity rs)) -> m (Vector (Rec Identity rs))
+generateM = G.generateM
+{-# INLINE generateM #-}
+
+-- | Execute the monadic action and freeze the resulting vector.
+--
+-- @
+-- create (do { v \<- new 2; write v 0 \'a\'; write v 1 \'b\'; return v }) = \<'a','b'\>
+-- @
+create :: G.Vector Vector (Rec Identity rs)
+  => (forall s. ST s (G.Mutable Vector s (Rec Identity rs))) -> Vector (Rec Identity rs)
+-- NOTE: eta-expanded due to http://hackage.haskell.org/trac/ghc/ticket/4120
+create p = G.create p
+{-# INLINE create #-}
+
+-- 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 :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+force = G.force
+{-# INLINE force #-}
+
+-- 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>
+--
+(//) :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs)   -- ^ initial vector (of length @m@)
+                -> [(Int, Rec Identity rs)]                          -- ^ list of index/value pairs (of length @n@)
+                -> Vector (Rec Identity rs)
+(//) = (G.//)
+{-# INLINE (//) #-}
+
+-- | Same as ('//') but without bounds checking.
+unsafeUpd :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> [(Int, Rec Identity rs)] -> Vector (Rec Identity rs)
+unsafeUpd = G.unsafeUpd
+{-# INLINE unsafeUpd #-}
+
+-- Accumulations
+-- -------------
+
+-- | /O(m+n)/ For each pair @(i,c)@ from the list, replace the vector element
+-- @a@ at position @i@ by @f a c@.
+--
+-- > accum (+) <5,9,2> [(2,4),(1,6),(0,3),(1,7)] = <5+3, 9+6+7, 2+4>
+accum :: G.Vector Vector (Rec Identity rs)
+      => (Rec Identity rs -> c -> Rec Identity rs) -- ^ accumulating function @f@
+      -> Vector (Rec Identity rs)       -- ^ initial vector (of length @m@)
+      -> [(Int,c)]               -- ^ list of index/value pairs (of length @n@)
+      -> Vector (Rec Identity rs)
+accum = G.accum
+{-# INLINE accum #-}
+
+-- | Same as 'accum' but without bounds checking.
+unsafeAccum :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> c -> Rec Identity rs) -> Vector (Rec Identity rs) -> [(Int,c)] -> Vector (Rec Identity rs)
+unsafeAccum = G.unsafeAccum
+{-# INLINE unsafeAccum #-}
+
+
+-- Permutations
+-- ------------
+
+-- | /O(n)/ Reverse a vector
+reverse :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+{-# INLINE reverse #-}
+reverse = G.reverse
+
+-- Safe destructive updates
+-- ------------------------
+
+-- | Apply a destructive operation to a vector. The operation will be
+-- performed in place if it is safe to do so and will modify a copy of the
+-- vector otherwise.
+--
+-- @
+-- modify (\\v -> write v 0 \'x\') ('replicate' 3 \'a\') = \<\'x\',\'a\',\'a\'\>
+-- @
+modify :: (G.Vector Vector (Rec Identity rs))
+       => (forall s. G.Mutable Vector s (Rec Identity rs) -> ST s ())
+       -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+{-# INLINE modify #-}
+modify p = G.modify p
+
+-- Mapping
+-- -------
+
+-- | /O(n)/ Map a function over a vector
+map :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+    => (Rec Identity rs -> Rec Identity ss) -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
+map = G.map
+{-# INLINE map #-}
+
+-- | /O(n)/ Apply a function to every element of a vector and its index
+imap :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+     => (Int -> Rec Identity rs -> Rec Identity ss)
+     -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
+imap = G.imap
+{-# INLINE imap #-}
+
+-- | Map a function over a vector and concatenate the results.
+concatMap :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+          => (Rec Identity rs -> Vector (Rec Identity ss)) -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
+concatMap = G.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, G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> m (Rec Identity ss)) -> Vector (Rec Identity rs) -> m (Vector (Rec Identity ss))
+mapM = G.mapM
+{-# INLINE mapM #-}
+
+-- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the
+-- results
+mapM_ :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => (Rec Identity rs -> m b) -> Vector (Rec Identity rs) -> m ()
+mapM_ = G.mapM_
+{-# INLINE mapM_ #-}
+
+-- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a
+-- vector of results. Equvalent to @flip 'mapM'@.
+forM :: (Monad m, G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => Vector (Rec Identity rs) -> (Rec Identity rs -> m (Rec Identity ss)) -> m (Vector (Rec Identity ss))
+forM = G.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, G.Vector Vector (Rec Identity rs))
+  => Vector (Rec Identity rs) -> (Rec Identity rs -> m b) -> m ()
+forM_ = G.forM_
+{-# INLINE forM_ #-}
+
+-- Zipping
+-- -------
+
+--   -- | /O(min(m,n))/ Zip two vectors with the given function.
+--   zipWith :: ( G.Vector u a, G.Vector v a'
+--              , G.Vector u b, G.Vector v b'
+--              , G.Vector u c, G.Vector v c'
+--              ) => ((a,a') -> (b,b') -> (c,c'))
+--                -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c')
+--   zipWith = G.zipWith
+--   {-# INLINE zipWith #-}
+--   
+--   -- | Zip three vectors with the given function.
+--   
+--   zipWith3 :: ( G.Vector u a, G.Vector v a'
+--               , G.Vector u b, G.Vector v b'
+--               , G.Vector u c, G.Vector v c'
+--               , G.Vector u d, G.Vector v d'
+--               ) => ((a,a') -> (b,b') -> (c,c') -> (d, d'))
+--                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d')
+--   zipWith3 = G.zipWith3
+--   {-# INLINE zipWith3 #-}
+--   
+--   zipWith4 :: ( G.Vector u a, G.Vector v a'
+--               , G.Vector u b, G.Vector v b'
+--               , G.Vector u c, G.Vector v c'
+--               , G.Vector u d, G.Vector v d'
+--               , G.Vector u e, G.Vector v e'
+--               ) => ((a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e'))
+--                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e')
+--   zipWith4 = G.zipWith4
+--   {-# INLINE zipWith4 #-}
+--   
+--   zipWith5 :: ( G.Vector u a, G.Vector v a'
+--               , G.Vector u b, G.Vector v b'
+--               , G.Vector u c, G.Vector v c'
+--               , G.Vector u d, G.Vector v d'
+--               , G.Vector u e, G.Vector v e'
+--               , G.Vector u f, G.Vector v f'
+--               ) => ((a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f'))
+--                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f')
+--   zipWith5 = G.zipWith5
+--   {-# INLINE zipWith5 #-}
+--   
+--   zipWith6 :: ( G.Vector u a, G.Vector v a'
+--               , G.Vector u b, G.Vector v b'
+--               , G.Vector u c, G.Vector v c'
+--               , G.Vector u d, G.Vector v d'
+--               , G.Vector u e, G.Vector v e'
+--               , G.Vector u f, G.Vector v f'
+--               , G.Vector u g, G.Vector v g'
+--               ) => ((a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f') -> (g,g'))
+--                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f') -> Vector u v (g,g')
+--   zipWith6 = G.zipWith6
+--   {-# INLINE zipWith6 #-}
+--   
+--   -- | /O(min(m,n))/ Zip two vectors with a function that also takes the
+--   -- elements' indices.
+--   izipWith :: ( G.Vector u a, G.Vector v a'
+--               , G.Vector u b, G.Vector v b'
+--               , G.Vector u c, G.Vector v c'
+--               ) => (Int -> (a,a') -> (b,b') -> (c,c'))
+--                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c')
+--   izipWith = G.izipWith
+--   {-# INLINE izipWith #-}
+--   
+--   -- | Zip three vectors and their indices with the given function.
+--   izipWith3 :: ( G.Vector u a, G.Vector v a'
+--               , G.Vector u b, G.Vector v b'
+--               , G.Vector u c, G.Vector v c'
+--               , G.Vector u d, G.Vector v d'
+--               ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d'))
+--                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d')
+--   izipWith3 = G.izipWith3
+--   {-# INLINE izipWith3 #-}
+--   
+--   izipWith4 :: ( G.Vector u a, G.Vector v a'
+--               , G.Vector u b, G.Vector v b'
+--               , G.Vector u c, G.Vector v c'
+--               , G.Vector u d, G.Vector v d'
+--               , G.Vector u e, G.Vector v e'
+--               ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e'))
+--                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e')
+--   izipWith4 = G.izipWith4
+--   {-# INLINE izipWith4 #-}
+--   
+--   izipWith5 :: ( G.Vector u a, G.Vector v a'
+--               , G.Vector u b, G.Vector v b'
+--               , G.Vector u c, G.Vector v c'
+--               , G.Vector u d, G.Vector v d'
+--               , G.Vector u e, G.Vector v e'
+--               , G.Vector u f, G.Vector v f'
+--               ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f'))
+--                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f')
+--   izipWith5 = G.izipWith5
+--   {-# INLINE izipWith5 #-}
+--   
+--   izipWith6 :: ( G.Vector u a, G.Vector v a'
+--               , G.Vector u b, G.Vector v b'
+--               , G.Vector u c, G.Vector v c'
+--               , G.Vector u d, G.Vector v d'
+--               , G.Vector u e, G.Vector v e'
+--               , G.Vector u f, G.Vector v f'
+--               , G.Vector u g, G.Vector v g'
+--               ) => (Int -> (a,a') -> (b,b') -> (c,c') -> (d, d') -> (e,e') -> (f,f') -> (g,g'))
+--                 -> Vector u v (a,a') -> Vector u v (b,b') -> Vector u v (c,c') -> Vector u v (d,d') -> Vector u v (e,e') -> Vector u v (f,f') -> Vector u v (g,g')
+--   izipWith6 = G.izipWith6
+--   {-# INLINE izipWith6 #-}
+
+-- Monadic zipping
+-- ---------------
+
+-- | /O(min(m,n))/ Zip the two vectors with the monadic action and yield a
+-- vector of results
+zipWithM :: (Monad m, G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss), G.Vector Vector (Rec Identity ts))
+         => (Rec Identity rs -> Rec Identity ss -> m (Rec Identity ts)) -> Vector (Rec Identity rs) -> Vector (Rec Identity ss) -> m (Vector (Rec Identity ts))
+zipWithM = G.zipWithM
+{-# INLINE zipWithM #-}
+
+-- | /O(min(m,n))/ Zip the two vectors with the monadic action and ignore the
+-- results
+zipWithM_ :: (Monad m, G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+          => (Rec Identity rs -> Rec Identity ss -> m e) -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)-> m ()
+zipWithM_ = G.zipWithM_
+{-# INLINE zipWithM_ #-}
+
+-- Filtering
+-- ---------
+
+-- | /O(n)/ Drop elements that do not satisfy the predicate
+filter :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+filter = G.filter
+{-# INLINE filter #-}
+
+-- | /O(n)/ Drop elements that do not satisfy the predicate which is applied to
+-- values and their indices
+ifilter :: G.Vector Vector (Rec Identity rs)
+  => (Int -> Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+ifilter = G.ifilter
+{-# INLINE ifilter #-}
+
+-- | /O(n)/ Drop elements that do not satisfy the monadic predicate
+filterM :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => (Rec Identity rs -> m Bool) -> Vector (Rec Identity rs) -> m (Vector (Rec Identity rs))
+filterM = G.filterM
+{-# INLINE filterM #-}
+
+-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate
+-- without copying.
+takeWhile :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+takeWhile = G.takeWhile
+{-# INLINE takeWhile #-}
+
+-- | /O(n)/ Drop the longest prefix of elements that satisfy the predicate
+-- without copying.
+dropWhile :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+dropWhile = G.dropWhile
+{-# INLINE dropWhile #-}
+
+
+-- Parititioning
+-- -------------
+
+-- | /O(n)/ Split the vector in two parts, the first one containing those
+-- elements that satisfy the predicate and the second one those that don't. The
+-- relative order of the elements is preserved at the cost of a sometimes
+-- reduced performance compared to 'unstablePartition'.
+partition :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> (Vector (Rec Identity rs), Vector (Rec Identity rs))
+{-# INLINE partition #-}
+partition = G.partition
+
+-- | /O(n)/ Split the vector in two parts, the first one containing those
+-- elements that satisfy the predicate and the second one those that don't.
+-- The order of the elements is not preserved but the operation is often
+-- faster than 'partition'.
+unstablePartition :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> (Vector (Rec Identity rs), Vector (Rec Identity rs))
+{-# INLINE unstablePartition #-}
+unstablePartition = G.unstablePartition
+
+-- | /O(n)/ Split the vector into the longest prefix of elements that satisfy
+-- the predicate and the rest without copying.
+span :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> (Vector (Rec Identity rs), Vector (Rec Identity rs))
+{-# INLINE span #-}
+span = G.span
+
+-- | /O(n)/ Split the vector into the longest prefix of elements that do not
+-- satisfy the predicate and the rest without copying.
+break :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> (Vector (Rec Identity rs), Vector (Rec Identity rs))
+{-# INLINE break #-}
+break = G.break
+
+-- Searching
+-- ---------
+
+infix 4 `elem`
+-- | /O(n)/ Check if the vector contains an element
+elem :: (G.Vector Vector (Rec Identity rs), Eq (Rec Identity rs))
+  => Rec Identity rs -> Vector (Rec Identity rs) -> Bool
+elem = G.elem
+{-# INLINE elem #-}
+
+infix 4 `notElem`
+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem')
+notElem :: (G.Vector Vector (Rec Identity rs), Eq (Rec Identity rs))
+  => Rec Identity rs -> Vector (Rec Identity rs) -> Bool
+notElem = G.notElem
+{-# INLINE notElem #-}
+
+-- | /O(n)/ Yield 'Just' the first element matching the predicate or 'Nothing'
+-- if no such element exists.
+find :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Maybe (Rec Identity rs)
+find = G.find
+{-# INLINE find #-}
+
+-- | /O(n)/ Yield 'Just' the index of the first element matching the predicate
+-- or 'Nothing' if no such element exists.
+findIndex :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Maybe Int
+findIndex = G.findIndex
+{-# INLINE findIndex #-}
+
+{-
+-- | /O(n)/ Yield the indices of elements satisfying the predicate in ascending
+-- order.
+findIndices :: ((a, b) -> Bool) -> Vector (Rec Identity rs) -> Vector u v Int
+findIndices = G.findIndices
+{-# INLINE findIndices #-}
+-}
+
+-- | /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 :: (G.Vector Vector (Rec Identity rs), Eq (Rec Identity rs))
+  => Rec Identity rs -> Vector (Rec Identity rs) -> Maybe Int
+elemIndex = G.elemIndex
+{-# INLINE elemIndex #-}
+
+{-
+-- | /O(n)/ Yield the indices of all occurences of the given element in
+-- ascending order. This is a specialised version of 'findIndices'.
+elemIndices :: (a, b) -> Vector (Rec Identity rs) -> Vector Int
+elemIndices = G.elemIndices
+{-# INLINE elemIndices #-}
+-}
+
+-- Folding
+-- -------
+
+-- | /O(n)/ Left fold
+foldl :: G.Vector Vector (Rec Identity rs)
+  => (r -> Rec Identity rs -> r) -> r -> Vector (Rec Identity rs) -> r
+foldl = G.foldl
+{-# INLINE foldl #-}
+
+-- | /O(n)/ Left fold on non-empty vectors
+foldl1 :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Rec Identity rs
+foldl1 = G.foldl1
+{-# INLINE foldl1 #-}
+
+-- | /O(n)/ Left fold with strict accumulator
+foldl' :: G.Vector Vector (Rec Identity rs)
+  => (r -> Rec Identity rs -> r) -> r -> Vector (Rec Identity rs) -> r
+foldl' = G.foldl'
+{-# INLINE foldl' #-}
+
+-- | /O(n)/ Left fold on non-empty vectors with strict accumulator
+foldl1' :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Rec Identity rs
+foldl1' = G.foldl1'
+{-# INLINE foldl1' #-}
+
+-- | /O(n)/ Right fold
+foldr :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> r -> r) -> r -> Vector (Rec Identity rs) -> r
+foldr = G.foldr
+{-# INLINE foldr #-}
+
+-- | /O(n)/ Right fold on non-empty vectors
+foldr1 :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Rec Identity rs
+foldr1 = G.foldr1
+{-# INLINE foldr1 #-}
+
+-- | /O(n)/ Right fold with a strict accumulator
+foldr' :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> r -> r) -> r -> Vector (Rec Identity rs) -> r
+foldr' = G.foldr'
+{-# INLINE foldr' #-}
+
+-- | /O(n)/ Right fold on non-empty vectors with strict accumulator
+foldr1' :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Rec Identity rs
+foldr1' = G.foldr1'
+{-# INLINE foldr1' #-}
+
+-- | /O(n)/ Left fold (function applied to each element and its index)
+ifoldl :: G.Vector Vector (Rec Identity rs)
+  => (r -> Int -> Rec Identity rs -> r) -> r -> Vector (Rec Identity rs) -> r
+ifoldl = G.ifoldl
+{-# INLINE ifoldl #-}
+
+-- | /O(n)/ Left fold with strict accumulator (function applied to each element
+-- and its index)
+ifoldl' :: G.Vector Vector (Rec Identity rs)
+  => (r -> Int -> Rec Identity rs -> r) -> r -> Vector (Rec Identity rs) -> r
+ifoldl' = G.ifoldl'
+{-# INLINE ifoldl' #-}
+
+-- | /O(n)/ Right fold (function applied to each element and its index)
+ifoldr :: G.Vector Vector (Rec Identity rs)
+  => (Int -> Rec Identity rs -> r -> r) -> r -> Vector (Rec Identity rs) -> r
+ifoldr = G.ifoldr
+{-# INLINE ifoldr #-}
+
+-- | /O(n)/ Right fold with strict accumulator (function applied to each
+-- element and its index)
+ifoldr' :: G.Vector Vector (Rec Identity rs)
+  => (Int -> Rec Identity rs -> r -> r) -> r -> Vector (Rec Identity rs) -> r
+ifoldr' = G.ifoldr'
+{-# INLINE ifoldr' #-}
+
+-- Specialised folds
+-- -----------------
+
+-- | /O(n)/ Check if all elements satisfy the predicate.
+all :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Bool
+{-# INLINE all #-}
+all = G.all
+
+-- | /O(n)/ Check if any element satisfies the predicate.
+any :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Bool) -> Vector (Rec Identity rs) -> Bool
+{-# INLINE any #-}
+any = G.any
+
+{-
+-- | /O(n)/ Compute the sum of the elements
+sum :: Vector (Rec Identity rs) -> (a, b)
+{-# INLINE sum #-}
+sum = G.sum
+
+-- | /O(n)/ Compute the product of the elements
+product :: Vector (Rec Identity rs) -> (a, b)
+{-# INLINE product #-}
+product = G.product
+-}
+
+-- | /O(n)/ Yield the maximum element of the vector. The vector may not be
+-- empty.
+maximum :: (G.Vector Vector (Rec Identity rs), Ord (Rec Identity rs))
+  => Vector (Rec Identity rs) -> Rec Identity rs
+{-# INLINE maximum #-}
+maximum = G.maximum
+
+-- | /O(n)/ Yield the maximum element of the vector according to the given
+-- comparison function. The vector may not be empty.
+maximumBy :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Ordering) -> Vector (Rec Identity rs) -> Rec Identity rs
+{-# INLINE maximumBy #-}
+maximumBy = G.maximumBy
+
+-- | /O(n)/ Yield the minimum element of the vector. The vector may not be
+-- empty.
+minimum :: (G.Vector Vector (Rec Identity rs), Ord (Rec Identity rs))
+  => Vector (Rec Identity rs) -> Rec Identity rs
+{-# INLINE minimum #-}
+minimum = G.minimum
+
+-- | /O(n)/ Yield the minimum element of the vector according to the given
+-- comparison function. The vector may not be empty.
+minimumBy :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Ordering) -> Vector (Rec Identity rs) -> Rec Identity rs
+{-# INLINE minimumBy #-}
+minimumBy = G.minimumBy
+
+-- | /O(n)/ Yield the index of the maximum element of the vector. The vector
+-- may not be empty.
+maxIndex :: (G.Vector Vector (Rec Identity rs), Ord (Rec Identity rs))
+  => Vector (Rec Identity rs) -> Int
+{-# INLINE maxIndex #-}
+maxIndex = G.maxIndex
+
+-- | /O(n)/ Yield the index of the maximum element of the vector according to
+-- the given comparison function. The vector may not be empty.
+maxIndexBy :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Ordering) -> Vector (Rec Identity rs) -> Int
+{-# INLINE maxIndexBy #-}
+maxIndexBy = G.maxIndexBy
+
+-- | /O(n)/ Yield the index of the minimum element of the vector. The vector
+-- may not be empty.
+minIndex :: (G.Vector Vector (Rec Identity rs), Ord (Rec Identity rs))
+  => Vector (Rec Identity rs) -> Int
+{-# INLINE minIndex #-}
+minIndex = G.minIndex
+
+-- | /O(n)/ Yield the index of the minimum element of the vector according to
+-- the given comparison function. The vector may not be empty.
+minIndexBy :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Ordering) -> Vector (Rec Identity rs) -> Int
+{-# INLINE minIndexBy #-}
+minIndexBy = G.minIndexBy
+
+-- Monadic folds
+-- -------------
+
+-- | /O(n)/ Monadic fold
+foldM :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => (r -> Rec Identity rs -> m r) -> r -> Vector (Rec Identity rs) -> m r
+foldM = G.foldM
+{-# INLINE foldM #-}
+
+-- | /O(n)/ Monadic fold over non-empty vectors
+fold1M :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => (Rec Identity rs -> Rec Identity rs -> m (Rec Identity rs)) -> Vector (Rec Identity rs) -> m (Rec Identity rs)
+{-# INLINE fold1M #-}
+fold1M = G.fold1M
+
+-- | /O(n)/ Monadic fold with strict accumulator
+foldM' :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => (r -> Rec Identity rs -> m r) -> r -> Vector (Rec Identity rs) -> m r
+{-# INLINE foldM' #-}
+foldM' = G.foldM'
+
+-- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator
+fold1M' :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => (Rec Identity rs -> Rec Identity rs -> m (Rec Identity rs)) -> Vector (Rec Identity rs) -> m (Rec Identity rs)
+{-# INLINE fold1M' #-}
+fold1M' = G.fold1M'
+
+-- | /O(n)/ Monadic fold that discards the result
+foldM_ :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => (r -> Rec Identity rs -> m r) -> r -> Vector (Rec Identity rs) -> m ()
+{-# INLINE foldM_ #-}
+foldM_ = G.foldM_
+
+-- | /O(n)/ Monadic fold over non-empty vectors that discards the result
+fold1M_ :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => (Rec Identity rs -> Rec Identity rs -> m (Rec Identity rs)) -> Vector (Rec Identity rs) -> m ()
+{-# INLINE fold1M_ #-}
+fold1M_ = G.fold1M_
+
+-- | /O(n)/ Monadic fold with strict accumulator that discards the result
+foldM'_ :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => (r -> Rec Identity rs -> m r) -> r -> Vector (Rec Identity rs) -> m ()
+{-# INLINE foldM'_ #-}
+foldM'_ = G.foldM'_
+
+-- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator
+-- that discards the result
+fold1M'_ :: (Monad m, G.Vector Vector (Rec Identity rs))
+  => (Rec Identity rs -> Rec Identity rs -> m (Rec Identity rs)) -> Vector (Rec Identity rs) -> m ()
+{-# INLINE fold1M'_ #-}
+fold1M'_ = G.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 :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
+prescanl = G.prescanl
+{-# INLINE prescanl #-}
+
+-- | /O(n)/ Prescan with strict accumulator
+prescanl' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
+prescanl' = G.prescanl'
+{-# INLINE prescanl' #-}
+
+-- | /O(n)/ Scan
+--
+-- @
+-- postscanl f z = 'tail' . 'scanl' f z
+-- @
+--
+-- Example: @postscanl (+) 0 \<1,2,3,4\> = \<1,3,6,10\>@
+--
+postscanl :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
+postscanl = G.postscanl
+{-# INLINE postscanl #-}
+
+-- | /O(n)/ Scan with strict accumulator
+postscanl' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
+postscanl' = G.postscanl'
+{-# INLINE postscanl' #-}
+
+-- | /O(n)/ Haskell-style scan
+--
+-- > scanl f z <x1,...,xn> = <y1,...,y(n+1)>
+-- >   where y1 = z
+-- >         yi = f y(i-1) x(i-1)
+--
+-- Example: @scanl (+) 0 \<1,2,3,4\> = \<0,1,3,6,10\>@
+--
+scanl :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
+scanl = G.scanl
+{-# INLINE scanl #-}
+
+-- | /O(n)/ Haskell-style scan with strict accumulator
+scanl' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity rs) -> Rec Identity rs -> Vector (Rec Identity ss) -> Vector (Rec Identity rs)
+scanl' = G.scanl'
+{-# INLINE scanl' #-}
+
+-- | /O(n)/ Scan over a non-empty vector
+--
+-- > scanl f <x1,...,xn> = <y1,...,yn>
+-- >   where y1 = x1
+-- >         yi = f y(i-1) xi
+--
+scanl1 :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+scanl1 = G.scanl1
+{-# INLINE scanl1 #-}
+
+-- | /O(n)/ Scan over a non-empty vector with a strict accumulator
+scanl1' :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+scanl1' = G.scanl1'
+{-# INLINE scanl1' #-}
+
+-- | /O(n)/ Right-to-left prescan
+--
+-- @
+-- prescanr f z = 'reverse' . 'prescanl' (flip f) z . 'reverse'
+-- @
+--
+prescanr :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
+{-# INLINE prescanr #-}
+prescanr = G.prescanr
+
+-- | /O(n)/ Right-to-left prescan with strict accumulator
+prescanr' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
+prescanr' = G.prescanr'
+{-# INLINE prescanr' #-}
+
+-- | /O(n)/ Right-to-left scan
+postscanr :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
+postscanr = G.postscanr
+{-# INLINE postscanr #-}
+
+-- | /O(n)/ Right-to-left scan with strict accumulator
+postscanr' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
+postscanr' = G.postscanr'
+{-# INLINE postscanr' #-}
+
+-- | /O(n)/ Right-to-left Haskell-style scan
+scanr :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
+scanr = G.scanr
+{-# INLINE scanr #-}
+
+-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator
+scanr' :: (G.Vector Vector (Rec Identity rs), G.Vector Vector (Rec Identity ss))
+  => (Rec Identity rs -> Rec Identity ss -> Rec Identity ss) -> Rec Identity ss -> Vector (Rec Identity rs) -> Vector (Rec Identity ss)
+scanr' = G.scanr'
+{-# INLINE scanr' #-}
+
+-- | /O(n)/ Right-to-left scan over a non-empty vector
+scanr1 :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+{-# INLINE scanr1 #-}
+scanr1 = G.scanr1
+
+-- | /O(n)/ Right-to-left scan over a non-empty vector with a strict
+-- accumulator
+scanr1' :: G.Vector Vector (Rec Identity rs)
+  => (Rec Identity rs -> Rec Identity rs -> Rec Identity rs) -> Vector (Rec Identity rs) -> Vector (Rec Identity rs)
+{-# INLINE scanr1' #-}
+scanr1' = G.scanr1'
+
+-- | /O(n)/ Convert a vector to a list
+toList :: G.Vector Vector (Rec Identity rs)
+  => Vector (Rec Identity rs) -> [Rec Identity rs]
+toList = G.toList
+{-# INLINE toList #-}
+
+-- | /O(n)/ Convert a list to a vector
+fromList :: G.Vector Vector (Rec Identity rs)
+  => [Rec Identity rs] -> Vector (Rec Identity rs)
+fromList = G.fromList
+{-# INLINE fromList #-}
+
+-- | /O(n)/ Convert the first @n@ elements of a list to a vector
+--
+-- @
+-- fromListN n xs = 'fromList' ('take' n xs)
+-- @
+fromListN :: G.Vector Vector (Rec Identity rs)
+  => Int -> [Rec Identity rs] -> Vector (Rec Identity rs)
+fromListN = G.fromListN
+{-# INLINE fromListN #-}
+
+-- Conversions - Mutable vectors
+-- -----------------------------
+
+-- | /O(1)/ Unsafe convert a mutable vector to an immutable one without
+-- copying. The mutable vector may not be used after this operation.
+unsafeFreeze :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
+             => G.Mutable Vector (PrimState m) (Rec Identity rs) -> m (Vector (Rec Identity rs))
+unsafeFreeze = G.unsafeFreeze
+{-# INLINE unsafeFreeze #-}
+
+-- | /O(1)/ Unsafely convert an immutable vector to a mutable one without
+-- copying. The immutable vector may not be used after this operation.
+unsafeThaw :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
+           => Vector (Rec Identity rs) -> m (G.Mutable Vector (PrimState m) (Rec Identity rs))
+unsafeThaw = G.unsafeThaw
+{-# INLINE unsafeThaw #-}
+
+-- | /O(n)/ Yield a mutable copy of the immutable vector.
+thaw :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
+     => Vector (Rec Identity rs) -> m (G.Mutable Vector (PrimState m) (Rec Identity rs))
+thaw = G.thaw
+{-# INLINE thaw #-}
+
+-- | /O(n)/ Yield an immutable copy of the mutable vector.
+freeze :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
+       => G.Mutable Vector (PrimState m) (Rec Identity rs) -> m (Vector (Rec Identity rs))
+freeze = G.freeze
+{-# INLINE freeze #-}
+
+-- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must
+-- have the same length. This is not checked.
+unsafeCopy :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
+           => G.Mutable Vector (PrimState m) (Rec Identity rs) -> Vector (Rec Identity rs) -> m ()
+unsafeCopy = G.unsafeCopy
+{-# INLINE unsafeCopy #-}
+
+-- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must
+-- have the same length.
+copy :: (PrimMonad m, G.Vector Vector (Rec Identity rs))
+     => G.Mutable Vector (PrimState m) (Rec Identity rs) -> Vector (Rec Identity rs) -> m ()
+copy = G.copy
+{-# INLINE copy #-}
+
diff --git a/src/Data/Vector/Vinyl/Default/Empty/Monomorphic/Implication.hs b/src/Data/Vector/Vinyl/Default/Empty/Monomorphic/Implication.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/Empty/Monomorphic/Implication.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE GADTs #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Copyright   :  Andrew Martin
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  Andrew Martin <andrew.thaddeus@gmail.com>
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- This module uses the "constraints" package to prove that if all of the
+-- columns satisfy the 'HasDefaultVector' constraint, then a vector 
+-- parameterized over the record has an instance of the generic vector 
+-- typeclass.
+-----------------------------------------------------------------------------
+module Data.Vector.Vinyl.Default.Empty.Monomorphic.Implication where
+
+import Data.Constraint
+import Data.Vector.Vinyl.Default.Empty.Monomorphic.Internal
+import Data.Vinyl.Core (Rec(..))
+import Data.Vinyl.Functor (Identity(..))
+import Data.Vector.Vinyl.TypeLevel (ListAll)
+
+import qualified Data.Vector.Generic.Mutable as GM
+import qualified Data.Vector.Generic as G
+
+listAllVector :: Rec proxy rs 
+              -> ListAll rs HasDefaultVector :- G.Vector Vector (Rec Identity rs)
+listAllVector RNil = Sub Dict
+listAllVector (_ :& rs) = Sub $ case listAllVector rs of
+  Sub Dict -> Dict
+
+listAllMVector :: Rec proxy rs 
+              -> ListAll rs HasDefaultVector :- GM.MVector MVector (Rec Identity rs)
+listAllMVector RNil = Sub Dict
+listAllMVector (_ :& rs) = Sub $ case listAllMVector rs of
+  Sub Dict -> Dict
+
+-- listAllVectorBoth :: Rec proxy rs 
+--   -> ListAll rs HasDefaultVector :- (GM.MVector MVector (Rec Identity rs), G.Vector Vector (Rec Identity rs))
+-- listAllVectorBoth RNil = Sub Dict
+-- listAllVectorBoth (_ :& rs) = Sub $ case listAllVectorBoth rs of
+--   Sub Dict -> Dict
+
diff --git a/src/Data/Vector/Vinyl/Default/Empty/Monomorphic/Internal.hs b/src/Data/Vector/Vinyl/Default/Empty/Monomorphic/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/Empty/Monomorphic/Internal.hs
@@ -0,0 +1,231 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE InstanceSigs #-}
+
+#ifndef MIN_VERSION_vector
+#define MIN_VERSION_vector(x,y,z) 1
+#endif
+
+module Data.Vector.Vinyl.Default.Empty.Monomorphic.Internal
+  ( MVector(..)
+  , Vector(..)
+  , HasDefaultVector(..)
+  ) where
+
+import Control.Monad
+import Data.Monoid
+import Data.Typeable (Typeable)
+import GHC.Exts (Constraint)
+import Control.Monad.Primitive (PrimMonad,PrimState)
+import qualified Data.Vector.Generic.Mutable as GM
+import qualified Data.Vector.Generic as G
+
+#if MIN_VERSION_vector(0,11,0)
+import Data.Vector.Fusion.Bundle as Stream
+#else
+import Data.Vector.Fusion.Stream as Stream
+#endif
+
+import Prelude hiding ( length, null, replicate, reverse, map, read, take, drop, init, tail )
+import Text.Read
+import Data.Proxy
+
+import Data.Vinyl.Core(Rec(..))
+import Data.Vinyl.Functor (Identity(..))
+import Data.Vector.Vinyl.Default.Types (VectorVal(..),MVectorVal(..),HasDefaultVector(..))
+
+data MVector :: * -> * -> * where
+  MV :: !Int -> !(Rec (MVectorVal s) rs) -> MVector s (Rec Identity rs)
+  deriving Typeable
+
+instance GM.MVector MVector (Rec Identity '[]) where
+  basicLength (MV i _) = i
+  {-# INLINE basicLength #-}
+  basicUnsafeSlice _ _ v = v
+  {-# INLINE basicUnsafeSlice #-}
+  basicOverlaps _ _ = False
+  {-# INLINE basicOverlaps #-}
+  basicUnsafeNew n = return (MV n RNil)
+  {-# INLINE basicUnsafeNew #-}
+  basicUnsafeReplicate n _ = return (MV n RNil)
+  {-# INLINE basicUnsafeReplicate #-}
+  basicUnsafeRead _ _ = return RNil
+  {-# INLINE basicUnsafeRead #-}
+  basicUnsafeWrite _ _ _ = return ()
+  {-# INLINE basicUnsafeWrite #-}
+  basicClear _ = return ()
+  {-# INLINE basicClear #-}
+  basicSet _ _ = return ()
+  {-# INLINE basicSet #-}
+  basicUnsafeCopy _ _ = return ()
+  {-# INLINE basicUnsafeCopy #-}
+  basicUnsafeMove _ _ = return ()
+  {-# INLINE basicUnsafeMove #-}
+  basicUnsafeGrow (MV i _) n = return (MV (i + n) RNil)
+  {-# INLINE basicUnsafeGrow #-}
+#if MIN_VERSION_vector(0,11,0)
+  basicInitialize _ = return ()
+  {-# INLINE basicInitialize #-}
+#endif
+  
+
+instance ( GM.MVector MVector (Rec Identity rs)
+         , HasDefaultVector r
+         )
+    => GM.MVector MVector (Rec Identity (r ': rs)) where
+  basicLength (MV i _) = i
+  {-# INLINE basicLength #-}
+
+  basicUnsafeSlice s e (MV i (MVectorVal v :& rs)) = case GM.basicUnsafeSlice s e (MV i rs) of
+    MV _ rsNext -> MV e (MVectorVal (GM.basicUnsafeSlice s e v) :& rsNext)
+  {-# INLINE basicUnsafeSlice #-}
+
+  basicOverlaps (MV i (MVectorVal a :& as)) (MV j (MVectorVal b :& bs)) = 
+    GM.basicOverlaps a b || GM.basicOverlaps (MV i as) (MV j bs)
+  {-# INLINE basicOverlaps #-}
+
+  basicUnsafeNew :: forall m. PrimMonad m => Int -> m (MVector (PrimState m) (Rec Identity (r ': rs)))
+  basicUnsafeNew n = 
+    consVec (Proxy :: Proxy m) n <$> GM.basicUnsafeNew n <*> GM.basicUnsafeNew n
+  {-# INLINE basicUnsafeNew #-}
+  
+  basicUnsafeReplicate :: forall m. PrimMonad m => Int -> Rec Identity (r ': rs) -> m (MVector (PrimState m) (Rec Identity (r ': rs)))
+  basicUnsafeReplicate n (Identity v :& rs) = 
+    consVec (Proxy :: Proxy m) n <$> GM.basicUnsafeReplicate n v <*> GM.basicUnsafeReplicate n rs
+  {-# INLINE basicUnsafeReplicate #-}
+
+  basicUnsafeRead (MV i (MVectorVal v :& rs)) n = do
+    r <- GM.basicUnsafeRead v n
+    rs <- GM.basicUnsafeRead (MV i rs) n
+    return (Identity r :& rs)
+  {-# INLINE basicUnsafeRead #-}
+
+  basicUnsafeWrite (MV i (MVectorVal v :& vrs)) n (Identity r :& rs) = do
+    GM.basicUnsafeWrite v n r
+    GM.basicUnsafeWrite (MV i vrs) n rs
+  {-# INLINE basicUnsafeWrite #-}
+
+  basicClear (MV i (MVectorVal v :& vrs)) = do
+    GM.basicClear v
+    GM.basicClear (MV i vrs)
+  {-# INLINE basicClear #-}
+
+  basicSet (MV i (MVectorVal v :& vrs)) (Identity r :& rs) = do
+    GM.basicSet v r
+    GM.basicSet (MV i vrs) rs
+  {-# INLINE basicSet #-}
+
+  basicUnsafeCopy (MV i (MVectorVal a :& as)) (MV j (MVectorVal b :& bs)) = do
+    GM.basicUnsafeCopy a b
+    GM.basicUnsafeCopy (MV i as) (MV j bs)
+  {-# INLINE basicUnsafeCopy #-}
+
+  basicUnsafeMove (MV i (MVectorVal a :& as)) (MV j (MVectorVal b :& bs)) = do
+    GM.basicUnsafeMove a b
+    GM.basicUnsafeMove (MV i as) (MV j bs)
+  {-# INLINE basicUnsafeMove #-}
+
+  basicUnsafeGrow :: forall m. PrimMonad m => MVector (PrimState m) (Rec Identity (r ': rs)) -> Int -> m (MVector (PrimState m) (Rec Identity (r ': rs)))
+  basicUnsafeGrow (MV i (MVectorVal v :& vrs)) n = do
+    r <- GM.basicUnsafeGrow v n
+    rs <- GM.basicUnsafeGrow (MV i vrs) n
+    return (MV (i + n) (MVectorVal r :& stripMV (Proxy :: Proxy m) rs))
+  {-# INLINE basicUnsafeGrow #-}
+
+#if MIN_VERSION_vector(0,11,0)
+  basicInitialize (MV i (MVectorVal v :& rs)) = do
+    GM.basicInitialize v
+    GM.basicInitialize (MV i rs)
+  {-# INLINE basicInitialize #-}
+#endif
+
+data Vector :: * -> * where
+  V :: !Int -> !(Rec VectorVal rs) -> Vector (Rec Identity rs)
+  deriving Typeable
+
+type instance G.Mutable Vector = MVector 
+
+instance G.Vector Vector (Rec Identity '[]) where
+  basicUnsafeFreeze (MV n _) = return (V n RNil)
+  {-# INLINE basicUnsafeFreeze #-}
+  basicUnsafeThaw (V i _) = return (MV i RNil)
+  {-# INLINE basicUnsafeThaw #-}
+  basicLength (V i _) = i
+  {-# INLINE basicLength #-}
+  basicUnsafeSlice _ e _ = V e RNil
+  {-# INLINE basicUnsafeSlice #-}
+  basicUnsafeIndexM _ n = return RNil
+  {-# INLINE basicUnsafeIndexM #-}
+  basicUnsafeCopy _ _ = return ()
+  {-# INLINE basicUnsafeCopy #-}
+  elemseq _ RNil b = b
+  {-# INLINE elemseq #-}
+
+instance ( G.Vector Vector (Rec Identity rs)
+         , HasDefaultVector r
+         )
+    => G.Vector Vector (Rec Identity (r ': rs)) where
+  basicUnsafeFreeze (MV i (MVectorVal v :& vrs)) = do
+    r <- G.basicUnsafeFreeze v
+    rs <- G.basicUnsafeFreeze (MV i vrs)
+    return (V i (VectorVal r :& stripV rs))
+  {-# INLINE basicUnsafeFreeze #-}
+
+  basicUnsafeThaw :: forall m. PrimMonad m => Vector (Rec Identity (r ': rs)) -> m (G.Mutable Vector (PrimState m) (Rec Identity (r ': rs)))
+  basicUnsafeThaw (V i (VectorVal v :& vrs)) = do
+    r <- G.basicUnsafeThaw v
+    rs <- G.basicUnsafeThaw (V i vrs)
+    return (MV i (MVectorVal r :& stripMV (Proxy :: Proxy m) rs))
+  {-# INLINE basicUnsafeThaw #-}
+
+  basicLength (V i _) = i
+  {-# INLINE basicLength #-}
+
+  basicUnsafeSlice s e (V i (VectorVal v :& rs)) = case G.basicUnsafeSlice s e (V i rs) of
+    V _ rsNext -> V e (VectorVal (G.basicUnsafeSlice s e v) :& rsNext)
+  {-# INLINE basicUnsafeSlice #-}
+
+  basicUnsafeIndexM (V i (VectorVal v :& vrs)) n = do
+    r <- G.basicUnsafeIndexM v n
+    rs <- G.basicUnsafeIndexM (V i vrs) n
+    return (Identity r :& rs)
+  {-# INLINE basicUnsafeIndexM #-}
+
+  basicUnsafeCopy (MV i (MVectorVal m :& mrs)) (V j (VectorVal v :& vrs)) = do
+    G.basicUnsafeCopy m v
+    G.basicUnsafeCopy (MV i mrs) (V j vrs)
+  {-# INLINE basicUnsafeCopy #-}
+
+  elemseq (V i (VectorVal v :& vrs)) (Identity a :& rs) b = G.elemseq v a (G.elemseq (V i vrs) rs b)
+  {-# INLINE elemseq #-}
+ 
+-----------------------------------------
+-- Helper functions for instance methods
+-----------------------------------------
+consVec :: Proxy m
+        -> Int 
+        -> G.Mutable (DefaultVector r) (PrimState m) r 
+        -> MVector (PrimState m) (Rec Identity rs)
+        -> MVector (PrimState m) (Rec Identity (r ': rs))
+consVec _ n v (MV _ rs) = MV n (MVectorVal v :& rs)
+{-# INLINE consVec #-}
+
+stripMV :: Proxy m -> MVector (PrimState m) (Rec Identity rs) -> Rec (MVectorVal (PrimState m)) rs
+stripMV _ (MV _ rs) = rs
+{-# INLINE stripMV #-}
+
+stripV :: Vector (Rec Identity rs) -> Rec VectorVal rs
+stripV (V _ rs) = rs
+{-# INLINE stripV #-}
diff --git a/src/Data/Vector/Vinyl/Default/Empty/Monomorphic/Mutable.hs b/src/Data/Vector/Vinyl/Default/Empty/Monomorphic/Mutable.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/Empty/Monomorphic/Mutable.hs
@@ -0,0 +1,283 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GADTs #-}
+
+-- |
+-- Module      : Data.Vector.Vinyl.Default.Mutable
+-- Copyright   : Andrew Martin
+-- License     : BSD-style
+--
+-- Maintainer  : Andrew Martin <andrew.thaddeus@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable
+--
+-- Vectors for vinyl records
+--
+
+module Data.Vector.Vinyl.Default.Empty.Monomorphic.Mutable (
+  -- * Mutable vectors of primitive types
+  MVector(..), 
+
+  -- * Accessors
+
+  -- ** Length information
+  length, null,
+
+  -- ** Extracting subvectors
+  slice, init, tail, take, drop, splitAt,
+  unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
+
+  -- ** Overlapping
+  overlaps,
+
+  -- * Construction
+
+  -- ** Initialisation
+  new, unsafeNew, replicate, replicateM, clone,
+
+  -- ** Growing
+  grow, unsafeGrow,
+
+  -- ** Restricting memory usage
+  clear,
+
+  -- * Zipping and unzipping - Omitting for now
+
+  -- * Accessing individual elements
+  read, write, swap,
+  unsafeRead, unsafeWrite, unsafeSwap,
+
+  -- * Modifying vectors
+
+  -- ** Filling and copying
+  set, copy, move, unsafeCopy, unsafeMove
+) where
+
+import Data.Vector.Vinyl.Default.Empty.Monomorphic.Internal
+import qualified Data.Vector.Generic.Mutable as G
+import Data.Vector.Fusion.Util ( delayed_min )
+import Control.Monad.Primitive
+import Data.Vinyl.Core (Rec)
+import Data.Vinyl.Functor (Identity)
+
+import Prelude hiding ( length, null, replicate, reverse, map, read,
+                        take, drop, splitAt, init, tail,
+                        zip, zip3, unzip, unzip3 )
+
+-- Length information
+-- ------------------
+
+-- | Length of the mutable vector.
+length :: MVector s (Rec Identity rs) -> Int
+{-# INLINE length #-}
+length (MV i _) = i
+
+-- | Check whether the vector is empty
+null :: MVector s (Rec Identity rs) -> Bool
+{-# INLINE null #-}
+null (MV i _) = i == 0
+
+-- Extracting subvectors
+-- ---------------------
+
+-- | Yield a part of the mutable vector without copying it.
+slice :: G.MVector MVector (Rec Identity rs) => Int -> Int -> MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
+{-# INLINE slice #-}
+slice = G.slice
+
+take :: G.MVector MVector (Rec Identity rs) => Int -> MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
+{-# INLINE take #-}
+take = G.take
+
+drop :: G.MVector MVector (Rec Identity rs) => Int -> MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
+{-# INLINE drop #-}
+drop = G.drop
+
+splitAt :: G.MVector MVector (Rec Identity rs) => Int -> MVector s (Rec Identity rs) -> (MVector s (Rec Identity rs), MVector s (Rec Identity rs))
+{-# INLINE splitAt #-}
+splitAt = G.splitAt
+
+init :: G.MVector MVector (Rec Identity rs) => MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
+{-# INLINE init #-}
+init = G.init
+
+tail :: G.MVector MVector (Rec Identity rs) => MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
+{-# INLINE tail #-}
+tail = G.tail
+
+-- | Yield a part of the mutable vector without copying it. No bounds checks
+-- are performed.
+unsafeSlice :: G.MVector MVector (Rec Identity rs)
+            => Int  -- ^ starting index
+            -> Int  -- ^ length of the slice
+            -> MVector s (Rec Identity rs)
+            -> MVector s (Rec Identity rs)
+{-# INLINE unsafeSlice #-}
+unsafeSlice = G.unsafeSlice
+
+unsafeTake :: G.MVector MVector (Rec Identity rs) => Int -> MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
+{-# INLINE unsafeTake #-}
+unsafeTake = G.unsafeTake
+
+unsafeDrop :: G.MVector MVector (Rec Identity rs) => Int -> MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
+{-# INLINE unsafeDrop #-}
+unsafeDrop = G.unsafeDrop
+
+unsafeInit :: G.MVector MVector (Rec Identity rs) => MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
+{-# INLINE unsafeInit #-}
+unsafeInit = G.unsafeInit
+
+unsafeTail :: G.MVector MVector (Rec Identity rs) => MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
+{-# INLINE unsafeTail #-}
+unsafeTail = G.unsafeTail
+
+-- Overlapping
+-- -----------
+
+-- | Check whether two vectors overlap.
+overlaps :: G.MVector MVector (Rec Identity rs) => MVector s (Rec Identity rs) -> MVector s (Rec Identity rs) -> Bool
+{-# INLINE overlaps #-}
+overlaps = G.overlaps
+
+-- Initialisation
+-- --------------
+
+-- | Create a mutable vector of the given length.
+new :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => Int -> m (MVector (PrimState m) (Rec Identity rs))
+{-# INLINE new #-}
+new = G.new
+
+-- | Create a mutable vector of the given length. The length is not checked.
+unsafeNew :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => Int -> m (MVector (PrimState m) (Rec Identity rs))
+{-# INLINE unsafeNew #-}
+unsafeNew = G.unsafeNew
+
+-- | Create a mutable vector of the given length (0 if the length is negative)
+-- and fill it with an initial value.
+replicate :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => Int -> (Rec Identity rs) -> m (MVector (PrimState m) (Rec Identity rs))
+{-# INLINE replicate #-}
+replicate = G.replicate
+
+-- | Create a mutable vector of the given length (0 if the length is negative)
+-- and fill it with values produced by repeatedly executing the monadic action.
+replicateM :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => Int -> m (Rec Identity rs) -> m (MVector (PrimState m) (Rec Identity rs))
+{-# INLINE replicateM #-}
+replicateM = G.replicateM
+
+-- | Create a copy of a mutable vector.
+clone :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
+      => MVector (PrimState m) (Rec Identity rs) -> m (MVector (PrimState m) (Rec Identity rs))
+{-# INLINE clone #-}
+clone = G.clone
+
+-- Growing
+-- -------
+
+-- | Grow a vector by the given number of elements. The number must be
+-- positive.
+grow :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
+              => MVector (PrimState m) (Rec Identity rs) -> Int -> m (MVector (PrimState m) (Rec Identity rs))
+{-# INLINE grow #-}
+grow = G.grow
+
+-- | Grow a vector by the given number of elements. The number must be
+-- positive but this is not checked.
+unsafeGrow :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
+               => MVector (PrimState m) (Rec Identity rs) -> Int -> m (MVector (PrimState m) (Rec Identity rs))
+{-# INLINE unsafeGrow #-}
+unsafeGrow = G.unsafeGrow
+
+-- Restricting memory usage
+-- ------------------------
+
+-- | Reset all elements of the vector to some undefined value, clearing all
+-- references to external objects. This is usually a noop for unboxed vectors.
+clear :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> m ()
+{-# INLINE clear #-}
+clear = G.clear
+
+-- Accessing individual elements
+-- -----------------------------
+
+-- | Yield the element at the given position.
+read :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> Int -> m (Rec Identity rs)
+{-# INLINE read #-}
+read = G.read
+
+-- | Replace the element at the given position.
+write :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> Int -> (Rec Identity rs) -> m ()
+{-# INLINE write #-}
+write = G.write
+
+-- | Swap the elements at the given positions.
+swap :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> Int -> Int -> m ()
+{-# INLINE swap #-}
+swap = G.swap
+
+
+-- | Yield the element at the given position. No bounds checks are performed.
+unsafeRead :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> Int -> m (Rec Identity rs)
+{-# INLINE unsafeRead #-}
+unsafeRead = G.unsafeRead
+
+-- | Replace the element at the given position. No bounds checks are performed.
+unsafeWrite
+    :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) =>  MVector (PrimState m) (Rec Identity rs) -> Int -> (Rec Identity rs) -> m ()
+{-# INLINE unsafeWrite #-}
+unsafeWrite = G.unsafeWrite
+
+-- | Swap the elements at the given positions. No bounds checks are performed.
+unsafeSwap
+    :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> Int -> Int -> m ()
+{-# INLINE unsafeSwap #-}
+unsafeSwap = G.unsafeSwap
+
+-- Filling and copying
+-- -------------------
+
+-- | Set all elements of the vector to the given value.
+set :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> (Rec Identity rs) -> m ()
+{-# INLINE set #-}
+set = G.set
+
+-- | Copy a vector. The two vectors must have the same length and may not
+-- overlap.
+copy :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
+                 => MVector (PrimState m) (Rec Identity rs) -> MVector (PrimState m) (Rec Identity rs) -> m ()
+{-# INLINE copy #-}
+copy = G.copy
+
+-- | Copy a vector. The two vectors must have the same length and may not
+-- overlap. This is not checked.
+unsafeCopy :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
+           => MVector (PrimState m) (Rec Identity rs)   -- ^ target
+           -> MVector (PrimState m) (Rec Identity rs)   -- ^ source
+           -> m ()
+{-# INLINE unsafeCopy #-}
+unsafeCopy = G.unsafeCopy
+
+-- | Move the contents of a vector. The two vectors must have the same
+-- length.
+--
+-- If the vectors do not overlap, then 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, G.MVector MVector (Rec Identity rs))
+     => MVector (PrimState m) (Rec Identity rs) -> MVector (PrimState m) (Rec Identity rs) -> m ()
+{-# INLINE move #-}
+move = G.move
+
+-- | Move the contents of a vector. The two vectors must have the same
+-- length, but this is not checked.
+--
+-- If the vectors do not overlap, then this is equivalent to 'unsafeCopy'.
+-- 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.
+unsafeMove :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
+           => MVector (PrimState m) (Rec Identity rs)   -- ^ target
+           -> MVector (PrimState m) (Rec Identity rs)   -- ^ source
+           -> m ()
+{-# INLINE unsafeMove #-}
+unsafeMove = G.unsafeMove
+
diff --git a/src/Data/Vector/Vinyl/Default/Implication.hs b/src/Data/Vector/Vinyl/Default/Implication.hs
deleted file mode 100644
--- a/src/Data/Vector/Vinyl/Default/Implication.hs
+++ /dev/null
@@ -1,46 +0,0 @@
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE GADTs #-}
-
------------------------------------------------------------------------------
--- |
--- Copyright   :  Andrew Martin
--- License     :  BSD-style (see the file LICENSE)
---
--- Maintainer  :  Andrew Martin <andrew.thaddeus@gmail.com>
--- Stability   :  experimental
--- Portability :  non-portable
---
--- This module uses the "constraints" package to prove that if all of the
--- columns satisfy the 'HasDefaultVector' constraint, then a vector 
--- parameterized over the record has an instance of the generic vector 
--- typeclass.
------------------------------------------------------------------------------
-module Data.Vector.Vinyl.Default.Implication where
-
-import Data.Constraint
-import Data.Vector.Vinyl.Default.Internal
-import Data.Vinyl.Core (Rec(..))
-import Data.Vinyl.Functor (Identity(..))
-import Data.Vector.Vinyl.TypeLevel (ListAll)
-
-import qualified Data.Vector.Generic.Mutable as GM
-import qualified Data.Vector.Generic as G
-
-listAllVector :: Rec proxy rs 
-              -> ListAll rs HasDefaultVector :- G.Vector Vector (Rec Identity rs)
-listAllVector RNil = Sub Dict
-listAllVector (_ :& rs) = Sub $ case listAllVector rs of
-  Sub Dict -> Dict
-
-listAllMVector :: Rec proxy rs 
-              -> ListAll rs HasDefaultVector :- GM.MVector MVector (Rec Identity rs)
-listAllMVector RNil = Sub Dict
-listAllMVector (_ :& rs) = Sub $ case listAllMVector rs of
-  Sub Dict -> Dict
-
--- listAllVectorBoth :: Rec proxy rs 
---   -> ListAll rs HasDefaultVector :- (GM.MVector MVector (Rec Identity rs), G.Vector Vector (Rec Identity rs))
--- listAllVectorBoth RNil = Sub Dict
--- listAllVectorBoth (_ :& rs) = Sub $ case listAllVectorBoth rs of
---   Sub Dict -> Dict
-
diff --git a/src/Data/Vector/Vinyl/Default/Internal.hs b/src/Data/Vector/Vinyl/Default/Internal.hs
deleted file mode 100644
--- a/src/Data/Vector/Vinyl/Default/Internal.hs
+++ /dev/null
@@ -1,263 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE KindSignatures #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE InstanceSigs #-}
-
-#ifndef MIN_VERSION_vector
-#define MIN_VERSION_vector(x,y,z) 1
-#endif
-
-module Data.Vector.Vinyl.Default.Internal
-  ( MVector(..)
-  , MVectorVal(..)
-  , Vector(..)
-  , HasDefaultVector(..)
-  ) where
-
-import Control.Monad
-import Data.Monoid
-import Data.Typeable (Typeable)
-import GHC.Exts (Constraint)
-import Control.Monad.Primitive (PrimMonad,PrimState)
-import qualified Data.Vector.Generic.Mutable as GM
-import qualified Data.Vector.Generic as G
-import qualified Data.Vector as B
-import qualified Data.Vector.Unboxed as U
-
-#if MIN_VERSION_vector(0,11,0)
-import Data.Vector.Fusion.Bundle as Stream
-#else
-import Data.Vector.Fusion.Stream as Stream
-#endif
-
-import Prelude hiding ( length, null, replicate, reverse, map, read, take, drop, init, tail )
-import Text.Read
-import Data.Proxy
-
-import Data.Vinyl.Core(Rec(..))
-import Data.Vinyl.Functor (Identity(..))
-import qualified Data.Text as Text
-import qualified Data.Text.Lazy as LText
-
--- | The most efficient vector type for each column data type.
-class ( GM.MVector (G.Mutable (DefaultVector t)) t
-      , G.Vector (DefaultVector t) t
-      ) => HasDefaultVector t where
-  type DefaultVector t :: * -> *
-
-instance HasDefaultVector Int where
-  type DefaultVector Int = U.Vector
-instance HasDefaultVector Char where
-  type DefaultVector Char = U.Vector
-instance HasDefaultVector Bool where
-  type DefaultVector Bool = U.Vector
-instance HasDefaultVector Float where
-  type DefaultVector Float = U.Vector
-instance HasDefaultVector Double where
-  type DefaultVector Double = U.Vector
-instance HasDefaultVector Text.Text where
-  type DefaultVector Text.Text = B.Vector
-instance HasDefaultVector LText.Text where
-  type DefaultVector LText.Text = B.Vector
-instance G.Vector Vector (Rec Identity rs)
-    => HasDefaultVector (Rec Identity rs) where
-  type DefaultVector (Rec Identity rs) = Vector
-
-newtype MVectorVal s t = MVectorVal { getMVectorVal :: G.Mutable (DefaultVector t) s t }
-
-data MVector :: * -> * -> * where
-  MV :: !Int -> !(Rec (MVectorVal s) rs) -> MVector s (Rec Identity rs)
-  deriving Typeable
-
-instance GM.MVector MVector (Rec Identity '[]) where
-  basicLength (MV i _) = i
-  {-# INLINE basicLength #-}
-  basicUnsafeSlice _ _ v = v
-  {-# INLINE basicUnsafeSlice #-}
-  basicOverlaps _ _ = False
-  {-# INLINE basicOverlaps #-}
-  basicUnsafeNew n = return (MV n RNil)
-  {-# INLINE basicUnsafeNew #-}
-  basicUnsafeReplicate n _ = return (MV n RNil)
-  {-# INLINE basicUnsafeReplicate #-}
-  basicUnsafeRead _ _ = return RNil
-  {-# INLINE basicUnsafeRead #-}
-  basicUnsafeWrite _ _ _ = return ()
-  {-# INLINE basicUnsafeWrite #-}
-  basicClear _ = return ()
-  {-# INLINE basicClear #-}
-  basicSet _ _ = return ()
-  {-# INLINE basicSet #-}
-  basicUnsafeCopy _ _ = return ()
-  {-# INLINE basicUnsafeCopy #-}
-  basicUnsafeMove _ _ = return ()
-  {-# INLINE basicUnsafeMove #-}
-  basicUnsafeGrow (MV i _) n = return (MV (i + n) RNil)
-  {-# INLINE basicUnsafeGrow #-}
-#if MIN_VERSION_vector(0,11,0)
-  basicInitialize _ = return ()
-  {-# INLINE basicInitialize #-}
-#endif
-  
-
-instance ( GM.MVector MVector (Rec Identity rs)
-         , HasDefaultVector r
-         )
-    => GM.MVector MVector (Rec Identity (r ': rs)) where
-  basicLength (MV i _) = i
-  {-# INLINE basicLength #-}
-
-  basicUnsafeSlice s e (MV i (MVectorVal v :& rs)) = case GM.basicUnsafeSlice s e (MV i rs) of
-    MV _ rsNext -> MV e (MVectorVal (GM.basicUnsafeSlice s e v) :& rsNext)
-  {-# INLINE basicUnsafeSlice #-}
-
-  basicOverlaps (MV i (MVectorVal a :& as)) (MV j (MVectorVal b :& bs)) = 
-    GM.basicOverlaps a b || GM.basicOverlaps (MV i as) (MV j bs)
-  {-# INLINE basicOverlaps #-}
-
-  basicUnsafeNew :: forall m. PrimMonad m => Int -> m (MVector (PrimState m) (Rec Identity (r ': rs)))
-  basicUnsafeNew n = 
-    consVec (Proxy :: Proxy m) n <$> GM.basicUnsafeNew n <*> GM.basicUnsafeNew n
-  {-# INLINE basicUnsafeNew #-}
-  
-  basicUnsafeReplicate :: forall m. PrimMonad m => Int -> Rec Identity (r ': rs) -> m (MVector (PrimState m) (Rec Identity (r ': rs)))
-  basicUnsafeReplicate n (Identity v :& rs) = 
-    consVec (Proxy :: Proxy m) n <$> GM.basicUnsafeReplicate n v <*> GM.basicUnsafeReplicate n rs
-  {-# INLINE basicUnsafeReplicate #-}
-
-  basicUnsafeRead (MV i (MVectorVal v :& rs)) n = do
-    r <- GM.basicUnsafeRead v n
-    rs <- GM.basicUnsafeRead (MV i rs) n
-    return (Identity r :& rs)
-  {-# INLINE basicUnsafeRead #-}
-
-  basicUnsafeWrite (MV i (MVectorVal v :& vrs)) n (Identity r :& rs) = do
-    GM.basicUnsafeWrite v n r
-    GM.basicUnsafeWrite (MV i vrs) n rs
-  {-# INLINE basicUnsafeWrite #-}
-
-  basicClear (MV i (MVectorVal v :& vrs)) = do
-    GM.basicClear v
-    GM.basicClear (MV i vrs)
-  {-# INLINE basicClear #-}
-
-  basicSet (MV i (MVectorVal v :& vrs)) (Identity r :& rs) = do
-    GM.basicSet v r
-    GM.basicSet (MV i vrs) rs
-  {-# INLINE basicSet #-}
-
-  basicUnsafeCopy (MV i (MVectorVal a :& as)) (MV j (MVectorVal b :& bs)) = do
-    GM.basicUnsafeCopy a b
-    GM.basicUnsafeCopy (MV i as) (MV j bs)
-  {-# INLINE basicUnsafeCopy #-}
-
-  basicUnsafeMove (MV i (MVectorVal a :& as)) (MV j (MVectorVal b :& bs)) = do
-    GM.basicUnsafeMove a b
-    GM.basicUnsafeMove (MV i as) (MV j bs)
-  {-# INLINE basicUnsafeMove #-}
-
-  basicUnsafeGrow :: forall m. PrimMonad m => MVector (PrimState m) (Rec Identity (r ': rs)) -> Int -> m (MVector (PrimState m) (Rec Identity (r ': rs)))
-  basicUnsafeGrow (MV i (MVectorVal v :& vrs)) n = do
-    r <- GM.basicUnsafeGrow v n
-    rs <- GM.basicUnsafeGrow (MV i vrs) n
-    return (MV (i + n) (MVectorVal r :& stripMV (Proxy :: Proxy m) rs))
-  {-# INLINE basicUnsafeGrow #-}
-
-#if MIN_VERSION_vector(0,11,0)
-  basicInitialize (MV i (MVectorVal v :& rs)) = do
-    GM.basicInitialize v
-    GM.basicInitialize (MV i rs)
-  {-# INLINE basicInitialize #-}
-#endif
-
-newtype VectorVal t = VectorVal { getVectorVal :: DefaultVector t t }
-
-data Vector :: * -> * where
-  V :: !Int -> !(Rec VectorVal rs) -> Vector (Rec Identity rs)
-  deriving Typeable
-
-type instance G.Mutable Vector = MVector 
-
-instance G.Vector Vector (Rec Identity '[]) where
-  basicUnsafeFreeze (MV n _) = return (V n RNil)
-  {-# INLINE basicUnsafeFreeze #-}
-  basicUnsafeThaw (V i _) = return (MV i RNil)
-  {-# INLINE basicUnsafeThaw #-}
-  basicLength (V i _) = i
-  {-# INLINE basicLength #-}
-  basicUnsafeSlice _ e _ = V e RNil
-  {-# INLINE basicUnsafeSlice #-}
-  basicUnsafeIndexM _ n = return RNil
-  {-# INLINE basicUnsafeIndexM #-}
-  basicUnsafeCopy _ _ = return ()
-  {-# INLINE basicUnsafeCopy #-}
-  elemseq _ RNil b = b
-  {-# INLINE elemseq #-}
-
-instance ( G.Vector Vector (Rec Identity rs)
-         , HasDefaultVector r
-         )
-    => G.Vector Vector (Rec Identity (r ': rs)) where
-  basicUnsafeFreeze (MV i (MVectorVal v :& vrs)) = do
-    r <- G.basicUnsafeFreeze v
-    rs <- G.basicUnsafeFreeze (MV i vrs)
-    return (V i (VectorVal r :& stripV rs))
-  {-# INLINE basicUnsafeFreeze #-}
-
-  basicUnsafeThaw :: forall m. PrimMonad m => Vector (Rec Identity (r ': rs)) -> m (G.Mutable Vector (PrimState m) (Rec Identity (r ': rs)))
-  basicUnsafeThaw (V i (VectorVal v :& vrs)) = do
-    r <- G.basicUnsafeThaw v
-    rs <- G.basicUnsafeThaw (V i vrs)
-    return (MV i (MVectorVal r :& stripMV (Proxy :: Proxy m) rs))
-  {-# INLINE basicUnsafeThaw #-}
-
-  basicLength (V i _) = i
-  {-# INLINE basicLength #-}
-
-  basicUnsafeSlice s e (V i (VectorVal v :& rs)) = case G.basicUnsafeSlice s e (V i rs) of
-    V _ rsNext -> V e (VectorVal (G.basicUnsafeSlice s e v) :& rsNext)
-  {-# INLINE basicUnsafeSlice #-}
-
-  basicUnsafeIndexM (V i (VectorVal v :& vrs)) n = do
-    r <- G.basicUnsafeIndexM v n
-    rs <- G.basicUnsafeIndexM (V i vrs) n
-    return (Identity r :& rs)
-  {-# INLINE basicUnsafeIndexM #-}
-
-  basicUnsafeCopy (MV i (MVectorVal m :& mrs)) (V j (VectorVal v :& vrs)) = do
-    G.basicUnsafeCopy m v
-    G.basicUnsafeCopy (MV i mrs) (V j vrs)
-  {-# INLINE basicUnsafeCopy #-}
-
-  elemseq (V i (VectorVal v :& vrs)) (Identity a :& rs) b = G.elemseq v a (G.elemseq (V i vrs) rs b)
-  {-# INLINE elemseq #-}
- 
------------------------------------------
--- Helper functions for instance methods
------------------------------------------
-consVec :: Proxy m
-        -> Int 
-        -> G.Mutable (DefaultVector r) (PrimState m) r 
-        -> MVector (PrimState m) (Rec Identity rs)
-        -> MVector (PrimState m) (Rec Identity (r ': rs))
-consVec _ n v (MV _ rs) = MV n (MVectorVal v :& rs)
-{-# INLINE consVec #-}
-
-stripMV :: Proxy m -> MVector (PrimState m) (Rec Identity rs) -> Rec (MVectorVal (PrimState m)) rs
-stripMV _ (MV _ rs) = rs
-{-# INLINE stripMV #-}
-
-stripV :: Vector (Rec Identity rs) -> Rec VectorVal rs
-stripV (V _ rs) = rs
-{-# INLINE stripV #-}
diff --git a/src/Data/Vector/Vinyl/Default/Mutable.hs b/src/Data/Vector/Vinyl/Default/Mutable.hs
deleted file mode 100644
--- a/src/Data/Vector/Vinyl/Default/Mutable.hs
+++ /dev/null
@@ -1,283 +0,0 @@
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE GADTs #-}
-
--- |
--- Module      : Data.Vector.Vinyl.Default.Mutable
--- Copyright   : Andrew Martin
--- License     : BSD-style
---
--- Maintainer  : Andrew Martin <andrew.thaddeus@gmail.com>
--- Stability   : experimental
--- Portability : non-portable
---
--- Vectors for vinyl records
---
-
-module Data.Vector.Vinyl.Default.Mutable (
-  -- * Mutable vectors of primitive types
-  MVector(..), 
-
-  -- * Accessors
-
-  -- ** Length information
-  length, null,
-
-  -- ** Extracting subvectors
-  slice, init, tail, take, drop, splitAt,
-  unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
-
-  -- ** Overlapping
-  overlaps,
-
-  -- * Construction
-
-  -- ** Initialisation
-  new, unsafeNew, replicate, replicateM, clone,
-
-  -- ** Growing
-  grow, unsafeGrow,
-
-  -- ** Restricting memory usage
-  clear,
-
-  -- * Zipping and unzipping - Omitting for now
-
-  -- * Accessing individual elements
-  read, write, swap,
-  unsafeRead, unsafeWrite, unsafeSwap,
-
-  -- * Modifying vectors
-
-  -- ** Filling and copying
-  set, copy, move, unsafeCopy, unsafeMove
-) where
-
-import Data.Vector.Vinyl.Default.Internal
-import qualified Data.Vector.Generic.Mutable as G
-import Data.Vector.Fusion.Util ( delayed_min )
-import Control.Monad.Primitive
-import Data.Vinyl.Core (Rec)
-import Data.Vinyl.Functor (Identity)
-
-import Prelude hiding ( length, null, replicate, reverse, map, read,
-                        take, drop, splitAt, init, tail,
-                        zip, zip3, unzip, unzip3 )
-
--- Length information
--- ------------------
-
--- | Length of the mutable vector.
-length :: MVector s (Rec Identity rs) -> Int
-{-# INLINE length #-}
-length (MV i _) = i
-
--- | Check whether the vector is empty
-null :: MVector s (Rec Identity rs) -> Bool
-{-# INLINE null #-}
-null (MV i _) = i == 0
-
--- Extracting subvectors
--- ---------------------
-
--- | Yield a part of the mutable vector without copying it.
-slice :: G.MVector MVector (Rec Identity rs) => Int -> Int -> MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
-{-# INLINE slice #-}
-slice = G.slice
-
-take :: G.MVector MVector (Rec Identity rs) => Int -> MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
-{-# INLINE take #-}
-take = G.take
-
-drop :: G.MVector MVector (Rec Identity rs) => Int -> MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
-{-# INLINE drop #-}
-drop = G.drop
-
-splitAt :: G.MVector MVector (Rec Identity rs) => Int -> MVector s (Rec Identity rs) -> (MVector s (Rec Identity rs), MVector s (Rec Identity rs))
-{-# INLINE splitAt #-}
-splitAt = G.splitAt
-
-init :: G.MVector MVector (Rec Identity rs) => MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
-{-# INLINE init #-}
-init = G.init
-
-tail :: G.MVector MVector (Rec Identity rs) => MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
-{-# INLINE tail #-}
-tail = G.tail
-
--- | Yield a part of the mutable vector without copying it. No bounds checks
--- are performed.
-unsafeSlice :: G.MVector MVector (Rec Identity rs)
-            => Int  -- ^ starting index
-            -> Int  -- ^ length of the slice
-            -> MVector s (Rec Identity rs)
-            -> MVector s (Rec Identity rs)
-{-# INLINE unsafeSlice #-}
-unsafeSlice = G.unsafeSlice
-
-unsafeTake :: G.MVector MVector (Rec Identity rs) => Int -> MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
-{-# INLINE unsafeTake #-}
-unsafeTake = G.unsafeTake
-
-unsafeDrop :: G.MVector MVector (Rec Identity rs) => Int -> MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
-{-# INLINE unsafeDrop #-}
-unsafeDrop = G.unsafeDrop
-
-unsafeInit :: G.MVector MVector (Rec Identity rs) => MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
-{-# INLINE unsafeInit #-}
-unsafeInit = G.unsafeInit
-
-unsafeTail :: G.MVector MVector (Rec Identity rs) => MVector s (Rec Identity rs) -> MVector s (Rec Identity rs)
-{-# INLINE unsafeTail #-}
-unsafeTail = G.unsafeTail
-
--- Overlapping
--- -----------
-
--- | Check whether two vectors overlap.
-overlaps :: G.MVector MVector (Rec Identity rs) => MVector s (Rec Identity rs) -> MVector s (Rec Identity rs) -> Bool
-{-# INLINE overlaps #-}
-overlaps = G.overlaps
-
--- Initialisation
--- --------------
-
--- | Create a mutable vector of the given length.
-new :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => Int -> m (MVector (PrimState m) (Rec Identity rs))
-{-# INLINE new #-}
-new = G.new
-
--- | Create a mutable vector of the given length. The length is not checked.
-unsafeNew :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => Int -> m (MVector (PrimState m) (Rec Identity rs))
-{-# INLINE unsafeNew #-}
-unsafeNew = G.unsafeNew
-
--- | Create a mutable vector of the given length (0 if the length is negative)
--- and fill it with an initial value.
-replicate :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => Int -> (Rec Identity rs) -> m (MVector (PrimState m) (Rec Identity rs))
-{-# INLINE replicate #-}
-replicate = G.replicate
-
--- | Create a mutable vector of the given length (0 if the length is negative)
--- and fill it with values produced by repeatedly executing the monadic action.
-replicateM :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => Int -> m (Rec Identity rs) -> m (MVector (PrimState m) (Rec Identity rs))
-{-# INLINE replicateM #-}
-replicateM = G.replicateM
-
--- | Create a copy of a mutable vector.
-clone :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
-      => MVector (PrimState m) (Rec Identity rs) -> m (MVector (PrimState m) (Rec Identity rs))
-{-# INLINE clone #-}
-clone = G.clone
-
--- Growing
--- -------
-
--- | Grow a vector by the given number of elements. The number must be
--- positive.
-grow :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
-              => MVector (PrimState m) (Rec Identity rs) -> Int -> m (MVector (PrimState m) (Rec Identity rs))
-{-# INLINE grow #-}
-grow = G.grow
-
--- | Grow a vector by the given number of elements. The number must be
--- positive but this is not checked.
-unsafeGrow :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
-               => MVector (PrimState m) (Rec Identity rs) -> Int -> m (MVector (PrimState m) (Rec Identity rs))
-{-# INLINE unsafeGrow #-}
-unsafeGrow = G.unsafeGrow
-
--- Restricting memory usage
--- ------------------------
-
--- | Reset all elements of the vector to some undefined value, clearing all
--- references to external objects. This is usually a noop for unboxed vectors.
-clear :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> m ()
-{-# INLINE clear #-}
-clear = G.clear
-
--- Accessing individual elements
--- -----------------------------
-
--- | Yield the element at the given position.
-read :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> Int -> m (Rec Identity rs)
-{-# INLINE read #-}
-read = G.read
-
--- | Replace the element at the given position.
-write :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> Int -> (Rec Identity rs) -> m ()
-{-# INLINE write #-}
-write = G.write
-
--- | Swap the elements at the given positions.
-swap :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> Int -> Int -> m ()
-{-# INLINE swap #-}
-swap = G.swap
-
-
--- | Yield the element at the given position. No bounds checks are performed.
-unsafeRead :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> Int -> m (Rec Identity rs)
-{-# INLINE unsafeRead #-}
-unsafeRead = G.unsafeRead
-
--- | Replace the element at the given position. No bounds checks are performed.
-unsafeWrite
-    :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) =>  MVector (PrimState m) (Rec Identity rs) -> Int -> (Rec Identity rs) -> m ()
-{-# INLINE unsafeWrite #-}
-unsafeWrite = G.unsafeWrite
-
--- | Swap the elements at the given positions. No bounds checks are performed.
-unsafeSwap
-    :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> Int -> Int -> m ()
-{-# INLINE unsafeSwap #-}
-unsafeSwap = G.unsafeSwap
-
--- Filling and copying
--- -------------------
-
--- | Set all elements of the vector to the given value.
-set :: (PrimMonad m, G.MVector MVector (Rec Identity rs)) => MVector (PrimState m) (Rec Identity rs) -> (Rec Identity rs) -> m ()
-{-# INLINE set #-}
-set = G.set
-
--- | Copy a vector. The two vectors must have the same length and may not
--- overlap.
-copy :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
-                 => MVector (PrimState m) (Rec Identity rs) -> MVector (PrimState m) (Rec Identity rs) -> m ()
-{-# INLINE copy #-}
-copy = G.copy
-
--- | Copy a vector. The two vectors must have the same length and may not
--- overlap. This is not checked.
-unsafeCopy :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
-           => MVector (PrimState m) (Rec Identity rs)   -- ^ target
-           -> MVector (PrimState m) (Rec Identity rs)   -- ^ source
-           -> m ()
-{-# INLINE unsafeCopy #-}
-unsafeCopy = G.unsafeCopy
-
--- | Move the contents of a vector. The two vectors must have the same
--- length.
---
--- If the vectors do not overlap, then 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, G.MVector MVector (Rec Identity rs))
-     => MVector (PrimState m) (Rec Identity rs) -> MVector (PrimState m) (Rec Identity rs) -> m ()
-{-# INLINE move #-}
-move = G.move
-
--- | Move the contents of a vector. The two vectors must have the same
--- length, but this is not checked.
---
--- If the vectors do not overlap, then this is equivalent to 'unsafeCopy'.
--- 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.
-unsafeMove :: (PrimMonad m, G.MVector MVector (Rec Identity rs))
-           => MVector (PrimState m) (Rec Identity rs)   -- ^ target
-           -> MVector (PrimState m) (Rec Identity rs)   -- ^ source
-           -> m ()
-{-# INLINE unsafeMove #-}
-unsafeMove = G.unsafeMove
-
diff --git a/src/Data/Vector/Vinyl/Default/NonEmpty/Monomorphic/Implication.hs b/src/Data/Vector/Vinyl/Default/NonEmpty/Monomorphic/Implication.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/NonEmpty/Monomorphic/Implication.hs
@@ -0,0 +1,49 @@
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE DataKinds #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Copyright   :  Andrew Martin
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  Andrew Martin <andrew.thaddeus@gmail.com>
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- This module uses the "constraints" package to prove that if all of the
+-- columns satisfy the 'HasDefaultVector' constraint, then a vector 
+-- parameterized over the record has an instance of the generic vector 
+-- typeclass.
+-----------------------------------------------------------------------------
+module Data.Vector.Vinyl.Default.NonEmpty.Monomorphic.Implication where
+
+import Data.Constraint
+import Data.Vector.Vinyl.Default.NonEmpty.Monomorphic.Internal
+import Data.Vinyl.Core (Rec(..))
+import Data.Vinyl.Functor (Identity(..))
+import Data.Vector.Vinyl.TypeLevel (ListAll)
+
+import qualified Data.Vector.Generic.Mutable as GM
+import qualified Data.Vector.Generic as G
+
+listAllVector :: (rs ~ (a ': as))
+              => Rec proxy rs 
+              -> ListAll rs HasDefaultVector :- G.Vector Vector (Rec Identity rs)
+listAllVector (_ :& RNil) = Sub Dict
+listAllVector (_ :& rs@(_ :& _)) = Sub $ case listAllVector rs of
+  Sub Dict -> Dict
+
+listAllMVector :: (rs ~ (a ': as))
+              => Rec proxy rs 
+              -> ListAll rs HasDefaultVector :- GM.MVector MVector (Rec Identity rs)
+listAllMVector (_ :& RNil) = Sub Dict
+listAllMVector (_ :& rs@(_ :& _)) = Sub $ case listAllMVector rs of
+  Sub Dict -> Dict
+
+-- listAllVectorBoth :: Rec proxy rs 
+--   -> ListAll rs HasDefaultVector :- (GM.MVector MVector (Rec Identity rs), G.Vector Vector (Rec Identity rs))
+-- listAllVectorBoth RNil = Sub Dict
+-- listAllVectorBoth (_ :& rs) = Sub $ case listAllVectorBoth rs of
+--   Sub Dict -> Dict
+
diff --git a/src/Data/Vector/Vinyl/Default/NonEmpty/Monomorphic/Internal.hs b/src/Data/Vector/Vinyl/Default/NonEmpty/Monomorphic/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/NonEmpty/Monomorphic/Internal.hs
@@ -0,0 +1,249 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE InstanceSigs #-}
+
+#ifndef MIN_VERSION_vector
+#define MIN_VERSION_vector(x,y,z) 1
+#endif
+
+module Data.Vector.Vinyl.Default.NonEmpty.Monomorphic.Internal
+  ( MVector(..)
+  , Vector(..)
+  , HasDefaultVector(..)
+  ) where
+
+import Control.Monad
+import Data.Monoid
+import Data.Typeable (Typeable)
+import GHC.Exts (Constraint)
+import Control.Monad.Primitive (PrimMonad,PrimState)
+import qualified Data.Vector.Generic.Mutable as GM
+import qualified Data.Vector.Generic as G
+
+#if MIN_VERSION_vector(0,11,0)
+import Data.Vector.Fusion.Bundle as Stream
+#else
+import Data.Vector.Fusion.Stream as Stream
+#endif
+
+import Prelude hiding ( length, null, replicate, reverse, map, read, take, drop, init, tail )
+import Text.Read
+import Data.Proxy
+
+import Data.Vinyl.Core(Rec(..))
+import Data.Vinyl.Functor (Identity(..))
+import Data.Vector.Vinyl.Default.Types (VectorVal(..),MVectorVal(..),HasDefaultVector(..))
+
+data MVector :: * -> * -> * where
+  MV :: !(Rec (MVectorVal s) rs) -> MVector s (Rec Identity rs)
+  deriving Typeable
+
+instance ( HasDefaultVector r
+         )
+    => GM.MVector MVector (Rec Identity (r ': '[])) where
+  basicLength (MV (MVectorVal v :& RNil)) = GM.basicLength v
+  {-# INLINE basicLength #-}
+  basicUnsafeSlice s e (MV (MVectorVal v :& RNil)) = MV (MVectorVal (GM.basicUnsafeSlice s e v) :& RNil)
+  {-# INLINE basicUnsafeSlice #-}
+  basicOverlaps (MV (MVectorVal a :& RNil)) (MV (MVectorVal b :& RNil)) = GM.basicOverlaps a b 
+  {-# INLINE basicOverlaps #-}
+  basicUnsafeNew n = do
+    r <- GM.basicUnsafeNew n 
+    return (MV (MVectorVal r :& RNil))
+  {-# INLINE basicUnsafeNew #-}
+  basicUnsafeReplicate n (Identity v :& RNil) = do
+    r <- GM.basicUnsafeReplicate n v 
+    return (MV (MVectorVal r :& RNil))
+  {-# INLINE basicUnsafeReplicate #-}
+  basicUnsafeRead (MV (MVectorVal v :& RNil)) n = do
+    r <- GM.basicUnsafeRead v n
+    return (Identity r :& RNil)
+  {-# INLINE basicUnsafeRead #-}
+  basicUnsafeWrite (MV (MVectorVal v :& RNil)) n (Identity r :& RNil) = GM.basicUnsafeWrite v n r
+  {-# INLINE basicUnsafeWrite #-}
+  basicClear (MV (MVectorVal v :& RNil)) = GM.basicClear v
+  {-# INLINE basicClear #-}
+  basicSet (MV (MVectorVal v :& RNil)) (Identity r :& RNil) = GM.basicSet v r
+  {-# INLINE basicSet #-}
+  basicUnsafeCopy (MV (MVectorVal a :& RNil)) (MV (MVectorVal b :& RNil)) = GM.basicUnsafeCopy a b
+  {-# INLINE basicUnsafeCopy #-}
+  basicUnsafeMove (MV (MVectorVal a :& RNil)) (MV (MVectorVal b :& RNil)) = GM.basicUnsafeMove a b
+  {-# INLINE basicUnsafeMove #-}
+  basicUnsafeGrow (MV (MVectorVal v :& RNil)) n = do
+    r <- GM.basicUnsafeGrow v n
+    return (MV (MVectorVal r :& RNil))
+  {-# INLINE basicUnsafeGrow #-}
+#if MIN_VERSION_vector(0,11,0)
+  basicInitialize (MV (MVectorVal v :& RNil)) = do
+    GM.basicInitialize v
+  {-# INLINE basicInitialize #-}
+#endif
+
+instance ( GM.MVector MVector (Rec Identity (s ': rs))
+         , HasDefaultVector r
+         )
+    => GM.MVector MVector (Rec Identity (r ': s ': rs)) where
+  basicLength (MV (MVectorVal v :& _)) = GM.basicLength v
+  {-# INLINE basicLength #-}
+
+  basicUnsafeSlice s e (MV (MVectorVal v :& rs)) = case GM.basicUnsafeSlice s e (MV rs) of
+    MV rsNext -> MV (MVectorVal (GM.basicUnsafeSlice s e v) :& rsNext)
+  {-# INLINE basicUnsafeSlice #-}
+
+  basicOverlaps (MV (MVectorVal a :& as)) (MV (MVectorVal b :& bs)) = 
+    GM.basicOverlaps a b || GM.basicOverlaps (MV as) (MV bs)
+  {-# INLINE basicOverlaps #-}
+
+  basicUnsafeNew :: forall m. PrimMonad m => Int -> m (MVector (PrimState m) (Rec Identity (r ': s ': rs)))
+  basicUnsafeNew n = 
+    consVec (Proxy :: Proxy m) <$> GM.basicUnsafeNew n <*> GM.basicUnsafeNew n
+  {-# INLINE basicUnsafeNew #-}
+  
+  basicUnsafeReplicate :: forall m. PrimMonad m => Int -> Rec Identity (r ': s ': rs) -> m (MVector (PrimState m) (Rec Identity (r ': s ': rs)))
+  basicUnsafeReplicate n (Identity v :& rs) = 
+    consVec (Proxy :: Proxy m) <$> GM.basicUnsafeReplicate n v <*> GM.basicUnsafeReplicate n rs
+  {-# INLINE basicUnsafeReplicate #-}
+
+  basicUnsafeRead (MV (MVectorVal v :& rs)) n = do
+    r <- GM.basicUnsafeRead v n
+    rs <- GM.basicUnsafeRead (MV rs) n
+    return (Identity r :& rs)
+  {-# INLINE basicUnsafeRead #-}
+
+  basicUnsafeWrite (MV (MVectorVal v :& vrs)) n (Identity r :& rs) = do
+    GM.basicUnsafeWrite v n r
+    GM.basicUnsafeWrite (MV vrs) n rs
+  {-# INLINE basicUnsafeWrite #-}
+
+  basicClear (MV (MVectorVal v :& vrs)) = do
+    GM.basicClear v
+    GM.basicClear (MV vrs)
+  {-# INLINE basicClear #-}
+
+  basicSet (MV (MVectorVal v :& vrs)) (Identity r :& rs) = do
+    GM.basicSet v r
+    GM.basicSet (MV vrs) rs
+  {-# INLINE basicSet #-}
+
+  basicUnsafeCopy (MV (MVectorVal a :& as)) (MV (MVectorVal b :& bs)) = do
+    GM.basicUnsafeCopy a b
+    GM.basicUnsafeCopy (MV as) (MV bs)
+  {-# INLINE basicUnsafeCopy #-}
+
+  basicUnsafeMove (MV (MVectorVal a :& as)) (MV (MVectorVal b :& bs)) = do
+    GM.basicUnsafeMove a b
+    GM.basicUnsafeMove (MV as) (MV bs)
+  {-# INLINE basicUnsafeMove #-}
+
+  basicUnsafeGrow :: forall m. PrimMonad m => MVector (PrimState m) (Rec Identity (r ': s ': rs)) -> Int -> m (MVector (PrimState m) (Rec Identity (r ': s ': rs)))
+  basicUnsafeGrow (MV (MVectorVal v :& vrs)) n = do
+    r <- GM.basicUnsafeGrow v n
+    rs <- GM.basicUnsafeGrow (MV vrs) n
+    return (MV (MVectorVal r :& stripMV (Proxy :: Proxy m) rs))
+  {-# INLINE basicUnsafeGrow #-}
+
+#if MIN_VERSION_vector(0,11,0)
+  basicInitialize (MV (MVectorVal v :& rs)) = do
+    GM.basicInitialize v
+    GM.basicInitialize (MV rs)
+  {-# INLINE basicInitialize #-}
+#endif
+
+data Vector :: * -> * where
+  V :: !(Rec VectorVal rs) -> Vector (Rec Identity rs)
+  deriving Typeable
+
+type instance G.Mutable Vector = MVector 
+
+instance ( HasDefaultVector r
+         )
+    => G.Vector Vector (Rec Identity (r ': '[])) where
+  basicUnsafeFreeze (MV (MVectorVal v :& RNil)) = do
+    r <- G.basicUnsafeFreeze v
+    return (V (VectorVal r :& RNil))
+  {-# INLINE basicUnsafeFreeze #-}
+  basicUnsafeThaw (V (VectorVal v :& RNil)) = do
+    r <- G.basicUnsafeThaw v
+    return (MV (MVectorVal r :& RNil))
+  {-# INLINE basicUnsafeThaw #-}
+  basicLength (V (VectorVal v :& RNil)) = G.basicLength v
+  {-# INLINE basicLength #-}
+  basicUnsafeSlice s e (V (VectorVal v :& RNil)) = V (VectorVal (G.basicUnsafeSlice s e v) :& RNil)
+  {-# INLINE basicUnsafeSlice #-}
+  basicUnsafeIndexM (V (VectorVal v :& RNil)) n = do
+    r <- G.basicUnsafeIndexM v n
+    return (Identity r :& RNil)
+  {-# INLINE basicUnsafeIndexM #-}
+  basicUnsafeCopy (MV (MVectorVal m :& RNil)) (V (VectorVal v :& RNil)) = G.basicUnsafeCopy m v
+  {-# INLINE basicUnsafeCopy #-}
+  elemseq (V (VectorVal v :& RNil)) (Identity a :& RNil) b = G.elemseq v a b
+  {-# INLINE elemseq #-}
+
+
+instance ( G.Vector Vector (Rec Identity (s ': rs))
+         , HasDefaultVector r
+         )
+    => G.Vector Vector (Rec Identity (r ': s ': rs)) where
+  basicUnsafeFreeze (MV (MVectorVal v :& vrs)) = do
+    r <- G.basicUnsafeFreeze v
+    rs <- G.basicUnsafeFreeze (MV vrs)
+    return (V (VectorVal r :& stripV rs))
+  {-# INLINE basicUnsafeFreeze #-}
+
+  basicUnsafeThaw :: forall m. PrimMonad m => Vector (Rec Identity (r ': s ': rs)) -> m (G.Mutable Vector (PrimState m) (Rec Identity (r ': s ': rs)))
+  basicUnsafeThaw (V (VectorVal v :& vrs)) = do
+    r <- G.basicUnsafeThaw v
+    rs <- G.basicUnsafeThaw (V vrs)
+    return (MV (MVectorVal r :& stripMV (Proxy :: Proxy m) rs))
+  {-# INLINE basicUnsafeThaw #-}
+
+  basicLength (V (VectorVal v :& _)) = G.basicLength v
+  {-# INLINE basicLength #-}
+
+  basicUnsafeSlice s e (V (VectorVal v :& rs)) = case G.basicUnsafeSlice s e (V rs) of
+    V rsNext -> V (VectorVal (G.basicUnsafeSlice s e v) :& rsNext)
+  {-# INLINE basicUnsafeSlice #-}
+
+  basicUnsafeIndexM (V (VectorVal v :& vrs)) n = do
+    r <- G.basicUnsafeIndexM v n
+    rs <- G.basicUnsafeIndexM (V vrs) n
+    return (Identity r :& rs)
+  {-# INLINE basicUnsafeIndexM #-}
+
+  basicUnsafeCopy (MV (MVectorVal m :& mrs)) (V (VectorVal v :& vrs)) = do
+    G.basicUnsafeCopy m v
+    G.basicUnsafeCopy (MV mrs) (V vrs)
+  {-# INLINE basicUnsafeCopy #-}
+
+  elemseq (V (VectorVal v :& vrs)) (Identity a :& rs) b = G.elemseq v a (G.elemseq (V vrs) rs b)
+  {-# INLINE elemseq #-}
+ 
+-----------------------------------------
+-- Helper functions for instance methods
+-----------------------------------------
+consVec :: Proxy m
+        -> G.Mutable (DefaultVector r) (PrimState m) r 
+        -> MVector (PrimState m) (Rec Identity rs)
+        -> MVector (PrimState m) (Rec Identity (r ': rs))
+consVec _ v (MV rs) = MV (MVectorVal v :& rs)
+{-# INLINE consVec #-}
+
+stripMV :: Proxy m -> MVector (PrimState m) (Rec Identity rs) -> Rec (MVectorVal (PrimState m)) rs
+stripMV _ (MV rs) = rs
+{-# INLINE stripMV #-}
+
+stripV :: Vector (Rec Identity rs) -> Rec VectorVal rs
+stripV (V rs) = rs
+{-# INLINE stripV #-}
diff --git a/src/Data/Vector/Vinyl/Default/NonEmpty/Polymorphic/Implication.hs b/src/Data/Vector/Vinyl/Default/NonEmpty/Polymorphic/Implication.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/NonEmpty/Polymorphic/Implication.hs
@@ -0,0 +1,52 @@
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE DataKinds #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Copyright   :  Andrew Martin
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  Andrew Martin <andrew.thaddeus@gmail.com>
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- This module uses the "constraints" package to prove that if all of the
+-- columns satisfy the 'HasDefaultVector' constraint, then a vector 
+-- parameterized over the record has an instance of the generic vector 
+-- typeclass.
+-----------------------------------------------------------------------------
+module Data.Vector.Vinyl.Default.NonEmpty.Polymorphic.Implication where
+
+import Data.Constraint
+import Data.Vector.Vinyl.Default.NonEmpty.Polymorphic.Internal
+import Data.Vinyl.Core (Rec(..))
+import Data.Vinyl.Functor (Identity(..))
+import Data.Vinyl.TypeLevel (RecAll)
+
+import qualified Data.Vector.Generic.Mutable as GM
+import qualified Data.Vector.Generic as G
+
+listAllVector :: (rs ~ (a ': as))
+              => Rec f rs 
+              -> RecAll f rs HasDefaultVector :- G.Vector Vector (Rec f rs)
+listAllVector (_ :& RNil) = Sub Dict
+listAllVector (_ :& rs@(_ :& _)) = Sub $ case listAllVector rs of
+  Sub Dict -> Dict
+
+listAllMVector :: (rs ~ (a ': as))
+               => Rec f rs 
+               -> RecAll f rs HasDefaultVector :- GM.MVector MVector (Rec f rs)
+listAllMVector (_ :& RNil) = Sub Dict
+listAllMVector (_ :& rs@(_ :& _)) = Sub $ case listAllMVector rs of
+  Sub Dict -> Dict
+
+listAllMVector' :: (rs ~ (a ': as))
+                => proxy1 f
+                -> Rec proxy2 rs 
+                -> RecAll f rs HasDefaultVector :- GM.MVector MVector (Rec f rs)
+listAllMVector' _ (_ :& RNil) = Sub Dict
+listAllMVector' p (_ :& rs@(_ :& _)) = Sub $ case listAllMVector' p rs of
+  Sub Dict -> Dict
+
+
diff --git a/src/Data/Vector/Vinyl/Default/NonEmpty/Polymorphic/Internal.hs b/src/Data/Vector/Vinyl/Default/NonEmpty/Polymorphic/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/NonEmpty/Polymorphic/Internal.hs
@@ -0,0 +1,262 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE InstanceSigs #-}
+
+#ifndef MIN_VERSION_vector
+#define MIN_VERSION_vector(x,y,z) 1
+#endif
+
+module Data.Vector.Vinyl.Default.NonEmpty.Polymorphic.Internal
+  ( MVector(..)
+  , Vector(..)
+  , HasDefaultVector(..)
+  ) where
+
+import Control.Monad
+import Data.Monoid
+import Data.Typeable (Typeable)
+import GHC.Exts (Constraint)
+import Control.Monad.Primitive (PrimMonad,PrimState)
+import qualified Data.Vector.Generic.Mutable as GM
+import qualified Data.Vector.Generic as G
+
+#if MIN_VERSION_vector(0,11,0)
+import Data.Vector.Fusion.Bundle as Stream
+#else
+import Data.Vector.Fusion.Stream as Stream
+#endif
+
+import Prelude hiding ( length, null, replicate, reverse, map, read, take, drop, init, tail )
+import Text.Read
+import Data.Proxy
+
+import Data.Vinyl.Core(Rec(..))
+import Data.Vinyl.Functor (Identity(..),Compose(..))
+import Data.Vector.Vinyl.Default.Types (VectorVal(..),MVectorVal(..),HasDefaultVector(..))
+
+data MVector :: * -> * -> * where
+  MV :: !(Rec (Compose (MVectorVal s) f) rs) -> MVector s (Rec f rs)
+  deriving Typeable
+
+instance ( HasDefaultVector (f r)
+         )
+    => GM.MVector MVector (Rec f (r ': '[])) where
+  basicLength (MV (Compose (MVectorVal v) :& RNil)) = GM.basicLength v
+  {-# INLINE basicLength #-}
+  basicUnsafeSlice s e (MV (Compose (MVectorVal v) :& RNil)) = 
+    MV (Compose (MVectorVal (GM.basicUnsafeSlice s e v)) :& RNil)
+  {-# INLINE basicUnsafeSlice #-}
+  basicOverlaps (MV (Compose (MVectorVal a) :& RNil)) (MV (Compose (MVectorVal b) :& RNil)) = 
+    GM.basicOverlaps a b 
+  {-# INLINE basicOverlaps #-}
+  basicUnsafeNew n = do
+    r <- GM.basicUnsafeNew n 
+    return (MV (Compose (MVectorVal r) :& RNil))
+  {-# INLINE basicUnsafeNew #-}
+  basicUnsafeReplicate n (v :& RNil) = do
+    r <- GM.basicUnsafeReplicate n v 
+    return (MV (Compose (MVectorVal r) :& RNil))
+  {-# INLINE basicUnsafeReplicate #-}
+  basicUnsafeRead (MV (Compose (MVectorVal v) :& RNil)) n = do
+    r <- GM.basicUnsafeRead v n
+    return (r :& RNil)
+  {-# INLINE basicUnsafeRead #-}
+  basicUnsafeWrite (MV (Compose (MVectorVal v) :& RNil)) n (r :& RNil) = GM.basicUnsafeWrite v n r
+  {-# INLINE basicUnsafeWrite #-}
+  basicClear (MV (Compose (MVectorVal v) :& RNil)) = GM.basicClear v
+  {-# INLINE basicClear #-}
+  basicSet (MV (Compose (MVectorVal v) :& RNil)) (r :& RNil) = GM.basicSet v r
+  {-# INLINE basicSet #-}
+  basicUnsafeCopy (MV (Compose (MVectorVal a) :& RNil)) (MV (Compose (MVectorVal b) :& RNil)) = 
+    GM.basicUnsafeCopy a b
+  {-# INLINE basicUnsafeCopy #-}
+  basicUnsafeMove (MV (Compose (MVectorVal a) :& RNil)) (MV (Compose (MVectorVal b) :& RNil)) = 
+    GM.basicUnsafeMove a b
+  {-# INLINE basicUnsafeMove #-}
+  basicUnsafeGrow (MV (Compose (MVectorVal v) :& RNil)) n = do
+    r <- GM.basicUnsafeGrow v n
+    return (MV (Compose (MVectorVal r) :& RNil))
+  {-# INLINE basicUnsafeGrow #-}
+#if MIN_VERSION_vector(0,11,0)
+  basicInitialize (MV (Compose (MVectorVal v) :& RNil)) = do
+    GM.basicInitialize v
+  {-# INLINE basicInitialize #-}
+#endif
+
+instance ( GM.MVector MVector (Rec f (s ': rs))
+         , HasDefaultVector (f r)
+         )
+    => GM.MVector MVector (Rec f (r ': s ': rs)) where
+  basicLength (MV (Compose (MVectorVal v) :& _)) = GM.basicLength v
+  {-# INLINE basicLength #-}
+
+  basicUnsafeSlice s e (MV (Compose (MVectorVal v) :& rs)) = case GM.basicUnsafeSlice s e (MV rs) of
+    MV rsNext -> MV (Compose (MVectorVal (GM.basicUnsafeSlice s e v)) :& rsNext)
+  {-# INLINE basicUnsafeSlice #-}
+
+  basicOverlaps (MV (Compose (MVectorVal a) :& as)) (MV (Compose (MVectorVal b) :& bs)) = 
+    GM.basicOverlaps a b || GM.basicOverlaps (MV as) (MV bs)
+  {-# INLINE basicOverlaps #-}
+
+  basicUnsafeNew :: forall m. PrimMonad m 
+                 => Int -> m (MVector (PrimState m) (Rec f (r ': s ': rs)))
+  basicUnsafeNew n = 
+    consVec (Proxy :: Proxy m) <$> GM.basicUnsafeNew n <*> GM.basicUnsafeNew n
+  {-# INLINE basicUnsafeNew #-}
+  
+  basicUnsafeReplicate :: forall m. PrimMonad m 
+                       => Int -> Rec f (r ': s ': rs) 
+                       -> m (MVector (PrimState m) (Rec f (r ': s ': rs)))
+  basicUnsafeReplicate n (v :& rs) = 
+    consVec (Proxy :: Proxy m) <$> GM.basicUnsafeReplicate n v <*> GM.basicUnsafeReplicate n rs
+  {-# INLINE basicUnsafeReplicate #-}
+
+  basicUnsafeRead (MV (Compose (MVectorVal v) :& rs)) n = do
+    r <- GM.basicUnsafeRead v n
+    rs <- GM.basicUnsafeRead (MV rs) n
+    return (r :& rs)
+  {-# INLINE basicUnsafeRead #-}
+
+  basicUnsafeWrite (MV (Compose (MVectorVal v) :& vrs)) n (r :& rs) = do
+    GM.basicUnsafeWrite v n r
+    GM.basicUnsafeWrite (MV vrs) n rs
+  {-# INLINE basicUnsafeWrite #-}
+
+  basicClear (MV (Compose (MVectorVal v) :& vrs)) = do
+    GM.basicClear v
+    GM.basicClear (MV vrs)
+  {-# INLINE basicClear #-}
+
+  basicSet (MV (Compose (MVectorVal v) :& vrs)) (r :& rs) = do
+    GM.basicSet v r
+    GM.basicSet (MV vrs) rs
+  {-# INLINE basicSet #-}
+
+  basicUnsafeCopy (MV (Compose (MVectorVal a) :& as)) (MV (Compose (MVectorVal b) :& bs)) = do
+    GM.basicUnsafeCopy a b
+    GM.basicUnsafeCopy (MV as) (MV bs)
+  {-# INLINE basicUnsafeCopy #-}
+
+  basicUnsafeMove (MV (Compose (MVectorVal a) :& as)) (MV (Compose (MVectorVal b) :& bs)) = do
+    GM.basicUnsafeMove a b
+    GM.basicUnsafeMove (MV as) (MV bs)
+  {-# INLINE basicUnsafeMove #-}
+
+  basicUnsafeGrow :: forall m. PrimMonad m 
+                  => MVector (PrimState m) (Rec f (r ': s ': rs)) 
+                  -> Int -> m (MVector (PrimState m) (Rec f (r ': s ': rs)))
+  basicUnsafeGrow (MV (Compose (MVectorVal v) :& vrs)) n = do
+    r <- GM.basicUnsafeGrow v n
+    rs <- GM.basicUnsafeGrow (MV vrs) n
+    return (MV (Compose (MVectorVal r) :& stripMV (Proxy :: Proxy m) rs))
+  {-# INLINE basicUnsafeGrow #-}
+
+#if MIN_VERSION_vector(0,11,0)
+  basicInitialize (MV (MVectorVal v :& rs)) = do
+    GM.basicInitialize v
+    GM.basicInitialize (MV rs)
+  {-# INLINE basicInitialize #-}
+#endif
+
+data Vector :: * -> * where
+  V :: !(Rec (Compose VectorVal f) rs) -> Vector (Rec f rs)
+  deriving Typeable
+
+type instance G.Mutable Vector = MVector 
+
+instance ( HasDefaultVector (f r)
+         )
+    => G.Vector Vector (Rec f (r ': '[])) where
+  basicUnsafeFreeze (MV (Compose (MVectorVal v) :& RNil)) = do
+    r <- G.basicUnsafeFreeze v
+    return (V (Compose (VectorVal r) :& RNil))
+  {-# INLINE basicUnsafeFreeze #-}
+  basicUnsafeThaw (V (Compose (VectorVal v) :& RNil)) = do
+    r <- G.basicUnsafeThaw v
+    return (MV (Compose (MVectorVal r) :& RNil))
+  {-# INLINE basicUnsafeThaw #-}
+  basicLength (V (Compose (VectorVal v) :& RNil)) = G.basicLength v
+  {-# INLINE basicLength #-}
+  basicUnsafeSlice s e (V (Compose (VectorVal v) :& RNil)) = 
+    V (Compose (VectorVal (G.basicUnsafeSlice s e v)) :& RNil)
+  {-# INLINE basicUnsafeSlice #-}
+  basicUnsafeIndexM (V (Compose (VectorVal v) :& RNil)) n = do
+    r <- G.basicUnsafeIndexM v n
+    return (r :& RNil)
+  {-# INLINE basicUnsafeIndexM #-}
+  basicUnsafeCopy (MV (Compose (MVectorVal m) :& RNil)) (V (Compose (VectorVal v) :& RNil)) = G.basicUnsafeCopy m v
+  {-# INLINE basicUnsafeCopy #-}
+  elemseq (V (Compose (VectorVal v) :& RNil)) (a :& RNil) b = G.elemseq v a b
+  {-# INLINE elemseq #-}
+
+
+instance ( G.Vector Vector (Rec f (s ': rs))
+         , HasDefaultVector (f r)
+         )
+    => G.Vector Vector (Rec f (r ': s ': rs)) where
+  basicUnsafeFreeze (MV (Compose (MVectorVal v) :& vrs)) = do
+    r <- G.basicUnsafeFreeze v
+    rs <- G.basicUnsafeFreeze (MV vrs)
+    return (V (Compose (VectorVal r) :& stripV rs))
+  {-# INLINE basicUnsafeFreeze #-}
+
+  basicUnsafeThaw :: forall m. PrimMonad m 
+                  => Vector (Rec f (r ': s ': rs)) 
+                  -> m (G.Mutable Vector (PrimState m) (Rec f (r ': s ': rs)))
+  basicUnsafeThaw (V (Compose (VectorVal v) :& vrs)) = do
+    r <- G.basicUnsafeThaw v
+    rs <- G.basicUnsafeThaw (V vrs)
+    return (MV (Compose (MVectorVal r) :& stripMV (Proxy :: Proxy m) rs))
+  {-# INLINE basicUnsafeThaw #-}
+
+  basicLength (V (Compose (VectorVal v) :& _)) = G.basicLength v
+  {-# INLINE basicLength #-}
+
+  basicUnsafeSlice s e (V (Compose (VectorVal v) :& rs)) = case G.basicUnsafeSlice s e (V rs) of
+    V rsNext -> V (Compose (VectorVal (G.basicUnsafeSlice s e v)) :& rsNext)
+  {-# INLINE basicUnsafeSlice #-}
+
+  basicUnsafeIndexM (V (Compose (VectorVal v) :& vrs)) n = do
+    r <- G.basicUnsafeIndexM v n
+    rs <- G.basicUnsafeIndexM (V vrs) n
+    return (r :& rs)
+  {-# INLINE basicUnsafeIndexM #-}
+
+  basicUnsafeCopy (MV (Compose (MVectorVal m) :& mrs)) (V (Compose (VectorVal v) :& vrs)) = do
+    G.basicUnsafeCopy m v
+    G.basicUnsafeCopy (MV mrs) (V vrs)
+  {-# INLINE basicUnsafeCopy #-}
+
+  elemseq (V (Compose (VectorVal v) :& vrs)) (a :& rs) b = G.elemseq v a (G.elemseq (V vrs) rs b)
+  {-# INLINE elemseq #-}
+ 
+-----------------------------------------
+-- Helper functions for instance methods
+-----------------------------------------
+consVec :: Proxy m
+        -> G.Mutable (DefaultVector (f r)) (PrimState m) (f r)
+        -> MVector (PrimState m) (Rec f rs)
+        -> MVector (PrimState m) (Rec f (r ': rs))
+consVec _ v (MV rs) = MV (Compose (MVectorVal v) :& rs)
+{-# INLINE consVec #-}
+
+stripMV :: Proxy m -> MVector (PrimState m) (Rec f rs) -> Rec (Compose (MVectorVal (PrimState m)) f) rs
+stripMV _ (MV rs) = rs
+{-# INLINE stripMV #-}
+
+stripV :: Vector (Rec f rs) -> Rec (Compose VectorVal f) rs
+stripV (V rs) = rs
+{-# INLINE stripV #-}
+
diff --git a/src/Data/Vector/Vinyl/Default/Types.hs b/src/Data/Vector/Vinyl/Default/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/Types.hs
@@ -0,0 +1,214 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE UndecidableInstances #-}
+module Data.Vector.Vinyl.Default.Types
+  ( MVectorVal(..)
+  , VectorVal(..)
+  , HasDefaultVector(..)
+  , DefaultBoxed(..)
+  ) where
+
+import Data.Default (Default(def))
+import qualified Data.Vector as B
+import qualified Data.Vector.Unboxed as U
+import qualified Data.Text as Text
+import qualified Data.Text.Lazy as LText
+import qualified Data.ByteString as ByteString
+import qualified Data.ByteString.Lazy as LByteString
+import qualified Data.Vector.Generic.Mutable as GM
+import qualified Data.Vector.Generic as G
+import Data.Vector.Vinyl.Default.Types.Deriving (derivingVector)
+import Data.Int (Int8,Int16,Int32,Int64)
+import Data.Word (Word8,Word16,Word32,Word64)
+
+newtype VectorVal t = VectorVal { getVectorVal :: DefaultVector t t }
+newtype MVectorVal s t = MVectorVal { getMVectorVal :: G.Mutable (DefaultVector t) s t }
+newtype DefaultBoxed a = DefaultBoxed { getDefaultBoxed :: a }
+
+-- | The most efficient vector type for each column data type.
+class ( GM.MVector (G.Mutable (DefaultVector t)) t
+      , G.Vector (DefaultVector t) t
+      ) => HasDefaultVector t where
+  type DefaultVector t :: * -> *
+
+instance HasDefaultVector (DefaultBoxed a) where
+  type DefaultVector (DefaultBoxed a) = B.Vector
+
+instance HasDefaultVector Int where
+  type DefaultVector Int = U.Vector
+instance HasDefaultVector Char where
+  type DefaultVector Char = U.Vector
+instance HasDefaultVector Bool where
+  type DefaultVector Bool = U.Vector
+instance HasDefaultVector Float where
+  type DefaultVector Float = U.Vector
+instance HasDefaultVector Double where
+  type DefaultVector Double = U.Vector
+
+instance HasDefaultVector Int8 where
+  type DefaultVector Int8 = U.Vector
+instance HasDefaultVector Int16 where
+  type DefaultVector Int16 = U.Vector
+instance HasDefaultVector Int32 where
+  type DefaultVector Int32 = U.Vector
+instance HasDefaultVector Int64 where
+  type DefaultVector Int64 = U.Vector
+
+instance HasDefaultVector Word8 where
+  type DefaultVector Word8 = U.Vector
+instance HasDefaultVector Word16 where
+  type DefaultVector Word16 = U.Vector
+instance HasDefaultVector Word32 where
+  type DefaultVector Word32 = U.Vector
+instance HasDefaultVector Word64 where
+  type DefaultVector Word64 = U.Vector
+
+instance HasDefaultVector [a] where
+  type DefaultVector [a] = B.Vector
+
+instance HasDefaultVector Text.Text where
+  type DefaultVector Text.Text = B.Vector
+instance HasDefaultVector LText.Text where
+  type DefaultVector LText.Text = B.Vector
+instance HasDefaultVector ByteString.ByteString where
+  type DefaultVector ByteString.ByteString = B.Vector
+instance HasDefaultVector LByteString.ByteString where
+  type DefaultVector LByteString.ByteString = B.Vector
+
+instance (HasDefaultVector a, HasDefaultVector b) => HasDefaultVector (a,b) where
+  type DefaultVector (a,b) = V_Tuple2
+
+-- instance for tuples
+data MV_Tuple2 s c where
+  MV_Tuple2 :: MVectorVal s a -> MVectorVal s b -> MV_Tuple2 s (a,b)
+data V_Tuple2 c where
+  V_Tuple2 :: VectorVal a -> VectorVal b -> V_Tuple2 (a,b)
+type instance G.Mutable V_Tuple2 = MV_Tuple2
+
+instance ( HasDefaultVector a
+         , HasDefaultVector b
+         )
+    => GM.MVector MV_Tuple2 (a,b) where
+  basicLength (MV_Tuple2 (MVectorVal v) _) = GM.basicLength v
+  {-# INLINE basicLength #-}
+  basicUnsafeSlice s e (MV_Tuple2 (MVectorVal v) (MVectorVal u)) = MV_Tuple2
+    (MVectorVal (GM.basicUnsafeSlice s e v))
+    (MVectorVal (GM.basicUnsafeSlice s e u))
+  {-# INLINE basicUnsafeSlice #-}
+  basicOverlaps (MV_Tuple2 (MVectorVal v1) (MVectorVal u1)) (MV_Tuple2 (MVectorVal v2) (MVectorVal u2)) = 
+    GM.basicOverlaps v1 v2 || GM.basicOverlaps u1 u2
+  {-# INLINE basicOverlaps #-}
+  basicUnsafeNew n = MV_Tuple2 <$> fmap MVectorVal (GM.basicUnsafeNew n)
+                               <*> fmap MVectorVal (GM.basicUnsafeNew n)
+  {-# INLINE basicUnsafeNew #-}
+  basicUnsafeReplicate n (a,b) = 
+    MV_Tuple2 <$> (fmap MVectorVal (GM.basicUnsafeReplicate n a))
+              <*> (fmap MVectorVal (GM.basicUnsafeReplicate n b))
+  {-# INLINE basicUnsafeReplicate #-}
+  basicUnsafeRead (MV_Tuple2 (MVectorVal v) (MVectorVal u)) n = do
+    v' <- GM.basicUnsafeRead v n
+    u' <- GM.basicUnsafeRead u n
+    return (v',u')
+  {-# INLINE basicUnsafeRead #-}
+  basicUnsafeWrite (MV_Tuple2 (MVectorVal v) (MVectorVal u)) n (v',u') = do
+    GM.basicUnsafeWrite v n v'
+    GM.basicUnsafeWrite u n u'
+  {-# INLINE basicUnsafeWrite #-}
+  basicClear (MV_Tuple2 (MVectorVal v) (MVectorVal u)) = do
+    GM.basicClear v
+    GM.basicClear u
+  {-# INLINE basicClear #-}
+  basicSet (MV_Tuple2 (MVectorVal v) (MVectorVal u)) (v',u') = do
+    GM.basicSet v v'
+    GM.basicSet u u'
+  {-# INLINE basicSet #-}
+  basicUnsafeCopy (MV_Tuple2 (MVectorVal v1) (MVectorVal u1)) (MV_Tuple2 (MVectorVal v2) (MVectorVal u2)) = do
+    GM.basicUnsafeCopy v1 v2
+    GM.basicUnsafeCopy u1 u2
+  {-# INLINE basicUnsafeCopy #-}
+  basicUnsafeMove (MV_Tuple2 (MVectorVal v1) (MVectorVal u1)) (MV_Tuple2 (MVectorVal v2) (MVectorVal u2)) = do
+    GM.basicUnsafeMove v1 v2
+    GM.basicUnsafeMove u1 u2
+  {-# INLINE basicUnsafeMove #-}
+  basicUnsafeGrow (MV_Tuple2 (MVectorVal v) (MVectorVal u)) n = do
+    v' <- GM.basicUnsafeGrow v n
+    u' <- GM.basicUnsafeGrow u n
+    return (MV_Tuple2 (MVectorVal v') (MVectorVal u'))
+  {-# INLINE basicUnsafeGrow #-}
+
+#if MIN_VERSION_vector(0,11,0)
+  basicInitialize (MV_Tuple2 (MVectorVal v) (MVectorVal u)) = do
+    GM.basicInitialize v
+    GM.basicInitialize u
+  {-# INLINE basicInitialize #-}
+#endif
+instance ( HasDefaultVector a
+         , HasDefaultVector b
+         )
+    => G.Vector V_Tuple2 (a,b) where
+  basicUnsafeFreeze (MV_Tuple2 (MVectorVal v) (MVectorVal u)) = do
+    v' <- G.basicUnsafeFreeze v
+    u' <- G.basicUnsafeFreeze u
+    return (V_Tuple2 (VectorVal v') (VectorVal u'))
+  {-# INLINE basicUnsafeFreeze #-}
+  basicUnsafeThaw (V_Tuple2 (VectorVal v) (VectorVal u)) = do
+    v' <- G.basicUnsafeThaw v
+    u' <- G.basicUnsafeThaw u
+    return (MV_Tuple2 (MVectorVal v') (MVectorVal u'))
+  {-# INLINE basicUnsafeThaw #-}
+  basicLength (V_Tuple2 (VectorVal v) _) = G.basicLength v
+  {-# INLINE basicLength #-}
+  basicUnsafeSlice s e (V_Tuple2 (VectorVal v) (VectorVal u)) = 
+    (V_Tuple2 (VectorVal (G.basicUnsafeSlice s e v)) 
+              (VectorVal (G.basicUnsafeSlice s e u)))
+  {-# INLINE basicUnsafeSlice #-}
+  basicUnsafeIndexM (V_Tuple2 (VectorVal v) (VectorVal u)) n = do
+    v' <- G.basicUnsafeIndexM v n
+    u' <- G.basicUnsafeIndexM u n
+    return (v',u')
+  {-# INLINE basicUnsafeIndexM #-}
+  basicUnsafeCopy (MV_Tuple2 (MVectorVal mv) (MVectorVal mu)) (V_Tuple2 (VectorVal v) (VectorVal u)) = do
+    G.basicUnsafeCopy mv v
+    G.basicUnsafeCopy mu u
+  {-# INLINE basicUnsafeCopy #-}
+  elemseq (V_Tuple2 (VectorVal v) (VectorVal u)) (v',u') b = G.elemseq v v' (G.elemseq u u' b)
+  {-# INLINE elemseq #-}
+
+class HasVectorizableRepresentation a where
+  type VectorizableRepresentation a :: *
+
+-- Derived stuff below here. Basically, we want to get
+-- maximally efficient vectors for things like `Maybe a`.
+instance HasVectorizableRepresentation (a,b,c) where
+  type VectorizableRepresentation (a,b,c) = (a,(b,c))
+derivingVector "Tuple3" ''HasDefaultVector ''DefaultVector ''VectorizableRepresentation
+  [t| forall a b c. (HasDefaultVector a, HasDefaultVector b, HasDefaultVector c) => (a,b,c) -> (a,(b,c)) |]
+  [| \ (a,b,c) -> (a,(b,c)) |]
+  [| \ (a,(b,c)) -> (a,b,c) |]
+instance (HasDefaultVector a, HasDefaultVector b, HasDefaultVector c) => HasDefaultVector (a,b,c) where
+  type DefaultVector (a,b,c) = V_Tuple3
+
+instance HasVectorizableRepresentation (Maybe a) where
+  type VectorizableRepresentation (Maybe a) = (Bool,a)
+derivingVector "Maybe" ''HasDefaultVector ''DefaultVector ''VectorizableRepresentation
+  [t| forall a. (Default a, HasDefaultVector a) => Maybe a -> (Bool, a) |]
+  [| maybe (False, def) (\ x -> (True, x)) |]
+  [| \ (b, x) -> if b then Just x else Nothing |]
+instance (Default a, HasDefaultVector a) => HasDefaultVector (Maybe a) where
+  type DefaultVector (Maybe a) = V_Maybe
+
+instance HasVectorizableRepresentation (Either a b) where
+  type VectorizableRepresentation (Either a b) = (Bool,(a,b))
+derivingVector "Either" ''HasDefaultVector ''DefaultVector ''VectorizableRepresentation
+  [t| forall a b. (Default a, Default b, HasDefaultVector a, HasDefaultVector b) => Either a b -> (Bool, (a,b)) |]
+  [| either (\a -> (True,(a,def))) (\b -> (True, (def,b))) |]
+  [| \ (p, (a,b)) -> if p then Left a else Right b |]
+instance (Default a, Default b, HasDefaultVector a, HasDefaultVector b) => HasDefaultVector (Either a b) where
+  type DefaultVector (Either a b) = V_Either
+
diff --git a/src/Data/Vector/Vinyl/Default/Types/Deriving.hs b/src/Data/Vector/Vinyl/Default/Types/Deriving.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/Types/Deriving.hs
@@ -0,0 +1,189 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE TemplateHaskell #-}
+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE Trustworthy #-}
+#endif
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# OPTIONS -Wall #-}
+
+{-|
+Module:      Data.Vector.Unboxed.Deriving
+Copyright:   © 2012−2015 Liyang HU
+License:     BSD3
+Maintainer:  vector-th-unbox@liyang.hu
+Stability:   experimental
+Portability: non-portable
+-}
+
+module Data.Vector.Vinyl.Default.Types.Deriving
+    ( -- $usage
+      derivingVector
+    ) where
+
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative
+#endif
+import Control.Arrow
+import Control.Monad
+import Data.Char (isAlphaNum)
+import qualified Data.Vector.Generic as G
+import qualified Data.Vector.Generic.Mutable as M
+-- import Data.Vector.Unboxed.Base (MVector (..), Vector (..), Unbox)
+import Language.Haskell.TH
+
+-- Create a @Pat@ bound to the given name and an @Exp@ for said binding.
+newPatExp :: String -> Q (Pat, Exp)
+newPatExp = fmap (VarP &&& VarE) . newName
+
+data Common = Common
+    { mvName, vName :: Name
+    , i, n, mv, mv', v :: (Pat, Exp) }
+
+common :: String -> Q Common
+common name = do
+    -- A bit looser than “Haskell 2010: §2.4 Identifiers and Operators”…
+    let valid c = c == '_' || c == '\'' || c == '#' || isAlphaNum c
+    unless (all valid name) $ do
+        fail (show name ++ " is not a valid constructor suffix!")
+    let mvName = mkName ("MV_" ++ name)
+    let vName = mkName ("V_" ++ name)
+    i <- newPatExp "idx"
+    n <- newPatExp "len"
+    mv  <- first (ConP mvName . (:[])) <$> newPatExp "mvec"
+    mv' <- first (ConP mvName . (:[])) <$> newPatExp "mvec'"
+    v   <- first (ConP vName  . (:[])) <$> newPatExp "vec"
+    return Common {..}
+
+-- Turn any 'Name' into a capturable one.
+capture :: Name -> Name
+#if __GLASGOW_HASKELL__ == 704
+capture = mkName . nameBase
+#else
+capture = id
+#endif
+
+liftE :: Exp -> Exp -> Exp
+liftE e = InfixE (Just e) (VarE 'liftM) . Just
+
+-- Create a wrapper for the given function with the same 'nameBase', given
+-- a list of argument bindings and expressions in terms of said bindings.
+-- A final coercion (@Exp → Exp@) is applied to the body of the function.
+-- Complimentary @INLINE@ pragma included.
+wrap :: Name -> [(Pat, Exp)] -> (Exp -> Exp) -> [Dec]
+wrap fun (unzip -> (pats, exps)) coerce = [inline, method] where
+    name = capture fun
+    inline = PragmaD (InlineP name Inline FunLike AllPhases)
+    body = coerce $ foldl AppE (VarE fun) exps
+    method = FunD name [Clause pats (NormalB body) []]
+
+{-| Let's consider a more complex example: suppose we want an @Unbox@
+instance for @Maybe a@. We could encode this using the pair @(Bool, a)@,
+with the boolean indicating whether we have @Nothing@ or @Just@ something.
+This encoding requires a dummy value in the @Nothing@ case, necessitating an
+additional <http://hackage.haskell.org/package/data-default/docs/Data-Default.html#t:Default Default>
+constraint. Thus:
+
+>derivingVector "Maybe"
+>    [t| ∀ a. (Default a, Unbox a) ⇒ Maybe a → (Bool, a) |]
+>    [| maybe (False, def) (\ x → (True, x)) |]
+>    [| \ (b, x) → if b then Just x else Nothing |]
+-}
+derivingVector
+    :: String   -- ^ Unique constructor suffix for the MVector and Vector data families
+    -> Name     -- ^ Name of the class
+    -> Name     -- ^ Name of the default type family
+    -> Name     -- ^ Vec Rep
+    -> TypeQ    -- ^ Quotation of the form @[t| /ctxt/ ⇒ src → rep |]@
+    -> ExpQ     -- ^ Quotation of an expression of type @src → rep@
+    -> ExpQ     -- ^ Quotation of an expression of type @rep → src@
+    -> DecsQ    -- ^ Declarations to be spliced for the derived Unbox instance
+derivingVector name cname famName vecRep argsQ toRepQ fromRepQ = do
+    Common {..} <- common name
+    toRep <- toRepQ
+    fromRep <- fromRepQ
+    a <- second (AppE toRep) <$> newPatExp "val"
+    args <- argsQ
+    (cxts, typ, rep) <- case args of
+        ForallT _ cxts (ArrowT `AppT` typ `AppT` rep) -> return (cxts, typ, rep)
+        ArrowT `AppT` typ `AppT` rep -> return ([], typ, rep)
+        _ -> fail "Expecting a type of the form: cxts => typ -> rep"
+    s <- newName "s"
+    t <- newName "t"
+    let newtypeMVector = NewtypeD [] mvName [PlainTV s, PlainTV t]
+            (NormalC mvName [(NotStrict, (ConT ''G.Mutable `AppT` 
+            (ConT famName `AppT` (ConT vecRep `AppT` VarT t)))
+             `AppT` VarT s `AppT` (ConT vecRep `AppT` VarT t))]) []
+    let mvCon = ConE mvName
+    let instanceMVector = InstanceD cxts
+            (ConT ''M.MVector `AppT` ConT mvName `AppT` typ) $ concat
+            [ wrap 'M.basicLength           [mv]        id
+            , wrap 'M.basicUnsafeSlice      [i, n, mv]  (AppE mvCon)
+            , wrap 'M.basicOverlaps         [mv, mv']   id
+            , wrap 'M.basicUnsafeNew        [n]         (liftE mvCon)
+#if MIN_VERSION_vector(0,11,0)
+            , wrap 'M.basicInitialize       [mv]        id
+#endif
+            , wrap 'M.basicUnsafeReplicate  [n, a]      (liftE mvCon)
+            , wrap 'M.basicUnsafeRead       [mv, i]     (liftE fromRep)
+            , wrap 'M.basicUnsafeWrite      [mv, i, a]  id
+            , wrap 'M.basicClear            [mv]        id
+            , wrap 'M.basicSet              [mv, a]     id
+            , wrap 'M.basicUnsafeCopy       [mv, mv']   id
+            , wrap 'M.basicUnsafeMove       [mv, mv']   id
+            , wrap 'M.basicUnsafeGrow       [mv, n]     (liftE mvCon) ]
+
+    -- let newtypeVector = NewtypeInstD [] ''Vector [typ]
+    --         (NormalC vName [(NotStrict, ConT ''Vector `AppT` rep)]) []
+    let newtypeVector = NewtypeD [] vName [PlainTV t]
+            (NormalC vName [(NotStrict, ConT famName `AppT` (ConT vecRep `AppT` VarT t) `AppT` (ConT vecRep `AppT` VarT t))]) []
+    let vCon  = ConE vName
+    let instanceVector = InstanceD cxts
+            (ConT ''G.Vector `AppT` ConT vName `AppT` typ) $ concat
+            [ wrap 'G.basicUnsafeFreeze     [mv]        (liftE vCon)
+            , wrap 'G.basicUnsafeThaw       [v]         (liftE mvCon)
+            , wrap 'G.basicLength           [v]         id
+            , wrap 'G.basicUnsafeSlice      [i, n, v]   (AppE vCon)
+            , wrap 'G.basicUnsafeIndexM     [v, i]      (liftE fromRep)
+            , wrap 'G.basicUnsafeCopy       [mv, v]     id
+            , wrap 'G.elemseq               [v, a]      id ]
+
+    return 
+      [ -- InstanceD cxts (ConT cname `AppT` typ) []
+        newtypeMVector, instanceMVector
+      , newtypeVector, instanceVector 
+      , TySynInstD ''G.Mutable (TySynEqn [ConT vName] (ConT mvName))
+      ]
+
+#undef __GLASGOW_HASKELL__
+{-$usage
+
+Writing @Unbox@ instances for new data types is tedious and formulaic. More
+often than not, there is a straightforward mapping of the new type onto some
+existing one already imbued with an @Unbox@ instance. The
+<http://hackage.haskell.org/package/vector/docs/Data-Vector-Unboxed.html example>
+from the @vector@ package represents @Complex a@ as pairs @(a, a)@. Using
+'derivingVector', we can define the same instances much more succinctly:
+
+>derivingVector "Complex"
+>    [t| ∀ a. (Unbox a) ⇒ Complex a → (a, a) |]
+>    [| \ (r :+ i) → (r, i) |]
+>    [| \ (r, i) → r :+ i |]
+
+Requires the @MultiParamTypeClasses@, @TemplateHaskell@, @TypeFamilies@ and
+probably the @FlexibleInstances@ @LANGUAGE@ extensions. Note that GHC 7.4
+(but not earlier nor later) needs the 'G.Vector' and 'M.MVector' class
+method names to be in scope in order to define the appropriate instances:
+
+>#if __GLASGOW_HASKELL__ == 704
+>import qualified Data.Vector.Generic
+>import qualified Data.Vector.Generic.Mutable
+>#endif
+
+Consult the <https://github.com/liyang/vector-th-unbox/blob/master/tests/sanity.hs sanity test>
+for a working example.
+
+-}
+
diff --git a/vinyl-vectors.cabal b/vinyl-vectors.cabal
--- a/vinyl-vectors.cabal
+++ b/vinyl-vectors.cabal
@@ -1,5 +1,5 @@
 name:                vinyl-vectors
-version:             0.1.0.3
+version:             0.2.0
 synopsis:            Vectors for vinyl vectors
 description:         This library provides vectors of vinyl records stored
                      as a structure of arrays. This vectors types provided
@@ -22,19 +22,32 @@
 
 library
   hs-source-dirs:      src
-  exposed-modules:     Data.Vector.Vinyl.Default
-                     , Data.Vector.Vinyl.Default.Implication
-                     , Data.Vector.Vinyl.Default.Internal
-                     , Data.Vector.Vinyl.Default.Mutable
+  exposed-modules:     Data.Vector.Vinyl.Default.Empty.Monomorphic
+                     , Data.Vector.Vinyl.Default.Empty.Monomorphic.Implication
+                     , Data.Vector.Vinyl.Default.Empty.Monomorphic.Internal
+                     , Data.Vector.Vinyl.Default.Empty.Monomorphic.Mutable
+
+                     , Data.Vector.Vinyl.Default.NonEmpty.Monomorphic.Internal
+                     , Data.Vector.Vinyl.Default.NonEmpty.Monomorphic.Implication
+
+                     , Data.Vector.Vinyl.Default.NonEmpty.Polymorphic.Internal
+                     , Data.Vector.Vinyl.Default.NonEmpty.Polymorphic.Implication
+
+                     , Data.Vector.Vinyl.Default.Types
+                     -- , Data.Vector.Vinyl.Default.Types.Derived
+                     , Data.Vector.Vinyl.Default.Types.Deriving
                      , Data.Vector.Vinyl.TypeLevel
   build-depends:       base >= 4.7 && < 5
                      , vinyl >= 0.5.1 && < 0.5.2
                      , vector >= 0.10 && < 0.12
                      , primitive >=0.6 && <0.7
                      , constraints >= 0.4
-                     , text >= 0.8.0.0 
+                     , data-default >= 0.5
+                     , template-haskell  >= 2.5
+                     , text 
+                     , bytestring
   default-language:    Haskell2010
-  ghc-options: -Wall -O2
+  ghc-options: -Wall -O2 
 
 executable sorting
   if !flag(examples)
