diff --git a/hw-prim.cabal b/hw-prim.cabal
--- a/hw-prim.cabal
+++ b/hw-prim.cabal
@@ -1,5 +1,5 @@
 name:                   hw-prim
-version:                0.1.0.3
+version:                0.3.0.0
 synopsis:               Primitive functions and data types
 description:            Please see README.md
 homepage:               http://github.com/haskell-works/hw-prim#readme
@@ -24,21 +24,37 @@
 
 library
   hs-source-dirs:       src
-  exposed-modules:      HaskellWorks.Data.ByteString
+  exposed-modules:      HaskellWorks.Data.AtIndex
+                      , HaskellWorks.Data.ByteString
                       , HaskellWorks.Data.Char.IsChar
+                      , HaskellWorks.Data.Concat
+                      , HaskellWorks.Data.Container
                       , HaskellWorks.Data.Decode
+                      , HaskellWorks.Data.Drop
+                      , HaskellWorks.Data.Filter
                       , HaskellWorks.Data.FromByteString
                       , HaskellWorks.Data.FromForeignRegion
-                      , HaskellWorks.Data.IndexedSeq
+                      , HaskellWorks.Data.Generate
+                      , HaskellWorks.Data.Length
                       , HaskellWorks.Data.Naive
+                      , HaskellWorks.Data.Narrow
+                      , HaskellWorks.Data.Narrow.Narrow8
+                      , HaskellWorks.Data.Narrow.Narrow16
+                      , HaskellWorks.Data.Narrow.Narrow32
+                      , HaskellWorks.Data.Narrow.Narrow64
                       , HaskellWorks.Data.Positioning
                       , HaskellWorks.Data.Search
-                      , HaskellWorks.Data.Seq
                       , HaskellWorks.Data.Snoc
+                      , HaskellWorks.Data.Take
                       , HaskellWorks.Data.TreeCursor
+                      , HaskellWorks.Data.Uncons
                       , HaskellWorks.Data.Vector.BoxedVectorLike
                       , HaskellWorks.Data.Vector.StorableVectorLike
-                      , HaskellWorks.Data.Vector.VectorLike
+                      , HaskellWorks.Data.Widen
+                      , HaskellWorks.Data.Widen.Widen8
+                      , HaskellWorks.Data.Widen.Widen16
+                      , HaskellWorks.Data.Widen.Widen32
+                      , HaskellWorks.Data.Widen.Widen64
   build-depends:        base                          >= 4          && < 5
                       , bytestring
                       , deepseq
