diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Author name here (c) 2015
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Author name here nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/examples/sorting.hs b/examples/sorting.hs
new file mode 100644
--- /dev/null
+++ b/examples/sorting.hs
@@ -0,0 +1,110 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE DataKinds #-}
+import Data.Vinyl
+import Data.Vinyl.TypeLevel (RIndex,RecAll)
+import Data.Vinyl.Functor (Identity(..))
+import Data.Text (Text)
+import GHC.Exts (Constraint)
+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.Algorithms.Intro as Intro
+import qualified Data.Vector.Algorithms.Merge as Merge
+
+-------------------------------------------------------------------------------
+-- This is a simple example of what can be done with vinyl-vectors. If you have
+-- already cloned the repository, you can run this example with:
+--
+--   stack build --flag vinyl-vectors:examples && stack exec sorting
+--
+-- In this example, we build a vector of records. Internally, this is stored
+-- as a structure of arrays. We then use the vector-algorithms to sort the
+-- data by several different criteria. Feel free to increase the number of
+-- elements to a million or change the record type. Have fun.
+
+numberOfElements :: Int
+numberOfElements = 20
+
+main :: IO ()
+main = do
+  -- vector-algoritms only works on mutable vectors,
+  -- so we just continually mutate recs throughout
+  -- the example.
+  recs <- V.thaw exampleVectorData 
+  printHeading "Original Data"
+  V.mapM_ print =<< V.freeze recs
+
+  Merge.sortBy (compareRecOn (Proxy :: Proxy '[Int])) recs
+  printHeading "Sort by Number"
+  V.mapM_ print =<< V.freeze recs
+
+  Merge.sortBy (compareRecOn (Proxy :: Proxy '[Char])) recs
+  printHeading "Sort by Letter"
+  V.mapM_ print =<< V.freeze recs
+
+  Merge.sortBy (compareRecOn (Proxy :: Proxy '[Char,Int])) recs
+  printHeading "Sort by Letter, Then by Number"
+  V.mapM_ print =<< V.freeze recs
+
+type family RElemAll (rs :: [k]) (ts :: [k]) :: Constraint where
+  RElemAll rs '[] = ()
+  RElemAll rs (t ': ts) = (RElem t rs (RIndex t rs), RElemAll rs ts)
+
+compareRecOn :: forall rs ts. (RElemAll rs ts, ListAll ts Ord, RecApplicative ts)
+  => Proxy ts -> Rec Identity rs -> Rec Identity rs -> Ordering
+compareRecOn _ a b = compareRecOnExplicit rpureX a b
+  where
+  rpureX :: Rec Proxy ts
+  rpureX = rpure Proxy 
+
+compareRecOnExplicit :: (RElemAll rs ts, ListAll ts Ord)
+  => Rec proxy ts -> Rec Identity rs -> Rec Identity rs -> Ordering
+compareRecOnExplicit RNil _ _ = LT -- arbitrary, could be GT as well
+compareRecOnExplicit (r :& rs) a b = mappend
+  (compare (getIdentity $ a ^. rlens r) (getIdentity $ b ^. rlens r))
+  (compareRecOnExplicit rs a b)
+  
+
+proxyInt = Proxy :: Proxy Int
+proxyChar = Proxy :: Proxy Char
+proxyText = Proxy :: Proxy Text
+
+exampleVectorData :: V.Vector (Rec Identity '[Int, Char, Text])
+exampleVectorData = V.fromList exampleData
+
+exampleData :: [Rec Identity '[Int, Char, Text]]
+exampleData = take numberOfElements $ zipWith3 
+  (\i c t -> Identity i :& Identity c :& Identity t :& RNil)
+  numbers letters names
+
+letters :: [Char]
+letters = scramble (cycle (enumFromTo 'a' 'f'))
+
+numbers :: [Int]
+numbers = scramble (enumFrom 1)
+
+names :: [Text]
+names = cycle
+  ["Drew","Luke","Alexa","Fido","Carlos","Juan"
+  ,"Anderson","Shen","Anders", "Andy","Jake"
+  ,"Josh","Michelle"
+  ]
+
+scramble :: [a] -> [a]
+scramble [] = []
+scramble (a : b : c : xs) = c : b : a : scramble xs
+scramble xs = xs
+
+printHeading :: String -> IO ()
+printHeading s = do
+  putStrLn "-------------------"
+  putStrLn s
+  putStrLn "-------------------"
+
diff --git a/src/Data/Vector/Vinyl/Default.hs b/src/Data/Vector/Vinyl/Default.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default.hs
@@ -0,0 +1,1307 @@
+{-# 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
+--
+-- TODO: Write an explanation.
+-----------------------------------------------------------------------------
+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/Implication.hs b/src/Data/Vector/Vinyl/Default/Implication.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/Implication.hs
@@ -0,0 +1,32 @@
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE GADTs #-}
+
+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
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/Internal.hs
@@ -0,0 +1,263 @@
+{-# 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
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/Default/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.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/TypeLevel.hs b/src/Data/Vector/Vinyl/TypeLevel.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Vector/Vinyl/TypeLevel.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Data.Vector.Vinyl.TypeLevel
+  ( ListAll
+  ) where
+
+import GHC.Exts (Constraint)
+
+-- | A constraint on each element of a type-level list.
+type family ListAll (ts :: [k]) (c :: k -> Constraint) :: Constraint where
+  ListAll '[] c = ()
+  ListAll (t ': ts) c = (c t, ListAll ts c)
diff --git a/vinyl-vectors.cabal b/vinyl-vectors.cabal
new file mode 100644
--- /dev/null
+++ b/vinyl-vectors.cabal
@@ -0,0 +1,53 @@
+name:                vinyl-vectors
+version:             0.1.0.0
+synopsis:            Initial project template from stack
+description:         Please see README.md
+homepage:            http://github.com/githubuser/vinyl-vectors#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Author name here
+maintainer:          example@example.com
+copyright:           2010 Author Here
+category:            Web
+build-type:          Simple
+cabal-version:       >=1.10
+
+flag examples
+  description: Build example programs
+  default:     False
+
+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
+                     , 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 
+  default-language:    Haskell2010
+  ghc-options: -Wall -O2
+
+executable sorting
+  if !flag(examples)
+    buildable: False
+  main-is: sorting.hs
+  if flag(examples)
+    build-depends: 
+        vinyl-vectors
+      , base              >= 4.7 && < 5.0
+      , vector-algorithms >= 0.6.0.0 && < 1.0
+      , text              >= 0.8.0.0
+      , vinyl             >= 0.5.1 && < 0.6.0
+      , microlens         >= 0.1
+  hs-source-dirs: examples
+  default-language: Haskell2010
+  ghc-options: -O2
+
+source-repository head
+  type:     git
+  location: https://github.com/andrewthad/vinyl-vectors