diff --git a/src/HaskellWorks/Data/AtIndex.hs b/src/HaskellWorks/Data/AtIndex.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/AtIndex.hs
@@ -0,0 +1,135 @@
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies        #-}
+
+module HaskellWorks.Data.AtIndex
+    ( Container(..)
+    , AtIndex(..)
+    , Length(..)
+    ) where
+
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Length
+import           HaskellWorks.Data.Positioning
+
+class Length v => AtIndex v where
+  (!!!) :: v -> Position -> Elem v
+  atIndex :: v -> Position -> Elem v
+
+instance AtIndex [a] where
+  (!!!) v i = v !! fromIntegral i
+  atIndex v i = v !! fromIntegral i
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex BS.ByteString where
+  (!!!) v i = v `BS.index` fromIntegral i
+  atIndex v i = BS.index v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DV.Vector Word8) where
+  (!!!) v i = v DV.! fromIntegral i
+  atIndex v i = DV.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DV.Vector Word16) where
+  (!!!) v i = v DV.! fromIntegral i
+  atIndex v i = DV.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DV.Vector Word32) where
+  (!!!) v i = v DV.! fromIntegral i
+  atIndex v i = DV.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DV.Vector Word64) where
+  (!!!) v i = v DV.! fromIntegral i
+  atIndex v i = DV.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DVS.Vector Word8) where
+  (!!!) v i = v DVS.! fromIntegral i
+  atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DVS.Vector Word16) where
+  (!!!) v i = v DVS.! fromIntegral i
+  atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DVS.Vector Word32) where
+  (!!!) v i = v DVS.! fromIntegral i
+  atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DVS.Vector Word64) where
+  (!!!) v i = v DVS.! fromIntegral i
+  atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DV.Vector Int8) where
+  (!!!) v i = v DV.! fromIntegral i
+  atIndex v i = DV.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DV.Vector Int16) where
+  (!!!) v i = v DV.! fromIntegral i
+  atIndex v i = DV.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DV.Vector Int32) where
+  (!!!) v i = v DV.! fromIntegral i
+  atIndex v i = DV.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DV.Vector Int64) where
+  (!!!) v i = v DV.! fromIntegral i
+  atIndex v i = DV.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DVS.Vector Int8) where
+  (!!!) v i = v DVS.! fromIntegral i
+  atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DVS.Vector Int16) where
+  (!!!) v i = v DVS.! fromIntegral i
+  atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DVS.Vector Int32) where
+  (!!!) v i = v DVS.! fromIntegral i
+  atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DVS.Vector Int64) where
+  (!!!) v i = v DVS.! fromIntegral i
+  atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
+
+instance AtIndex (DVS.Vector Int) where
+  (!!!) v i = v DVS.! fromIntegral i
+  atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+  {-# INLINE (!!!)   #-}
+  {-# INLINE atIndex #-}
diff --git a/src/HaskellWorks/Data/Concat.hs b/src/HaskellWorks/Data/Concat.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Concat.hs
@@ -0,0 +1,94 @@
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+module HaskellWorks.Data.Concat
+  ( Concat(..)
+  ) where
+
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.List                     as L
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+
+-- | Class of values that support vector like operations
+class Concat v where
+  concat :: [v] -> v
+
+instance Concat [a] where
+  concat = L.concat
+  {-# INLINE concat #-}
+
+instance Concat BS.ByteString where
+  concat = BS.concat
+  {-# INLINE concat #-}
+
+instance Concat (DV.Vector Word8) where
+  concat = DV.concat
+  {-# INLINE concat #-}
+
+instance Concat (DV.Vector Word16) where
+  concat = DV.concat
+  {-# INLINE concat #-}
+
+instance Concat (DV.Vector Word32) where
+  concat = DV.concat
+  {-# INLINE concat #-}
+
+instance Concat (DV.Vector Word64) where
+  concat = DV.concat
+  {-# INLINE concat #-}
+
+instance Concat (DVS.Vector Word8) where
+  concat = DVS.concat
+  {-# INLINE concat #-}
+
+instance Concat (DVS.Vector Word16) where
+  concat = DVS.concat
+  {-# INLINE concat #-}
+
+instance Concat (DVS.Vector Word32) where
+  concat = DVS.concat
+  {-# INLINE concat #-}
+
+instance Concat (DVS.Vector Word64) where
+  concat = DVS.concat
+  {-# INLINE concat #-}
+
+instance Concat (DV.Vector Int8) where
+  concat = DV.concat
+  {-# INLINE concat #-}
+
+instance Concat (DV.Vector Int16) where
+  concat = DV.concat
+  {-# INLINE concat #-}
+
+instance Concat (DV.Vector Int32) where
+  concat = DV.concat
+  {-# INLINE concat #-}
+
+instance Concat (DV.Vector Int64) where
+  concat = DV.concat
+  {-# INLINE concat #-}
+
+instance Concat (DVS.Vector Int8) where
+  concat = DVS.concat
+  {-# INLINE concat #-}
+
+instance Concat (DVS.Vector Int16) where
+  concat = DVS.concat
+  {-# INLINE concat #-}
+
+instance Concat (DVS.Vector Int32) where
+  concat = DVS.concat
+  {-# INLINE concat #-}
+
+instance Concat (DVS.Vector Int64) where
+  concat = DVS.concat
+  {-# INLINE concat #-}
+
+instance Concat (DVS.Vector Int) where
+  concat = DVS.concat
+  {-# INLINE concat #-}
diff --git a/src/HaskellWorks/Data/Container.hs b/src/HaskellWorks/Data/Container.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Container.hs
@@ -0,0 +1,73 @@
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+module HaskellWorks.Data.Container
+    ( Container(..)
+    ) where
+
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+
+class Container a where
+  type Elem a
+
+instance Container [a] where
+  type Elem [a] = a
+
+instance Container BS.ByteString where
+  type Elem BS.ByteString = Word8
+
+instance Container (DV.Vector Word8) where
+  type Elem (DV.Vector Word8) = Word8
+
+instance Container (DV.Vector Word16) where
+  type Elem (DV.Vector Word16) = Word16
+
+instance Container (DV.Vector Word32) where
+  type Elem (DV.Vector Word32) = Word32
+
+instance Container (DV.Vector Word64) where
+  type Elem (DV.Vector Word64) = Word64
+
+instance Container (DVS.Vector Word8) where
+  type Elem (DVS.Vector Word8) = Word8
+
+instance Container (DVS.Vector Word16) where
+  type Elem (DVS.Vector Word16) = Word16
+
+instance Container (DVS.Vector Word32) where
+  type Elem (DVS.Vector Word32) = Word32
+
+instance Container (DVS.Vector Word64) where
+  type Elem (DVS.Vector Word64) = Word64
+
+instance Container (DV.Vector Int8) where
+  type Elem (DV.Vector Int8) = Int8
+
+instance Container (DV.Vector Int16) where
+  type Elem (DV.Vector Int16) = Int16
+
+instance Container (DV.Vector Int32) where
+  type Elem (DV.Vector Int32) = Int32
+
+instance Container (DV.Vector Int64) where
+  type Elem (DV.Vector Int64) = Int64
+
+instance Container (DVS.Vector Int8) where
+  type Elem (DVS.Vector Int8) = Int8
+
+instance Container (DVS.Vector Int16) where
+  type Elem (DVS.Vector Int16) = Int16
+
+instance Container (DVS.Vector Int32) where
+  type Elem (DVS.Vector Int32) = Int32
+
+instance Container (DVS.Vector Int64) where
+  type Elem (DVS.Vector Int64) = Int64
+
+instance Container (DVS.Vector Int) where
+  type Elem (DVS.Vector Int) = Int
diff --git a/src/HaskellWorks/Data/Drop.hs b/src/HaskellWorks/Data/Drop.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Drop.hs
@@ -0,0 +1,97 @@
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+module HaskellWorks.Data.Drop
+    ( Container(..)
+    , Drop(..)
+    ) where
+
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.List                     as L
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+import           HaskellWorks.Data.Positioning
+import           Prelude hiding (drop)
+
+class Container v => Drop v where
+  drop :: Count -> v -> v
+
+instance Drop [a] where
+  drop = L.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop BS.ByteString where
+  drop = BS.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DV.Vector Word8) where
+  drop = DV.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DV.Vector Word16) where
+  drop = DV.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DV.Vector Word32) where
+  drop = DV.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DV.Vector Word64) where
+  drop = DV.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DVS.Vector Word8) where
+  drop = DVS.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DVS.Vector Word16) where
+  drop = DVS.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DVS.Vector Word32) where
+  drop = DVS.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DVS.Vector Word64) where
+  drop = DVS.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DV.Vector Int8) where
+  drop = DV.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DV.Vector Int16) where
+  drop = DV.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DV.Vector Int32) where
+  drop = DV.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DV.Vector Int64) where
+  drop = DV.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DVS.Vector Int8) where
+  drop = DVS.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DVS.Vector Int16) where
+  drop = DVS.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DVS.Vector Int32) where
+  drop = DVS.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DVS.Vector Int64) where
+  drop = DVS.drop . fromIntegral
+  {-# INLINE drop #-}
+
+instance Drop (DVS.Vector Int) where
+  drop = DVS.drop . fromIntegral
+  {-# INLINE drop #-}
diff --git a/src/HaskellWorks/Data/Filter.hs b/src/HaskellWorks/Data/Filter.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Filter.hs
@@ -0,0 +1,96 @@
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+module HaskellWorks.Data.Filter
+  ( Container(..)
+  , Filter(..)
+  ) where
+
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.List                     as L
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+
+-- | Class of values that support vector like operations
+class Container v => Filter v where
+  filter :: (Elem v -> Bool) -> v -> v
+
+instance Filter String where
+  filter = L.filter
+  {-# INLINE filter #-}
+
+instance Filter BS.ByteString where
+  filter = BS.filter
+  {-# INLINE filter #-}
+
+instance Filter (DV.Vector Word8) where
+  filter = DV.filter
+  {-# INLINE filter #-}
+
+instance Filter (DV.Vector Word16) where
+  filter = DV.filter
+  {-# INLINE filter #-}
+
+instance Filter (DV.Vector Word32) where
+  filter = DV.filter
+  {-# INLINE filter #-}
+
+instance Filter (DV.Vector Word64) where
+  filter = DV.filter
+  {-# INLINE filter #-}
+
+instance Filter (DVS.Vector Word8) where
+  filter = DVS.filter
+  {-# INLINE filter #-}
+
+instance Filter (DVS.Vector Word16) where
+  filter = DVS.filter
+  {-# INLINE filter #-}
+
+instance Filter (DVS.Vector Word32) where
+  filter = DVS.filter
+  {-# INLINE filter #-}
+
+instance Filter (DVS.Vector Word64) where
+  filter = DVS.filter
+  {-# INLINE filter #-}
+
+instance Filter (DV.Vector Int8) where
+  filter = DV.filter
+  {-# INLINE filter #-}
+
+instance Filter (DV.Vector Int16) where
+  filter = DV.filter
+  {-# INLINE filter #-}
+
+instance Filter (DV.Vector Int32) where
+  filter = DV.filter
+  {-# INLINE filter #-}
+
+instance Filter (DV.Vector Int64) where
+  filter = DV.filter
+  {-# INLINE filter #-}
+
+instance Filter (DVS.Vector Int8) where
+  filter = DVS.filter
+  {-# INLINE filter #-}
+
+instance Filter (DVS.Vector Int16) where
+  filter = DVS.filter
+  {-# INLINE filter #-}
+
+instance Filter (DVS.Vector Int32) where
+  filter = DVS.filter
+  {-# INLINE filter #-}
+
+instance Filter (DVS.Vector Int64) where
+  filter = DVS.filter
+  {-# INLINE filter #-}
+
+instance Filter (DVS.Vector Int) where
+  filter = DVS.filter
+  {-# INLINE filter #-}
diff --git a/src/HaskellWorks/Data/Generate.hs b/src/HaskellWorks/Data/Generate.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Generate.hs
@@ -0,0 +1,96 @@
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+module HaskellWorks.Data.Generate
+  ( Container(..)
+  , Generate(..)
+  ) where
+
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+
+-- | Class of values that support vector like operations
+class Container v => Generate v where
+  generate :: Int -> (Int -> Elem v) -> v
+
+instance Generate String where
+  generate n f = f `fmap` [0 .. (n - 1)]
+  {-# INLINE generate #-}
+
+instance Generate BS.ByteString where
+  generate n f = fst (BS.unfoldrN n go 0)
+    where go i = if i /= n then Just (f i, i + 1) else Nothing
+  {-# INLINE generate #-}
+
+instance Generate (DV.Vector Word8) where
+  generate = DV.generate
+  {-# INLINE generate #-}
+
+instance Generate (DV.Vector Word16) where
+  generate = DV.generate
+  {-# INLINE generate #-}
+
+instance Generate (DV.Vector Word32) where
+  generate = DV.generate
+  {-# INLINE generate #-}
+
+instance Generate (DV.Vector Word64) where
+  generate = DV.generate
+  {-# INLINE generate #-}
+
+instance Generate (DVS.Vector Word8) where
+  generate = DVS.generate
+  {-# INLINE generate #-}
+
+instance Generate (DVS.Vector Word16) where
+  generate = DVS.generate
+  {-# INLINE generate #-}
+
+instance Generate (DVS.Vector Word32) where
+  generate = DVS.generate
+  {-# INLINE generate #-}
+
+instance Generate (DVS.Vector Word64) where
+  generate = DVS.generate
+  {-# INLINE generate #-}
+
+instance Generate (DV.Vector Int8) where
+  generate = DV.generate
+  {-# INLINE generate #-}
+
+instance Generate (DV.Vector Int16) where
+  generate = DV.generate
+  {-# INLINE generate #-}
+
+instance Generate (DV.Vector Int32) where
+  generate = DV.generate
+  {-# INLINE generate #-}
+
+instance Generate (DV.Vector Int64) where
+  generate = DV.generate
+  {-# INLINE generate #-}
+
+instance Generate (DVS.Vector Int8) where
+  generate = DVS.generate
+  {-# INLINE generate #-}
+
+instance Generate (DVS.Vector Int16) where
+  generate = DVS.generate
+  {-# INLINE generate #-}
+
+instance Generate (DVS.Vector Int32) where
+  generate = DVS.generate
+  {-# INLINE generate #-}
+
+instance Generate (DVS.Vector Int64) where
+  generate = DVS.generate
+  {-# INLINE generate #-}
+
+instance Generate (DVS.Vector Int) where
+  generate = DVS.generate
+  {-# INLINE generate #-}
diff --git a/src/HaskellWorks/Data/IndexedSeq.hs b/src/HaskellWorks/Data/IndexedSeq.hs
deleted file mode 100644
--- a/src/HaskellWorks/Data/IndexedSeq.hs
+++ /dev/null
@@ -1,134 +0,0 @@
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeFamilies          #-}
-
-module HaskellWorks.Data.IndexedSeq
-    ( IndexedSeq(..)
-    , Seq(..)
-    ) where
-
-import qualified Data.ByteString               as BS
-import           Data.Int
-import qualified Data.Vector                   as DV
-import qualified Data.Vector.Storable          as DVS
-import           Data.Word
-import           HaskellWorks.Data.Positioning
-import           HaskellWorks.Data.Seq
-
-class Seq v => IndexedSeq v where
-  (!!!)   :: v -> Position -> Elem v
-  vIndex  :: v -> Position -> Elem v
-
-instance IndexedSeq String where
-  (!!!)   v (Position i) = v !! fromIntegral i
-  vIndex  v (Position i) = v !! fromIntegral i
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq BS.ByteString where
-  (!!!)   v (Position i) = v `BS.index` fromIntegral i
-  vIndex  v (Position i) = BS.index v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DV.Vector Word8) where
-  (!!!)   v (Position i) = v DV.! fromIntegral i
-  vIndex  v (Position i) = DV.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DV.Vector Word16) where
-  (!!!)   v (Position i) = v DV.! fromIntegral i
-  vIndex  v (Position i) = DV.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DV.Vector Word32) where
-  (!!!)   v (Position i) = v DV.! fromIntegral i
-  vIndex  v (Position i) = DV.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DV.Vector Word64) where
-  (!!!)   v (Position i) = v DV.! fromIntegral i
-  vIndex  v (Position i) = DV.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DVS.Vector Word8) where
-  (!!!)   v (Position i) = v DVS.! fromIntegral i
-  vIndex  v (Position i) = DVS.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DVS.Vector Word16) where
-  (!!!)   v (Position i) = v DVS.! fromIntegral i
-  vIndex  v (Position i) = DVS.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DVS.Vector Word32) where
-  (!!!)   v (Position i) = v DVS.! fromIntegral i
-  vIndex  v (Position i) = DVS.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DVS.Vector Word64) where
-  (!!!)   v (Position i) = v DVS.! fromIntegral i
-  vIndex  v (Position i) = DVS.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DV.Vector Int8) where
-  (!!!)   v (Position i) = v DV.! fromIntegral i
-  vIndex  v (Position i) = DV.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DV.Vector Int16) where
-  (!!!)   v (Position i) = v DV.! fromIntegral i
-  vIndex  v (Position i) = DV.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DV.Vector Int32) where
-  (!!!)   v (Position i) = v DV.! fromIntegral i
-  vIndex  v (Position i) = DV.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DV.Vector Int64) where
-  (!!!)   v (Position i) = v DV.! fromIntegral i
-  vIndex  v (Position i) = DV.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DVS.Vector Int8) where
-  (!!!)   v (Position i) = v DVS.! fromIntegral i
-  vIndex  v (Position i) = DVS.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DVS.Vector Int16) where
-  (!!!)   v (Position i) = v DVS.! fromIntegral i
-  vIndex  v (Position i) = DVS.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DVS.Vector Int32) where
-  (!!!)   v (Position i) = v DVS.! fromIntegral i
-  vIndex  v (Position i) = DVS.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DVS.Vector Int64) where
-  (!!!)   v (Position i) = v DVS.! fromIntegral i
-  vIndex  v (Position i) = DVS.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
-
-instance IndexedSeq (DVS.Vector Int) where
-  (!!!)   v (Position i) = v DVS.! fromIntegral i
-  vIndex  v (Position i) = DVS.unsafeIndex v (fromIntegral i)
-  {-# INLINE (!!!)     #-}
-  {-# INLINE vIndex    #-}
diff --git a/src/HaskellWorks/Data/Length.hs b/src/HaskellWorks/Data/Length.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Length.hs
@@ -0,0 +1,99 @@
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+module HaskellWorks.Data.Length
+    ( Container(..)
+    , Length(..)
+    ) where
+
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.List                     as L
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+import           HaskellWorks.Data.Positioning
+import           Prelude hiding (length)
+
+class Container v => Length v where
+  length :: v -> Count
+  end :: v -> Position
+  end = fromIntegral . length
+  {-# INLINE end #-}
+
+instance Length [a] where
+  length = fromIntegral . L.length
+  {-# INLINE length #-}
+
+instance Length BS.ByteString where
+  length = fromIntegral . BS.length
+  {-# INLINE length #-}
+
+instance Length (DV.Vector Word8) where
+  length = fromIntegral . DV.length
+  {-# INLINE length #-}
+
+instance Length (DV.Vector Word16) where
+  length = fromIntegral . DV.length
+  {-# INLINE length #-}
+
+instance Length (DV.Vector Word32) where
+  length = fromIntegral . DV.length
+  {-# INLINE length #-}
+
+instance Length (DV.Vector Word64) where
+  length = fromIntegral . DV.length
+  {-# INLINE length #-}
+
+instance Length (DVS.Vector Word8) where
+  length = fromIntegral . DVS.length
+  {-# INLINE length #-}
+
+instance Length (DVS.Vector Word16) where
+  length = fromIntegral . DVS.length
+  {-# INLINE length #-}
+
+instance Length (DVS.Vector Word32) where
+  length = fromIntegral . DVS.length
+  {-# INLINE length #-}
+
+instance Length (DVS.Vector Word64) where
+  length = fromIntegral . DVS.length
+  {-# INLINE length #-}
+
+instance Length (DV.Vector Int8) where
+  length = fromIntegral . DV.length
+  {-# INLINE length #-}
+
+instance Length (DV.Vector Int16) where
+  length = fromIntegral . DV.length
+  {-# INLINE length #-}
+
+instance Length (DV.Vector Int32) where
+  length = fromIntegral . DV.length
+  {-# INLINE length #-}
+
+instance Length (DV.Vector Int64) where
+  length = fromIntegral . DV.length
+  {-# INLINE length #-}
+
+instance Length (DVS.Vector Int8) where
+  length = fromIntegral . DVS.length
+  {-# INLINE length #-}
+
+instance Length (DVS.Vector Int16) where
+  length = fromIntegral . DVS.length
+  {-# INLINE length #-}
+
+instance Length (DVS.Vector Int32) where
+  length = fromIntegral . DVS.length
+  {-# INLINE length #-}
+
+instance Length (DVS.Vector Int64) where
+  length = fromIntegral . DVS.length
+  {-# INLINE length #-}
+
+instance Length (DVS.Vector Int) where
+  length = fromIntegral . DVS.length
+  {-# INLINE length #-}
diff --git a/src/HaskellWorks/Data/Narrow.hs b/src/HaskellWorks/Data/Narrow.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Narrow.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE TypeFamilies #-}
+module HaskellWorks.Data.Narrow
+  ( module X
+  ) where
+
+import HaskellWorks.Data.Narrow.Narrow8   as X
+import HaskellWorks.Data.Narrow.Narrow16  as X
+import HaskellWorks.Data.Narrow.Narrow32  as X
+import HaskellWorks.Data.Narrow.Narrow64  as X
diff --git a/src/HaskellWorks/Data/Narrow/Narrow16.hs b/src/HaskellWorks/Data/Narrow/Narrow16.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Narrow/Narrow16.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module HaskellWorks.Data.Narrow.Narrow16
+  ( Narrow16(..)
+  ) where
+
+import Data.Int
+import Data.Word
+
+class Narrow16 a where
+  type Narrowed16 a
+  narrow16 :: a -> Narrowed16 a
+
+instance Narrow16 Word16 where
+  type Narrowed16 Word16 = Word16
+  narrow16 = fromIntegral
+  {-# INLINE narrow16 #-}
+
+instance Narrow16 Word32 where
+  type Narrowed16 Word32 = Word16
+  narrow16 = fromIntegral
+  {-# INLINE narrow16 #-}
+
+instance Narrow16 Word64 where
+  type Narrowed16 Word64 = Word16
+  narrow16 = fromIntegral
+  {-# INLINE narrow16 #-}
+
+instance Narrow16 Int16 where
+  type Narrowed16 Int16 = Int16
+  narrow16 = fromIntegral
+  {-# INLINE narrow16 #-}
+
+instance Narrow16 Int32 where
+  type Narrowed16 Int32 = Int16
+  narrow16 = fromIntegral
+  {-# INLINE narrow16 #-}
+
+instance Narrow16 Int64 where
+  type Narrowed16 Int64 = Int16
+  narrow16 = fromIntegral
+  {-# INLINE narrow16 #-}
diff --git a/src/HaskellWorks/Data/Narrow/Narrow32.hs b/src/HaskellWorks/Data/Narrow/Narrow32.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Narrow/Narrow32.hs
@@ -0,0 +1,32 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module HaskellWorks.Data.Narrow.Narrow32
+  ( Narrow32(..)
+  ) where
+
+import Data.Int
+import Data.Word
+
+class Narrow32 a where
+  type Narrowed32 a
+  narrow32 :: a -> Narrowed32 a
+
+instance Narrow32 Word32 where
+  type Narrowed32 Word32 = Word32
+  narrow32 = fromIntegral
+  {-# INLINE narrow32 #-}
+
+instance Narrow32 Word64 where
+  type Narrowed32 Word64 = Word32
+  narrow32 = fromIntegral
+  {-# INLINE narrow32 #-}
+
+instance Narrow32 Int32 where
+  type Narrowed32 Int32 = Int32
+  narrow32 = fromIntegral
+  {-# INLINE narrow32 #-}
+
+instance Narrow32 Int64 where
+  type Narrowed32 Int64 = Int32
+  narrow32 = fromIntegral
+  {-# INLINE narrow32 #-}
diff --git a/src/HaskellWorks/Data/Narrow/Narrow64.hs b/src/HaskellWorks/Data/Narrow/Narrow64.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Narrow/Narrow64.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module HaskellWorks.Data.Narrow.Narrow64
+  ( Narrow64(..)
+  ) where
+
+import Data.Int
+import Data.Word
+
+class Narrow64 a where
+  type Narrowed64 a
+  narrow64 :: a -> Narrowed64 a
+
+instance Narrow64 Word64 where
+  type Narrowed64 Word64 = Word64
+  narrow64 = fromIntegral
+  {-# INLINE narrow64 #-}
+
+instance Narrow64 Int64 where
+  type Narrowed64 Int64 = Int64
+  narrow64 = fromIntegral
+  {-# INLINE narrow64 #-}
diff --git a/src/HaskellWorks/Data/Narrow/Narrow8.hs b/src/HaskellWorks/Data/Narrow/Narrow8.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Narrow/Narrow8.hs
@@ -0,0 +1,52 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module HaskellWorks.Data.Narrow.Narrow8
+  ( Narrow8(..)
+  ) where
+
+import Data.Int
+import Data.Word
+
+class Narrow8 a where
+  type Narrowed8 a
+  narrow8 :: a -> Narrowed8 a
+
+instance Narrow8 Word8 where
+  type Narrowed8 Word8 = Word8
+  narrow8 = fromIntegral
+  {-# INLINE narrow8 #-}
+
+instance Narrow8 Word16 where
+  type Narrowed8 Word16 = Word8
+  narrow8 = fromIntegral
+  {-# INLINE narrow8 #-}
+
+instance Narrow8 Word32 where
+  type Narrowed8 Word32 = Word8
+  narrow8 = fromIntegral
+  {-# INLINE narrow8 #-}
+
+instance Narrow8 Word64 where
+  type Narrowed8 Word64 = Word8
+  narrow8 = fromIntegral
+  {-# INLINE narrow8 #-}
+
+instance Narrow8 Int8 where
+  type Narrowed8 Int8 = Int8
+  narrow8 = fromIntegral
+  {-# INLINE narrow8 #-}
+
+instance Narrow8 Int16 where
+  type Narrowed8 Int16 = Int8
+  narrow8 = fromIntegral
+  {-# INLINE narrow8 #-}
+
+instance Narrow8 Int32 where
+  type Narrowed8 Int32 = Int8
+  narrow8 = fromIntegral
+  {-# INLINE narrow8 #-}
+
+instance Narrow8 Int64 where
+  type Narrowed8 Int64 = Int8
+  narrow8 = fromIntegral
+  {-# INLINE narrow8 #-}
diff --git a/src/HaskellWorks/Data/Positioning.hs b/src/HaskellWorks/Data/Positioning.hs
--- a/src/HaskellWorks/Data/Positioning.hs
+++ b/src/HaskellWorks/Data/Positioning.hs
@@ -1,48 +1,40 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE TypeSynonymInstances       #-}
 
 module HaskellWorks.Data.Positioning
-  ( Count(..)
-  , Position(..)
+  ( Count
+  , Position
   , lastPositionOf
   , toCount
   , toPosition
   ) where
 
-import           Control.DeepSeq
 import           Data.Int
 import           Data.Word
-import           System.Random
 
 -- | A value representing a count
-newtype Count = Count { getCount :: Word64 }
-  deriving (Eq, Num, Ord, Enum, Integral, Real, Random)
-
-instance Show Count where
-    show (Count w64) = show w64
-
-    -- | A value representing a position
-newtype Position = Position { getPosition :: Int64 }
-  deriving (Eq, Num, Ord, Enum, Real, Integral)
+type Count = Word64
 
-instance Show Position where
-    show (Position n) = show n
+-- | A value representing a position
+type Position = Int64
 
-instance NFData Count where
-  rnf = rnf . getCount
-  {-# INLINE rnf #-}
+class ToPosition a where
+  -- | Convert to a position
+  toPosition :: a -> Position
 
-instance NFData Position where
-  rnf = rnf . getPosition
-  {-# INLINE rnf #-}
+instance ToPosition Count where
+  toPosition = fromIntegral
+  {-# INLINE toPosition #-}
 
--- | Convert a count to a position
-toPosition :: Count -> Position
-toPosition (Count n) = Position (fromIntegral n)
+class ToCount a where
+  -- | Convert a count to a count
+  toCount :: a -> Count
 
--- | Convert a count to a count
-toCount :: Position -> Count
-toCount (Position n) = Count (fromIntegral n)
+instance ToCount Position where
+  toCount = fromIntegral
+  {-# INLINE toCount #-}
 
 -- | Get largest position in a sequenced container of size count.
 lastPositionOf :: Count -> Position
-lastPositionOf (Count c)  = Position (fromIntegral c - 1)
+lastPositionOf c  = fromIntegral c - 1
+{-# INLINE lastPositionOf #-}
diff --git a/src/HaskellWorks/Data/Seq.hs b/src/HaskellWorks/Data/Seq.hs
deleted file mode 100644
--- a/src/HaskellWorks/Data/Seq.hs
+++ /dev/null
@@ -1,348 +0,0 @@
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeFamilies          #-}
-
-module HaskellWorks.Data.Seq
-    ( Seq(..)
-    ) where
-
-import qualified Data.ByteString               as BS
-import           Data.Int
-import qualified Data.Vector                   as DV
-import qualified Data.Vector.Storable          as DVS
-import           Data.Word
-import           HaskellWorks.Data.Positioning
-
-class Seq v where
-  type Elem v
-  vEmpty :: v
-  vLength :: v -> Count
-  vEnd :: v -> Position
-  vEnd = fromIntegral . vLength
-  vDrop :: Count -> v -> v
-  vTake :: Count -> v -> v
-  vUncons :: v -> Maybe (Elem v, v)
-
-instance Seq String where
-  type Elem String = Char
-  vEmpty = ""
-  vLength = Count . fromIntegral . length
-  vEnd = fromIntegral . vLength
-  vDrop = drop . fromIntegral
-  vTake = take . fromIntegral
-  vUncons s = case s of
-    (x:xs)  -> Just (x, xs)
-    _       -> Nothing
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq BS.ByteString where
-  type Elem BS.ByteString = Word8
-
-  vEmpty = BS.empty
-  vLength = Count . fromIntegral . BS.length
-  vEnd = fromIntegral . vLength
-  vDrop = BS.drop . fromIntegral
-  vTake = BS.take . fromIntegral
-  vUncons = BS.uncons
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DV.Vector Word8) where
-  type Elem (DV.Vector Word8) = Word8
-
-  vEmpty = DV.empty
-  vLength = Count . fromIntegral . DV.length
-  vEnd = fromIntegral . vLength
-  vDrop = DV.drop . fromIntegral
-  vTake = DV.take . fromIntegral
-  vUncons s = if DV.length s == 0 then Nothing else Just (DV.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DV.Vector Word16) where
-  type Elem (DV.Vector Word16) = Word16
-
-  vEmpty = DV.empty
-  vLength = Count . fromIntegral . DV.length
-  vEnd = fromIntegral . vLength
-  vDrop = DV.drop . fromIntegral
-  vTake = DV.take . fromIntegral
-  vUncons s = if DV.length s == 0 then Nothing else Just (DV.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DV.Vector Word32) where
-  type Elem (DV.Vector Word32) = Word32
-
-  vEmpty = DV.empty
-  vLength = Count . fromIntegral . DV.length
-  vEnd = fromIntegral . vLength
-  vDrop = DV.drop . fromIntegral
-  vTake = DV.take . fromIntegral
-  vUncons s = if DV.length s == 0 then Nothing else Just (DV.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DV.Vector Word64) where
-  type Elem (DV.Vector Word64) = Word64
-
-  vEmpty = DV.empty
-  vLength = Count . fromIntegral . DV.length
-  vEnd = fromIntegral . vLength
-  vDrop = DV.drop . fromIntegral
-  vTake = DV.take . fromIntegral
-  vUncons s = if DV.length s == 0 then Nothing else Just (DV.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DVS.Vector Word8) where
-  type Elem (DVS.Vector Word8) = Word8
-
-  vEmpty = DVS.empty
-  vLength = Count . fromIntegral . DVS.length
-  vEnd = fromIntegral . vLength
-  vDrop = DVS.drop . fromIntegral
-  vTake = DVS.take . fromIntegral
-  vUncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DVS.Vector Word16) where
-  type Elem (DVS.Vector Word16) = Word16
-
-  vEmpty = DVS.empty
-  vLength = Count . fromIntegral . DVS.length
-  vEnd = fromIntegral . vLength
-  vDrop = DVS.drop . fromIntegral
-  vTake = DVS.take . fromIntegral
-  vUncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DVS.Vector Word32) where
-  type Elem (DVS.Vector Word32) = Word32
-
-  vEmpty = DVS.empty
-  vLength = Count . fromIntegral . DVS.length
-  vEnd = fromIntegral . vLength
-  vDrop = DVS.drop . fromIntegral
-  vTake = DVS.take . fromIntegral
-  vUncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DVS.Vector Word64) where
-  type Elem (DVS.Vector Word64) = Word64
-
-  vEmpty = DVS.empty
-  vLength = Count . fromIntegral . DVS.length
-  vEnd = fromIntegral . vLength
-  vDrop = DVS.drop . fromIntegral
-  vTake = DVS.take . fromIntegral
-  vUncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DV.Vector Int8) where
-  type Elem (DV.Vector Int8) = Int8
-
-  vEmpty = DV.empty
-  vLength = Count . fromIntegral . DV.length
-  vEnd = fromIntegral . vLength
-  vDrop = DV.drop . fromIntegral
-  vTake = DV.take . fromIntegral
-  vUncons s = if DV.length s == 0 then Nothing else Just (DV.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DV.Vector Int16) where
-  type Elem (DV.Vector Int16) = Int16
-
-  vEmpty = DV.empty
-  vLength = Count . fromIntegral . DV.length
-  vEnd = fromIntegral . vLength
-  vDrop = DV.drop . fromIntegral
-  vTake = DV.take . fromIntegral
-  vUncons s = if DV.length s == 0 then Nothing else Just (DV.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DV.Vector Int32) where
-  type Elem (DV.Vector Int32) = Int32
-
-  vEmpty = DV.empty
-  vLength = Count . fromIntegral . DV.length
-  vEnd = fromIntegral . vLength
-  vDrop = DV.drop . fromIntegral
-  vTake = DV.take . fromIntegral
-  vUncons s = if DV.length s == 0 then Nothing else Just (DV.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DV.Vector Int64) where
-  type Elem (DV.Vector Int64) = Int64
-
-  vEmpty = DV.empty
-  vLength = Count . fromIntegral . DV.length
-  vEnd = fromIntegral . vLength
-  vDrop = DV.drop . fromIntegral
-  vTake = DV.take . fromIntegral
-  vUncons s = if DV.length s == 0 then Nothing else Just (DV.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DVS.Vector Int8) where
-  type Elem (DVS.Vector Int8) = Int8
-
-  vEmpty = DVS.empty
-  vLength = Count . fromIntegral . DVS.length
-  vEnd = fromIntegral . vLength
-  vDrop = DVS.drop . fromIntegral
-  vTake = DVS.take . fromIntegral
-  vUncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DVS.Vector Int16) where
-  type Elem (DVS.Vector Int16) = Int16
-
-  vEmpty = DVS.empty
-  vLength = Count . fromIntegral . DVS.length
-  vEnd = fromIntegral . vLength
-  vDrop = DVS.drop . fromIntegral
-  vTake = DVS.take . fromIntegral
-  vUncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DVS.Vector Int32) where
-  type Elem (DVS.Vector Int32) = Int32
-
-  vEmpty = DVS.empty
-  vLength = Count . fromIntegral . DVS.length
-  vEnd = fromIntegral . vLength
-  vDrop = DVS.drop . fromIntegral
-  vTake = DVS.take . fromIntegral
-  vUncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DVS.Vector Int64) where
-  type Elem (DVS.Vector Int64) = Int64
-
-  vEmpty = DVS.empty
-  vLength = Count . fromIntegral . DVS.length
-  vEnd = fromIntegral . vLength
-  vDrop = DVS.drop . fromIntegral
-  vTake = DVS.take . fromIntegral
-  vUncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
-
-instance Seq (DVS.Vector Int) where
-  type Elem (DVS.Vector Int) = Int
-
-  vEmpty = DVS.empty
-  vLength = Count . fromIntegral . DVS.length
-  vEnd = fromIntegral . vLength
-  vDrop = DVS.drop . fromIntegral
-  vTake = DVS.take . fromIntegral
-  vUncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, vDrop 1 s)
-
-  {-# INLINE vEmpty    #-}
-  {-# INLINE vLength   #-}
-  {-# INLINE vEnd      #-}
-  {-# INLINE vDrop     #-}
-  {-# INLINE vTake     #-}
-  {-# INLINE vUncons   #-}
diff --git a/src/HaskellWorks/Data/Snoc.hs b/src/HaskellWorks/Data/Snoc.hs
--- a/src/HaskellWorks/Data/Snoc.hs
+++ b/src/HaskellWorks/Data/Snoc.hs
@@ -11,83 +11,83 @@
 import qualified Data.Vector                   as DV
 import qualified Data.Vector.Storable          as DVS
 import           Data.Word
-import           HaskellWorks.Data.Seq
+import           HaskellWorks.Data.Container
 
-class Seq v => Snoc v where
-  vSnoc :: v -> Elem v -> v
+class Container v => Snoc v where
+  snoc :: v -> Elem v -> v
 
-instance Snoc String where
-  vSnoc v c = v ++ [c]
-  {-# INLINE vSnoc     #-}
+instance Snoc [a] where
+  snoc v a = v ++ [a]
+  {-# INLINE snoc #-}
 
 instance Snoc BS.ByteString where
-  vSnoc = BS.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = BS.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DV.Vector Word8) where
-  vSnoc = DV.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DV.Vector Word16) where
-  vSnoc = DV.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DV.Vector Word32) where
-  vSnoc = DV.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DV.Vector Word64) where
-  vSnoc = DV.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DVS.Vector Word8) where
-  vSnoc = DVS.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DVS.Vector Word16) where
-  vSnoc = DVS.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DVS.Vector Word32) where
-  vSnoc = DVS.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DVS.Vector Word64) where
-  vSnoc = DVS.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DV.Vector Int8) where
-  vSnoc = DV.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DV.Vector Int16) where
-  vSnoc = DV.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DV.Vector Int32) where
-  vSnoc = DV.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DV.Vector Int64) where
-  vSnoc = DV.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DVS.Vector Int8) where
-  vSnoc = DVS.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DVS.Vector Int16) where
-  vSnoc = DVS.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DVS.Vector Int32) where
-  vSnoc = DVS.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DVS.Vector Int64) where
-  vSnoc = DVS.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
 
 instance Snoc (DVS.Vector Int) where
-  vSnoc = DVS.snoc
-  {-# INLINE vSnoc     #-}
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
diff --git a/src/HaskellWorks/Data/Take.hs b/src/HaskellWorks/Data/Take.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Take.hs
@@ -0,0 +1,96 @@
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+module HaskellWorks.Data.Take
+    ( Container(..)
+    , Take(..)
+    ) where
+
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.List                     as L
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+import           HaskellWorks.Data.Positioning
+
+class Container v => Take v where
+  take :: Count -> v -> v
+
+instance Take [a] where
+  take = L.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take BS.ByteString where
+  take = BS.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DV.Vector Word8) where
+  take = DV.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DV.Vector Word16) where
+  take = DV.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DV.Vector Word32) where
+  take = DV.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DV.Vector Word64) where
+  take = DV.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DVS.Vector Word8) where
+  take = DVS.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DVS.Vector Word16) where
+  take = DVS.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DVS.Vector Word32) where
+  take = DVS.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DVS.Vector Word64) where
+  take = DVS.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DV.Vector Int8) where
+  take = DV.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DV.Vector Int16) where
+  take = DV.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DV.Vector Int32) where
+  take = DV.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DV.Vector Int64) where
+  take = DV.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DVS.Vector Int8) where
+  take = DVS.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DVS.Vector Int16) where
+  take = DVS.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DVS.Vector Int32) where
+  take = DVS.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DVS.Vector Int64) where
+  take = DVS.take . fromIntegral
+  {-# INLINE take #-}
+
+instance Take (DVS.Vector Int) where
+  take = DVS.take . fromIntegral
+  {-# INLINE take #-}
diff --git a/src/HaskellWorks/Data/Uncons.hs b/src/HaskellWorks/Data/Uncons.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Uncons.hs
@@ -0,0 +1,99 @@
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+module HaskellWorks.Data.Uncons
+    ( Container(..)
+    , Uncons(..)
+    ) where
+
+import qualified Data.ByteString               as BS
+import           Data.Int
+import           Data.Maybe
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+import           HaskellWorks.Data.Drop
+import           Prelude hiding (drop)
+
+class Drop v => Uncons v where
+  uncons :: v -> Maybe (Elem v, v)
+
+instance Uncons String where
+  uncons s = case s of
+    (x:xs)  -> Just (x, xs)
+    _       -> Nothing
+  {-# INLINE uncons   #-}
+
+instance Uncons BS.ByteString where
+  uncons = BS.uncons
+  {-# INLINE uncons   #-}
+
+instance Uncons (DV.Vector Word8) where
+  uncons s = if DV.length s == 0 then Nothing else Just (DV.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DV.Vector Word16) where
+  uncons s = if DV.length s == 0 then Nothing else Just (DV.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DV.Vector Word32) where
+  uncons s = if DV.length s == 0 then Nothing else Just (DV.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DV.Vector Word64) where
+  uncons s = if DV.length s == 0 then Nothing else Just (DV.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DVS.Vector Word8) where
+  uncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DVS.Vector Word16) where
+  uncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DVS.Vector Word32) where
+  uncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DVS.Vector Word64) where
+  uncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DV.Vector Int8) where
+  uncons s = if DV.length s == 0 then Nothing else Just (DV.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DV.Vector Int16) where
+  uncons s = if DV.length s == 0 then Nothing else Just (DV.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DV.Vector Int32) where
+  uncons s = if DV.length s == 0 then Nothing else Just (DV.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DV.Vector Int64) where
+  uncons s = if DV.length s == 0 then Nothing else Just (DV.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DVS.Vector Int8) where
+  uncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DVS.Vector Int16) where
+  uncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DVS.Vector Int32) where
+  uncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DVS.Vector Int64) where
+  uncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, drop 1 s)
+  {-# INLINE uncons   #-}
+
+instance Uncons (DVS.Vector Int) where
+  uncons s = if DVS.length s == 0 then Nothing else Just (DVS.head s, drop 1 s)
+  {-# INLINE uncons   #-}
diff --git a/src/HaskellWorks/Data/Vector/VectorLike.hs b/src/HaskellWorks/Data/Vector/VectorLike.hs
deleted file mode 100644
--- a/src/HaskellWorks/Data/Vector/VectorLike.hs
+++ /dev/null
@@ -1,176 +0,0 @@
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeFamilies          #-}
-
-module HaskellWorks.Data.Vector.VectorLike
-  ( VectorLike(..)
-  , IndexedSeq(..)
-  , Seq(..)
-  ) where
-
-import qualified Data.ByteString               as BS
-import           Data.Int
-import qualified Data.Vector                   as DV
-import qualified Data.Vector.Storable          as DVS
-import           Data.Word
-import           HaskellWorks.Data.IndexedSeq
-import           HaskellWorks.Data.Snoc
-
--- | Class of values that support vector like operations
-class (IndexedSeq v, Snoc v) => VectorLike v where
-  vConcat :: [v] -> v
-  vFilter :: (Elem v -> Bool) -> v -> v
-  vGenerate :: Int -> (Int -> Elem v) -> v
-
-instance VectorLike String where
-  vConcat = concat
-  vFilter = filter
-  vGenerate n f = f `fmap` [0 .. (n - 1)]
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike BS.ByteString where
-  vConcat = BS.concat
-  vFilter = BS.filter
-  vGenerate n f = fst (BS.unfoldrN n go 0)
-    where go i = if i /= n then Just (f i, i + 1) else Nothing
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DV.Vector Word8) where
-  vConcat = DV.concat
-  vFilter = DV.filter
-  vGenerate = DV.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DV.Vector Word16) where
-  vConcat = DV.concat
-  vFilter = DV.filter
-  vGenerate = DV.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DV.Vector Word32) where
-  vConcat = DV.concat
-  vFilter = DV.filter
-  vGenerate = DV.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DV.Vector Word64) where
-  vConcat = DV.concat
-  vFilter = DV.filter
-  vGenerate = DV.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DVS.Vector Word8) where
-  vConcat = DVS.concat
-  vFilter = DVS.filter
-  vGenerate = DVS.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DVS.Vector Word16) where
-  vConcat = DVS.concat
-  vFilter = DVS.filter
-  vGenerate = DVS.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DVS.Vector Word32) where
-  vConcat = DVS.concat
-  vFilter = DVS.filter
-  vGenerate = DVS.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DVS.Vector Word64) where
-  vConcat = DVS.concat
-  vFilter = DVS.filter
-  vGenerate = DVS.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DV.Vector Int8) where
-  vConcat = DV.concat
-  vFilter = DV.filter
-  vGenerate = DV.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DV.Vector Int16) where
-  vConcat = DV.concat
-  vFilter = DV.filter
-  vGenerate = DV.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DV.Vector Int32) where
-  vConcat = DV.concat
-  vFilter = DV.filter
-  vGenerate = DV.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DV.Vector Int64) where
-  vConcat = DV.concat
-  vFilter = DV.filter
-  vGenerate = DV.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DVS.Vector Int8) where
-  vConcat = DVS.concat
-  vFilter = DVS.filter
-  vGenerate = DVS.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DVS.Vector Int16) where
-  vConcat = DVS.concat
-  vFilter = DVS.filter
-  vGenerate = DVS.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DVS.Vector Int32) where
-  vConcat = DVS.concat
-  vFilter = DVS.filter
-  vGenerate = DVS.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DVS.Vector Int64) where
-  vConcat = DVS.concat
-  vFilter = DVS.filter
-  vGenerate = DVS.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
-
-instance VectorLike (DVS.Vector Int) where
-  vConcat = DVS.concat
-  vFilter = DVS.filter
-  vGenerate = DVS.generate
-  {-# INLINE vConcat   #-}
-  {-# INLINE vFilter   #-}
-  {-# INLINE vGenerate #-}
diff --git a/src/HaskellWorks/Data/Widen.hs b/src/HaskellWorks/Data/Widen.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Widen.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE TypeFamilies #-}
+module HaskellWorks.Data.Widen
+  ( module X
+  ) where
+
+import HaskellWorks.Data.Widen.Widen64 as X
diff --git a/src/HaskellWorks/Data/Widen/Widen16.hs b/src/HaskellWorks/Data/Widen/Widen16.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Widen/Widen16.hs
@@ -0,0 +1,32 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module HaskellWorks.Data.Widen.Widen16
+  ( Widen16(..)
+  ) where
+
+import Data.Int
+import Data.Word
+
+class Widen16 a where
+  type Widened16 a
+  widen16 :: a -> Widened16 a
+
+instance Widen16 Word8 where
+  type Widened16 Word8 = Word16
+  widen16 = fromIntegral
+  {-# INLINE widen16 #-}
+
+instance Widen16 Word16 where
+  type Widened16 Word16 = Word16
+  widen16 = fromIntegral
+  {-# INLINE widen16 #-}
+
+instance Widen16 Int8 where
+  type Widened16 Int8 = Int16
+  widen16 = fromIntegral
+  {-# INLINE widen16 #-}
+
+instance Widen16 Int16 where
+  type Widened16 Int16 = Int16
+  widen16 = fromIntegral
+  {-# INLINE widen16 #-}
diff --git a/src/HaskellWorks/Data/Widen/Widen32.hs b/src/HaskellWorks/Data/Widen/Widen32.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Widen/Widen32.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module HaskellWorks.Data.Widen.Widen32
+  ( Widen32(..)
+  ) where
+
+import Data.Int
+import Data.Word
+
+class Widen32 a where
+  type Widened32 a
+  widen32 :: a -> Widened32 a
+
+instance Widen32 Word8 where
+  type Widened32 Word8 = Word32
+  widen32 = fromIntegral
+  {-# INLINE widen32 #-}
+
+instance Widen32 Word16 where
+  type Widened32 Word16 = Word32
+  widen32 = fromIntegral
+  {-# INLINE widen32 #-}
+
+instance Widen32 Word32 where
+  type Widened32 Word32 = Word32
+  widen32 = fromIntegral
+  {-# INLINE widen32 #-}
+
+instance Widen32 Int8 where
+  type Widened32 Int8 = Int32
+  widen32 = fromIntegral
+  {-# INLINE widen32 #-}
+
+instance Widen32 Int16 where
+  type Widened32 Int16 = Int32
+  widen32 = fromIntegral
+  {-# INLINE widen32 #-}
+
+instance Widen32 Int32 where
+  type Widened32 Int32 = Int32
+  widen32 = fromIntegral
+  {-# INLINE widen32 #-}
diff --git a/src/HaskellWorks/Data/Widen/Widen64.hs b/src/HaskellWorks/Data/Widen/Widen64.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Widen/Widen64.hs
@@ -0,0 +1,52 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module HaskellWorks.Data.Widen.Widen64
+  ( Widen64(..)
+  ) where
+
+import Data.Int
+import Data.Word
+
+class Widen64 a where
+  type Widened64 a
+  widen64 :: a -> Widened64 a
+
+instance Widen64 Word8 where
+  type Widened64 Word8 = Word64
+  widen64 = fromIntegral
+  {-# INLINE widen64 #-}
+
+instance Widen64 Word16 where
+  type Widened64 Word16 = Word64
+  widen64 = fromIntegral
+  {-# INLINE widen64 #-}
+
+instance Widen64 Word32 where
+  type Widened64 Word32 = Word64
+  widen64 = fromIntegral
+  {-# INLINE widen64 #-}
+
+instance Widen64 Word64 where
+  type Widened64 Word64 = Word64
+  widen64 = id
+  {-# INLINE widen64 #-}
+
+instance Widen64 Int8 where
+  type Widened64 Int8 = Int64
+  widen64 = fromIntegral
+  {-# INLINE widen64 #-}
+
+instance Widen64 Int16 where
+  type Widened64 Int16 = Int64
+  widen64 = fromIntegral
+  {-# INLINE widen64 #-}
+
+instance Widen64 Int32 where
+  type Widened64 Int32 = Int64
+  widen64 = fromIntegral
+  {-# INLINE widen64 #-}
+
+instance Widen64 Int64 where
+  type Widened64 Int64 = Int64
+  widen64 = id
+  {-# INLINE widen64 #-}
diff --git a/src/HaskellWorks/Data/Widen/Widen8.hs b/src/HaskellWorks/Data/Widen/Widen8.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Widen/Widen8.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module HaskellWorks.Data.Widen.Widen8
+  ( Widen8(..)
+  ) where
+
+import Data.Int
+import Data.Word
+
+class Widen8 a where
+  type Widened8 a
+  widen8 :: a -> Widened8 a
+
+instance Widen8 Word8 where
+  type Widened8 Word8 = Word8
+  widen8 = fromIntegral
+  {-# INLINE widen8 #-}
+
+instance Widen8 Int8 where
+  type Widened8 Int8 = Int8
+  widen8 = fromIntegral
+  {-# INLINE widen8 #-}
