diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,12 @@
 # Change Log
 
+## [0.6.1.0] - 2017-08-04
+- Add lenses ix, _head and _last
+
+## [0.6.0.0] - 2017-06-07
+- Make ordering of additions in types be more consistent
+- Make slice more general
+
 ## [0.5.1.0] - 2017-02-01
 - Loosen upper bound on `vector`
 
diff --git a/src/Data/Vector/Generic/Sized.hs b/src/Data/Vector/Generic/Sized.hs
--- a/src/Data/Vector/Generic/Sized.hs
+++ b/src/Data/Vector/Generic/Sized.hs
@@ -100,6 +100,10 @@
   , reverse
   , backpermute
   , unsafeBackpermute
+    -- * Lenses
+  , ix
+  , _head
+  , _last
     -- * Elementwise operations
     -- ** Indexing
   , indexed
@@ -303,8 +307,8 @@
 {-# inline index #-}
 
 -- | /O(1)/ Safe indexing using a 'Proxy'.
-index' :: forall v n m a. (KnownNat n, KnownNat m, VG.Vector v a)
-       => Vector v (n+m+1) a -> Proxy n -> a
+index' :: forall v n m a p. (KnownNat n, KnownNat m, VG.Vector v a)
+       => Vector v (n+m+1) a -> p n -> a
 index' (Vector v) p = v `VG.unsafeIndex` i
   where i = fromInteger (natVal p)
 {-# inline index' #-}
@@ -317,7 +321,7 @@
 
 -- | /O(1)/ Yield the first element of a non-empty vector.
 head :: forall v n a. (VG.Vector v a)
-     => Vector v (n+1) a -> a
+     => Vector v (1+n) a -> a
 head (Vector v) = VG.unsafeHead v
 {-# inline head #-}
 
@@ -327,6 +331,24 @@
 last (Vector v) = VG.unsafeLast v
 {-# inline last #-}
 
+-- | Lens to access (/O(1)/) and update (/O(n)/) an arbitrary element by its index.
+ix :: forall v n a f. (KnownNat n, VG.Vector v a, Functor f)
+   => Finite n -> (a -> f a) -> Vector v n a -> f (Vector v n a)
+ix n f vector = (\x -> vector // [(fromInteger $ getFinite n, x)]) <$> f (index vector n)
+{-# inline ix #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) the first element of a non-empty vector.
+_head :: forall v n a f. (KnownNat n, VG.Vector v a, Functor f)
+      => (a -> f a) -> Vector v (1+n) a -> f (Vector v (1+n) a)
+_head f vector = (\x -> cons x $ tail vector) <$> f (head vector)
+{-# inline _head #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) the last element of a non-empty vector.
+_last :: forall v n a f. (KnownNat n, VG.Vector v a, Functor f)
+       => (a -> f a) -> Vector v (n+1) a -> f (Vector v (n+1) a)
+_last f vector = (\x -> snoc (init vector) x) <$> f (last vector)
+{-# inline _last #-}
+
 -- | /O(1)/ Safe indexing in a monad. See the documentation for 'VG.indexM' for
 -- an explanation of why this is useful.
 indexM :: forall v n a m. (KnownNat n, VG.Vector v a, Monad m)
@@ -336,8 +358,8 @@
 
 -- | /O(1)/ Safe indexing in a monad using a 'Proxy'. See the documentation for
 -- 'VG.indexM' for an explanation of why this is useful.
-indexM' :: forall v n k a m. (KnownNat n, KnownNat k, VG.Vector v a, Monad m)
-      => Vector v (n+k) a -> Proxy n -> m a
+indexM' :: forall v n k a m p. (KnownNat n, KnownNat k, VG.Vector v a, Monad m)
+      => Vector v (n+k) a -> p n -> m a
 indexM' (Vector v) p = v `VG.indexM` i
   where i = fromInteger (natVal p)
 {-# inline indexM' #-}
@@ -352,7 +374,7 @@
 -- | /O(1)/ Yield the first element of a non-empty vector in a monad. See the
 -- documentation for 'VG.indexM' for an explanation of why this is useful.
 headM :: forall v n a m. (KnownNat n, VG.Vector v a, Monad m)
-      => Vector v (n+1) a -> m a
+      => Vector v (1+n) a -> m a
 headM (Vector v) = VG.unsafeHeadM v
 {-# inline headM #-}
 
@@ -365,9 +387,9 @@
 
 -- | /O(1)/ Yield a slice of the vector without copying it with an inferred
 -- length argument.
-slice :: forall v i n a. (KnownNat i, KnownNat n, VG.Vector v a)
-      => Proxy i -- ^ starting index
-      -> Vector v (i+n) a
+slice :: forall v i n m a p. (KnownNat i, KnownNat n, KnownNat m, VG.Vector v a)
+      => p i -- ^ starting index
+      -> Vector v (i+n+m) a
       -> Vector v n a
 slice start (Vector v) = Vector (VG.unsafeSlice i n v)
   where i = fromInteger (natVal start)
@@ -376,10 +398,11 @@
 
 -- | /O(1)/ Yield a slice of the vector without copying it with an explicit
 -- length argument.
-slice' :: forall v i n a. (KnownNat i, KnownNat n, VG.Vector v a)
-       => Proxy i -- ^ starting index
-       -> Proxy n -- ^ length
-       -> Vector v (i+n) a
+slice' :: forall v i n m a p
+        . (KnownNat i, KnownNat n, KnownNat m, VG.Vector v a)
+       => p i -- ^ starting index
+       -> p n -- ^ length
+       -> Vector v (i+n+m) a
        -> Vector v n a
 slice' start _ = slice start
 {-# inline slice' #-}
@@ -394,7 +417,7 @@
 -- | /O(1)/ Yield all but the first element of a non-empty vector without
 -- copying.
 tail :: forall v n a. (VG.Vector v a)
-     => Vector v (n+1) a -> Vector v n a
+     => Vector v (1+n) a -> Vector v n a
 tail (Vector v) = Vector (VG.unsafeTail v)
 {-# inline tail #-}
 
@@ -402,7 +425,7 @@
 -- this many elements. The length of the resultant vector is inferred from the
 -- type.
 take :: forall v n m a. (KnownNat n, KnownNat m, VG.Vector v a)
-     => Vector v (m+n) a -> Vector v n a
+     => Vector v (n+m) a -> Vector v n a
 take (Vector v) = Vector (VG.unsafeTake i v)
   where i = fromInteger (natVal (Proxy :: Proxy n))
 {-# inline take #-}
@@ -410,8 +433,8 @@
 -- | /O(1)/ Yield the first n elements. The resultant vector always contains
 -- this many elements. The length of the resultant vector is given explicitly
 -- as a 'Proxy' argument.
-take' :: forall v n m a. (KnownNat n, KnownNat m, VG.Vector v a)
-      => Proxy n -> Vector v (m+n) a -> Vector v n a
+take' :: forall v n m a p. (KnownNat n, KnownNat m, VG.Vector v a)
+      => p n -> Vector v (n+m) a -> Vector v n a
 take' _ = take
 {-# inline take' #-}
 
@@ -419,7 +442,7 @@
 -- contain at least this many elements The length of the resultant vector is
 -- inferred from the type.
 drop :: forall v n m a. (KnownNat n, KnownNat m, VG.Vector v a)
-     => Vector v (m+n) a -> Vector v m a
+     => Vector v (n+m) a -> Vector v m a
 drop (Vector v) = Vector (VG.unsafeDrop i v)
   where i = fromInteger (natVal (Proxy :: Proxy n))
 {-# inline drop #-}
@@ -427,8 +450,8 @@
 -- | /O(1)/ Yield all but the the first n elements. The given vector must
 -- contain at least this many elements The length of the resultant vector is
 -- givel explicitly as a 'Proxy' argument.
-drop' :: forall v n m a. (KnownNat n, KnownNat m, VG.Vector v a)
-      => Proxy n -> Vector v (m+n) a -> Vector v m a
+drop' :: forall v n m a p. (KnownNat n, KnownNat m, VG.Vector v a)
+      => p n -> Vector v (n+m) a -> Vector v m a
 drop' _ = drop
 {-# inline drop' #-}
 
@@ -444,8 +467,8 @@
 -- | /O(1)/ Yield the first n elements paired with the remainder without
 -- copying.  The length of the first resultant vector is passed explicitly as a
 -- 'Proxy' argument.
-splitAt' :: forall v n m a. (KnownNat n, KnownNat m, VG.Vector v a)
-         => Proxy n -> Vector v (n+m) a -> (Vector v n a, Vector v m a)
+splitAt' :: forall v n m a p. (KnownNat n, KnownNat m, VG.Vector v a)
+         => p n -> Vector v (n+m) a -> (Vector v n a, Vector v m a)
 splitAt' _ = splitAt
 {-# inline splitAt' #-}
 
@@ -479,8 +502,8 @@
 
 -- | /O(n)/ Construct a vector with the same element in each position where the
 -- length is given explicitly as a 'Proxy' argument.
-replicate' :: forall v n a. (KnownNat n, VG.Vector v a)
-           => Proxy n -> a -> Vector v n a
+replicate' :: forall v n a p. (KnownNat n, VG.Vector v a)
+           => p n -> a -> Vector v n a
 replicate' _ = replicate
 {-# inline replicate' #-}
 
@@ -494,8 +517,8 @@
 
 -- | /O(n)/ construct a vector of the given length by applying the function to
 -- each index where the length is given explicitly as a 'Proxy' argument.
-generate' :: forall v n a. (KnownNat n, VG.Vector v a)
-          => Proxy n -> (Int -> a) -> Vector v n a
+generate' :: forall v n a p. (KnownNat n, VG.Vector v a)
+          => p n -> (Int -> a) -> Vector v n a
 generate' _ = generate
 {-# inline generate' #-}
 
@@ -520,8 +543,8 @@
 
 -- | /O(n)/ Apply function n times to value. Zeroth element is original value.
 -- The length is given explicitly as a 'Proxy' argument.
-iterateN' :: forall v n a. (KnownNat n, VG.Vector v a)
-          => Proxy n -> (a -> a) -> a -> Vector v n a
+iterateN' :: forall v n a p. (KnownNat n, VG.Vector v a)
+          => p n -> (a -> a) -> a -> Vector v n a
 iterateN' _ = iterateN
 {-# inline iterateN' #-}
 
@@ -539,8 +562,8 @@
 
 -- | /O(n)/ Execute the monadic action @n@ times and store the results in a
 -- vector where @n@ is given explicitly as a 'Proxy' argument.
-replicateM' :: forall v n m a. (KnownNat n, VG.Vector v a, Monad m)
-            => Proxy n -> m a -> m (Vector v n a)
+replicateM' :: forall v n m a p. (KnownNat n, VG.Vector v a, Monad m)
+            => p n -> m a -> m (Vector v n a)
 replicateM' _ = replicateM
 {-# inline replicateM' #-}
 
@@ -554,8 +577,8 @@
 
 -- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
 -- each index where n is given explicitly as a 'Proxy' argument.
-generateM' :: forall v n m a. (KnownNat n, VG.Vector v a, Monad m)
-           => Proxy n -> (Int -> m a) -> m (Vector v n a)
+generateM' :: forall v n m a p. (KnownNat n, VG.Vector v a, Monad m)
+           => p n -> (Int -> m a) -> m (Vector v n a)
 generateM' _ = generateM
 {-# inline generateM' #-}
 
@@ -586,14 +609,14 @@
 -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
 -- the generator function to the a seed. The length, @n@, is given explicitly
 -- as a 'Proxy' argument.
-unfoldrN' :: forall v n a b. (KnownNat n, VG.Vector v a)
-          => Proxy n -> (b -> (a, b)) -> b -> Vector v n a
+unfoldrN' :: forall v n a b p. (KnownNat n, VG.Vector v a)
+          => p n -> (b -> (a, b)) -> b -> Vector v n a
 unfoldrN' _ = unfoldrN
 {-# inline unfoldrN' #-}
 
 --
 -- ** Enumeration
--- 
+--
 
 -- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
 -- etc. The length, @n@, is inferred from the type.
@@ -605,8 +628,8 @@
 
 -- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
 -- etc. The length, @n@, is given explicitly as a 'Proxy' argument.
-enumFromN' :: forall v n a. (KnownNat n, VG.Vector v a, Num a)
-           => a -> Proxy n -> Vector v n a
+enumFromN' :: forall v n a p. (KnownNat n, VG.Vector v a, Num a)
+           => a -> p n -> Vector v n a
 enumFromN' a _ = enumFromN a
 {-# inline enumFromN' #-}
 
@@ -620,8 +643,8 @@
 
 -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
 -- @x+y+y@ etc. The length, @n@, is given explicitly as a 'Proxy' argument.
-enumFromStepN' :: forall v n a. (KnownNat n, VG.Vector v a, Num a)
-               => a -> a -> Proxy n -> Vector v n a
+enumFromStepN' :: forall v n a p. (KnownNat n, VG.Vector v a, Num a)
+               => a -> a -> p n -> Vector v n a
 enumFromStepN' a a' _ = enumFromStepN a a'
 {-# inline enumFromStepN' #-}
 
@@ -631,7 +654,7 @@
 
 -- | /O(n)/ Prepend an element.
 cons :: forall v n a. VG.Vector v a
-     => a -> Vector v n a -> Vector v (n+1) a
+     => a -> Vector v n a -> Vector v (1+n) a
 cons x (Vector xs) = Vector (VG.cons x xs)
 {-# inline cons #-}
 
@@ -1208,7 +1231,7 @@
 {-# inline foldl #-}
 
 -- | /O(n)/ Left fold on non-empty vectors
-foldl1 :: (VG.Vector v a, KnownNat n) => (a -> a -> a) -> Vector v (n+1) a -> a
+foldl1 :: (VG.Vector v a, KnownNat n) => (a -> a -> a) -> Vector v (1+n) a -> a
 foldl1 f = VG.foldl1 f . fromSized
 {-# inline foldl1 #-}
 
@@ -1218,7 +1241,7 @@
 {-# inline foldl' #-}
 
 -- | /O(n)/ Left fold on non-empty vectors with strict accumulator
-foldl1' :: (VG.Vector v a, KnownNat n) => (a -> a -> a) -> Vector v (n+1) a -> a
+foldl1' :: (VG.Vector v a, KnownNat n) => (a -> a -> a) -> Vector v (1+n) a -> a
 foldl1' f = VG.foldl1' f . fromSized
 {-# inline foldl1' #-}
 
@@ -1358,7 +1381,7 @@
 
 -- | /O(n)/ Monadic fold over non-empty vectors
 fold1M :: (Monad m, VG.Vector v a, KnownNat n)
-       => (a -> a -> m a) -> Vector v (n+1) a -> m a
+       => (a -> a -> m a) -> Vector v (1+n) a -> m a
 fold1M m = VG.fold1M m . fromSized
 {-# inline fold1M #-}
 
@@ -1536,12 +1559,12 @@
 
 -- | /O(n)/ Convert a list to a vector
 fromList :: (VG.Vector v a, KnownNat n) => [a] -> Maybe (Vector v n a)
-fromList = toSized . VG.fromList 
+fromList = toSized . VG.fromList
 {-# inline fromList #-}
 
 -- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
 -- the resultant vector is inferred from the type.
-fromListN :: forall v n a. (VG.Vector v a, KnownNat n) 
+fromListN :: forall v n a. (VG.Vector v a, KnownNat n)
           => [a] -> Maybe (Vector v n a)
 fromListN = toSized . VG.fromListN i
   where i = fromInteger (natVal (Proxy :: Proxy n))
@@ -1549,8 +1572,8 @@
 
 -- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
 -- the resultant vector is given explicitly as a 'Proxy' argument.
-fromListN' :: forall v n a. (VG.Vector v a, KnownNat n) 
-           => Proxy n -> [a] -> Maybe (Vector v n a)
+fromListN' :: forall v n a p. (VG.Vector v a, KnownNat n)
+           => p n -> [a] -> Maybe (Vector v n a)
 fromListN' _ = fromListN
 {-# inline fromListN' #-}
 
@@ -1608,3 +1631,37 @@
                  => (v a -> w b) -> Vector v n a -> Vector w n b
 withVectorUnsafe f (Vector v) = Vector (f v)
 {-# inline withVectorUnsafe #-}
+
+instance (VG.Vector v a, Num a, KnownNat n) => Num (Vector v n a) where
+    (+)         = zipWith (+)
+    (-)         = zipWith (-)
+    (*)         = zipWith (*)
+    negate      = map negate
+    abs         = map abs
+    signum      = map signum
+    fromInteger = replicate . fromInteger
+
+instance (VG.Vector v a, Fractional a, KnownNat n) => Fractional (Vector v n a) where
+    (/)          = zipWith (/)
+    recip        = map recip
+    fromRational = replicate . fromRational
+
+instance (VG.Vector v a, Floating a, KnownNat n) => Floating (Vector v n a) where
+    pi      = replicate pi
+    exp     = map exp
+    log     = map log
+    sqrt    = map sqrt
+    (**)    = zipWith (**)
+    logBase = zipWith logBase
+    sin     = map sin
+    cos     = map cos
+    tan     = map tan
+    asin    = map asin
+    acos    = map acos
+    atan    = map atan
+    sinh    = map sinh
+    cosh    = map cosh
+    tanh    = map tanh
+    asinh   = map asinh
+    acosh   = map acosh
+    atanh   = map atanh
diff --git a/src/Data/Vector/Sized.hs b/src/Data/Vector/Sized.hs
--- a/src/Data/Vector/Sized.hs
+++ b/src/Data/Vector/Sized.hs
@@ -1,11 +1,11 @@
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DataKinds                  #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE FlexibleInstances          #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE KindSignatures #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE KindSignatures             #-}
+{-# LANGUAGE RankNTypes                 #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE TypeOperators              #-}
 
 {-|
 This module re-exports the functionality in 'Data.Vector.Generic.Sized'
@@ -97,6 +97,10 @@
   , reverse
   , backpermute
   , unsafeBackpermute
+  -- * Lenses
+  , ix
+  , _head
+  , _last
     -- * Elementwise operations
     -- ** Indexing
   , indexed
@@ -263,8 +267,8 @@
 {-# inline index #-}
 
 -- | /O(1)/ Safe indexing using a 'Proxy'.
-index' :: forall n m a. (KnownNat n, KnownNat m)
-       => Vector (n+m+1) a -> Proxy n -> a
+index' :: forall n m a p. (KnownNat n, KnownNat m)
+       => Vector (n+m+1) a -> p n -> a
 index' = V.index'
 {-# inline index' #-}
 
@@ -275,7 +279,7 @@
 {-# inline unsafeIndex #-}
 
 -- | /O(1)/ Yield the first element of a non-empty vector.
-head :: forall n a. Vector (n+1) a -> a
+head :: forall n a. Vector (1+n) a -> a
 head = V.head
 {-# inline head #-}
 
@@ -284,6 +288,24 @@
 last = V.last
 {-# inline last #-}
 
+-- | Lens to access (/O(1)/) and update (/O(n)/) an arbitrary element by its index.
+ix :: forall n a f. (KnownNat n, Functor f)
+   => Finite n -> (a -> f a) -> Vector n a -> f (Vector n a)
+ix = V.ix
+{-# inline ix #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) the first element of a non-empty vector.
+_head :: forall n a f. (KnownNat n, Functor f)
+   => (a -> f a) -> Vector (1+n) a -> f (Vector (1+n) a)
+_head = V._head
+{-# inline _head #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) the last element of a non-empty vector.
+_last :: forall n a f. (KnownNat n, Functor f)
+      => (a -> f a) -> Vector (n+1) a -> f (Vector (n+1) a)
+_last = V._last
+{-# inline _last #-}
+
 -- | /O(1)/ Safe indexing in a monad. See the documentation for 'VG.indexM' for
 -- an explanation of why this is useful.
 indexM :: forall n a m. (KnownNat n, Monad m)
@@ -293,8 +315,8 @@
 
 -- | /O(1)/ Safe indexing in a monad using a 'Proxy'. See the documentation for
 -- 'VG.indexM' for an explanation of why this is useful.
-indexM' :: forall n k a m. (KnownNat n, KnownNat k, Monad m)
-      => Vector (n+k) a -> Proxy n -> m a
+indexM' :: forall n k a m p. (KnownNat n, KnownNat k, Monad m)
+      => Vector (n+k) a -> p n -> m a
 indexM' = V.indexM'
 {-# inline indexM' #-}
 
@@ -308,7 +330,7 @@
 -- | /O(1)/ Yield the first element of a non-empty vector in a monad. See the
 -- documentation for 'VG.indexM' for an explanation of why this is useful.
 headM :: forall n a m. (KnownNat n, Monad m)
-      => Vector (n+1) a -> m a
+      => Vector (1+n) a -> m a
 headM = V.headM
 {-# inline headM #-}
 
@@ -321,19 +343,19 @@
 
 -- | /O(1)/ Yield a slice of the vector without copying it with an inferred
 -- length argument.
-slice :: forall i n a. (KnownNat i, KnownNat n)
-      => Proxy i -- ^ starting index
-      -> Vector (i+n) a
+slice :: forall i n m a p. (KnownNat i, KnownNat n, KnownNat m)
+      => p i -- ^ starting index
+      -> Vector (i+n+m) a
       -> Vector n a
 slice = V.slice
 {-# inline slice #-}
 
 -- | /O(1)/ Yield a slice of the vector without copying it with an explicit
 -- length argument.
-slice' :: forall i n a. (KnownNat i, KnownNat n)
-       => Proxy i -- ^ starting index
-       -> Proxy n -- ^ length
-       -> Vector (i+n) a
+slice' :: forall i n m a p. (KnownNat i, KnownNat n, KnownNat m)
+       => p i -- ^ starting index
+       -> p n -- ^ length
+       -> Vector (i+n+m) a
        -> Vector n a
 slice' = V.slice'
 {-# inline slice' #-}
@@ -346,7 +368,7 @@
 
 -- | /O(1)/ Yield all but the first element of a non-empty vector without
 -- copying.
-tail :: forall n a. Vector (n+1) a -> Vector n a
+tail :: forall n a. Vector (1+n) a -> Vector n a
 tail = V.tail
 {-# inline tail #-}
 
@@ -354,15 +376,15 @@
 -- this many elements. The length of the resultant vector is inferred from the
 -- type.
 take :: forall n m a. (KnownNat n, KnownNat m)
-     => Vector (m+n) a -> Vector n a
+     => Vector (n+m) a -> Vector n a
 take = V.take
 {-# inline take #-}
 
 -- | /O(1)/ Yield the first n elements. The resultant vector always contains
 -- this many elements. The length of the resultant vector is given explicitly
 -- as a 'Proxy' argument.
-take' :: forall n m a. (KnownNat n, KnownNat m)
-      => Proxy n -> Vector (m+n) a -> Vector n a
+take' :: forall n m a p. (KnownNat n, KnownNat m)
+      => p n -> Vector (n+m) a -> Vector n a
 take' = V.take'
 {-# inline take' #-}
 
@@ -370,15 +392,15 @@
 -- contain at least this many elements The length of the resultant vector is
 -- inferred from the type.
 drop :: forall n m a. (KnownNat n, KnownNat m)
-     => Vector (m+n) a -> Vector m a
+     => Vector (n+m) a -> Vector m a
 drop = V.drop
 {-# inline drop #-}
 
 -- | /O(1)/ Yield all but the the first n elements. The given vector must
 -- contain at least this many elements The length of the resultant vector is
 -- givel explicitly as a 'Proxy' argument.
-drop' :: forall n m a. (KnownNat n, KnownNat m)
-      => Proxy n -> Vector (m+n) a -> Vector m a
+drop' :: forall n m a p. (KnownNat n, KnownNat m)
+      => p n -> Vector (n+m) a -> Vector m a
 drop' = V.drop'
 {-# inline drop' #-}
 
@@ -392,8 +414,8 @@
 -- | /O(1)/ Yield the first n elements paired with the remainder without
 -- copying.  The length of the first resultant vector is passed explicitly as a
 -- 'Proxy' argument.
-splitAt' :: forall n m a. (KnownNat n, KnownNat m)
-         => Proxy n -> Vector (n+m) a -> (Vector n a, Vector m a)
+splitAt' :: forall n m a p. (KnownNat n, KnownNat m)
+         => p n -> Vector (n+m) a -> (Vector n a, Vector m a)
 splitAt' = V.splitAt'
 {-# inline splitAt' #-}
 
@@ -424,8 +446,8 @@
 
 -- | /O(n)/ Construct a vector with the same element in each position where the
 -- length is given explicitly as a 'Proxy' argument.
-replicate' :: forall n a. KnownNat n
-           => Proxy n -> a -> Vector n a
+replicate' :: forall n a p. KnownNat n
+           => p n -> a -> Vector n a
 replicate' = V.replicate'
 {-# inline replicate' #-}
 
@@ -438,8 +460,8 @@
 
 -- | /O(n)/ construct a vector of the given length by applying the function to
 -- each index where the length is given explicitly as a 'Proxy' argument.
-generate' :: forall n a. KnownNat n
-          => Proxy n -> (Int -> a) -> Vector n a
+generate' :: forall n a p. KnownNat n
+          => p n -> (Int -> a) -> Vector n a
 generate' = V.generate'
 {-# inline generate' #-}
 
@@ -462,8 +484,8 @@
 
 -- | /O(n)/ Apply function n times to value. Zeroth element is original value.
 -- The length is given explicitly as a 'Proxy' argument.
-iterateN' :: forall n a. KnownNat n
-          => Proxy n -> (a -> a) -> a -> Vector n a
+iterateN' :: forall n a p. KnownNat n
+          => p n -> (a -> a) -> a -> Vector n a
 iterateN' = V.iterateN'
 {-# inline iterateN' #-}
 
@@ -480,8 +502,8 @@
 
 -- | /O(n)/ Execute the monadic action @n@ times and store the results in a
 -- vector where @n@ is given explicitly as a 'Proxy' argument.
-replicateM' :: forall n m a. (KnownNat n, Monad m)
-            => Proxy n -> m a -> m (Vector n a)
+replicateM' :: forall n m a p. (KnownNat n, Monad m)
+            => p n -> m a -> m (Vector n a)
 replicateM' = V.replicateM'
 {-# inline replicateM' #-}
 
@@ -504,8 +526,8 @@
 
 -- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
 -- each index where n is given explicitly as a 'Proxy' argument.
-generateM' :: forall n m a. (KnownNat n, Monad m)
-           => Proxy n -> (Int -> m a) -> m (Vector n a)
+generateM' :: forall n m a p. (KnownNat n, Monad m)
+           => p n -> (Int -> m a) -> m (Vector n a)
 generateM' = V.generateM'
 {-# inline generateM' #-}
 
@@ -524,14 +546,14 @@
 -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
 -- the generator function to the a seed. The length, @n@, is given explicitly
 -- as a 'Proxy' argument.
-unfoldrN' :: forall n a b. KnownNat n
-          => Proxy n -> (b -> (a, b)) -> b -> Vector n a
+unfoldrN' :: forall n a b p. KnownNat n
+          => p n -> (b -> (a, b)) -> b -> Vector n a
 unfoldrN' = V.unfoldrN'
 {-# inline unfoldrN' #-}
 
 --
 -- ** Enumeration
--- 
+--
 
 -- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
 -- etc. The length, @n@, is inferred from the type.
@@ -542,8 +564,8 @@
 
 -- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
 -- etc. The length, @n@, is given explicitly as a 'Proxy' argument.
-enumFromN' :: forall n a. (KnownNat n, Num a)
-           => a -> Proxy n -> Vector n a
+enumFromN' :: forall n a p. (KnownNat n, Num a)
+           => a -> p n -> Vector n a
 enumFromN' = V.enumFromN'
 {-# inline enumFromN' #-}
 
@@ -556,8 +578,8 @@
 
 -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
 -- @x+y+y@ etc. The length, @n@, is given explicitly as a 'Proxy' argument.
-enumFromStepN' :: forall n a. (KnownNat n, Num a)
-               => a -> a -> Proxy n -> Vector n a
+enumFromStepN' :: forall n a p. (KnownNat n, Num a)
+               => a -> a -> p n -> Vector n a
 enumFromStepN' = V.enumFromStepN'
 {-# inline enumFromStepN' #-}
 
@@ -566,7 +588,7 @@
 --
 
 -- | /O(n)/ Prepend an element.
-cons :: forall n a. a -> Vector n a -> Vector (n+1) a
+cons :: forall n a. a -> Vector n a -> Vector (1+n) a
 cons = V.cons
 {-# inline cons #-}
 
@@ -862,7 +884,7 @@
          -> Vector n c
          -> Vector n d
          -> Vector n e
-zipWith4 = V.zipWith4 
+zipWith4 = V.zipWith4
 {-# inline zipWith4 #-}
 
 zipWith5 :: (a -> b -> c -> d -> e -> f)
@@ -1074,7 +1096,7 @@
 {-# inline foldl #-}
 
 -- | /O(n)/ Left fold on non-empty vectors
-foldl1 :: KnownNat n => (a -> a -> a) -> Vector (n+1) a -> a
+foldl1 :: KnownNat n => (a -> a -> a) -> Vector (1+n) a -> a
 foldl1 = V.foldl1
 {-# inline foldl1 #-}
 
@@ -1084,7 +1106,7 @@
 {-# inline foldl' #-}
 
 -- | /O(n)/ Left fold on non-empty vectors with strict accumulator
-foldl1' :: KnownNat n => (a -> a -> a) -> Vector (n+1) a -> a
+foldl1' :: KnownNat n => (a -> a -> a) -> Vector (1+n) a -> a
 foldl1' = V.foldl1'
 {-# inline foldl1' #-}
 
@@ -1224,7 +1246,7 @@
 
 -- | /O(n)/ Monadic fold over non-empty vectors
 fold1M :: (Monad m, KnownNat n)
-       => (a -> a -> m a) -> Vector (n+1) a -> m a
+       => (a -> a -> m a) -> Vector (1+n) a -> m a
 fold1M = V.fold1M
 {-# inline fold1M #-}
 
@@ -1413,8 +1435,8 @@
 
 -- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
 -- the resultant vector is given explicitly as a 'Proxy' argument.
-fromListN' :: forall n a. KnownNat n
-           => Proxy n -> [a] -> Maybe (Vector n a)
+fromListN' :: forall n a p. KnownNat n
+           => p n -> [a] -> Maybe (Vector n a)
 fromListN' = V.fromListN'
 {-# inline fromListN' #-}
 
diff --git a/src/Data/Vector/Storable/Sized.hs b/src/Data/Vector/Storable/Sized.hs
--- a/src/Data/Vector/Storable/Sized.hs
+++ b/src/Data/Vector/Storable/Sized.hs
@@ -1,11 +1,10 @@
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE KindSignatures      #-}
+{-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TypeOperators       #-}
 
 {-|
 This module re-exports the functionality in 'Data.Vector.Generic.Sized'
@@ -97,6 +96,10 @@
   , reverse
   , backpermute
   , unsafeBackpermute
+    -- * Lenses
+  , ix
+  , _head
+  , _last
     -- * Elementwise operations
     -- ** Indexing
   , indexed
@@ -264,8 +267,8 @@
 {-# inline index #-}
 
 -- | /O(1)/ Safe indexing using a 'Proxy'.
-index' :: forall n m a. (KnownNat n, KnownNat m, Storable a)
-       => Vector (n+m+1) a -> Proxy n -> a
+index' :: forall n m a p. (KnownNat n, KnownNat m, Storable a)
+       => Vector (n+m+1) a -> p n -> a
 index' = V.index'
 {-# inline index' #-}
 
@@ -277,7 +280,7 @@
 
 -- | /O(1)/ Yield the first element of a non-empty vector.
 head :: forall n a. (Storable a)
-     => Vector (n+1) a -> a
+     => Vector (1+n) a -> a
 head = V.head
 {-# inline head #-}
 
@@ -287,6 +290,25 @@
 last = V.last
 {-# inline last #-}
 
+-- | Lens to access (/O(1)/) and update (/O(n)/) an arbitrary element by its index.
+ix :: forall n a f. (KnownNat n, Storable a, Functor f)
+   => Finite n -> (a -> f a) -> Vector n a -> f (Vector n a)
+ix = V.ix
+{-# inline ix #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) the first element of a non-empty vector.
+_head :: forall n a f. (KnownNat n, Storable a, Functor f)
+      => (a -> f a) -> Vector (1+n) a -> f (Vector (1+n) a)
+_head = V._head
+{-# inline _head #-}
+
+-- | Lens to access (/O(1)/) and update (/O(n)/) the last element of a non-empty vector.
+_last :: forall n a f. (KnownNat n, Storable a, Functor f)
+       => (a -> f a) -> Vector (n+1) a -> f (Vector (n+1) a)
+_last = V._last
+{-# inline _last #-}
+
+
 -- | /O(1)/ Safe indexing in a monad. See the documentation for 'VG.indexM' for
 -- an explanation of why this is useful.
 indexM :: forall n a m. (KnownNat n, Storable a, Monad m)
@@ -296,8 +318,8 @@
 
 -- | /O(1)/ Safe indexing in a monad using a 'Proxy'. See the documentation for
 -- 'VG.indexM' for an explanation of why this is useful.
-indexM' :: forall n k a m. (KnownNat n, KnownNat k, Storable a, Monad m)
-      => Vector (n+k) a -> Proxy n -> m a
+indexM' :: forall n k a m p. (KnownNat n, KnownNat k, Storable a, Monad m)
+      => Vector (n+k) a -> p n -> m a
 indexM' = V.indexM'
 {-# inline indexM' #-}
 
@@ -311,7 +333,7 @@
 -- | /O(1)/ Yield the first element of a non-empty vector in a monad. See the
 -- documentation for 'VG.indexM' for an explanation of why this is useful.
 headM :: forall n a m. (KnownNat n, Storable a, Monad m)
-      => Vector (n+1) a -> m a
+      => Vector (1+n) a -> m a
 headM = V.headM
 {-# inline headM #-}
 
@@ -324,19 +346,19 @@
 
 -- | /O(1)/ Yield a slice of the vector without copying it with an inferred
 -- length argument.
-slice :: forall i n a. (KnownNat i, KnownNat n, Storable a)
-      => Proxy i -- ^ starting index
-      -> Vector (i+n) a
+slice :: forall i n m a p. (KnownNat i, KnownNat n, KnownNat m, Storable a)
+      => p i -- ^ starting index
+      -> Vector (i+n+m) a
       -> Vector n a
 slice = V.slice
 {-# inline slice #-}
 
 -- | /O(1)/ Yield a slice of the vector without copying it with an explicit
 -- length argument.
-slice' :: forall i n a. (KnownNat i, KnownNat n, Storable a)
-       => Proxy i -- ^ starting index
-       -> Proxy n -- ^ length
-       -> Vector (i+n) a
+slice' :: forall i n m a p. (KnownNat i, KnownNat n, KnownNat m, Storable a)
+       => p i -- ^ starting index
+       -> p n -- ^ length
+       -> Vector (i+n+m) a
        -> Vector n a
 slice' = V.slice'
 {-# inline slice' #-}
@@ -351,7 +373,7 @@
 -- | /O(1)/ Yield all but the first element of a non-empty vector without
 -- copying.
 tail :: forall n a. (Storable a)
-     => Vector (n+1) a -> Vector n a
+     => Vector (1+n) a -> Vector n a
 tail = V.tail
 {-# inline tail #-}
 
@@ -359,15 +381,15 @@
 -- this many elements. The length of the resultant vector is inferred from the
 -- type.
 take :: forall n m a. (KnownNat n, KnownNat m, Storable a)
-     => Vector (m+n) a -> Vector n a
+     => Vector (n+m) a -> Vector n a
 take = V.take
 {-# inline take #-}
 
 -- | /O(1)/ Yield the first n elements. The resultant vector always contains
 -- this many elements. The length of the resultant vector is given explicitly
 -- as a 'Proxy' argument.
-take' :: forall n m a. (KnownNat n, KnownNat m, Storable a)
-      => Proxy n -> Vector (m+n) a -> Vector n a
+take' :: forall n m a p. (KnownNat n, KnownNat m, Storable a)
+      => p n -> Vector (n+m) a -> Vector n a
 take' = V.take'
 {-# inline take' #-}
 
@@ -375,15 +397,15 @@
 -- contain at least this many elements The length of the resultant vector is
 -- inferred from the type.
 drop :: forall n m a. (KnownNat n, KnownNat m, Storable a)
-     => Vector (m+n) a -> Vector m a
+     => Vector (n+m) a -> Vector m a
 drop = V.drop
 {-# inline drop #-}
 
 -- | /O(1)/ Yield all but the the first n elements. The given vector must
 -- contain at least this many elements The length of the resultant vector is
 -- givel explicitly as a 'Proxy' argument.
-drop' :: forall n m a. (KnownNat n, KnownNat m, Storable a)
-      => Proxy n -> Vector (m+n) a -> Vector m a
+drop' :: forall n m a p. (KnownNat n, KnownNat m, Storable a)
+      => p n -> Vector (n+m) a -> Vector m a
 drop' = V.drop'
 {-# inline drop' #-}
 
@@ -397,8 +419,8 @@
 -- | /O(1)/ Yield the first n elements paired with the remainder without
 -- copying.  The length of the first resultant vector is passed explicitly as a
 -- 'Proxy' argument.
-splitAt' :: forall n m a. (KnownNat n, KnownNat m, Storable a)
-         => Proxy n -> Vector (n+m) a -> (Vector n a, Vector m a)
+splitAt' :: forall n m a p. (KnownNat n, KnownNat m, Storable a)
+         => p n -> Vector (n+m) a -> (Vector n a, Vector m a)
 splitAt' = V.splitAt'
 {-# inline splitAt' #-}
 
@@ -431,8 +453,8 @@
 
 -- | /O(n)/ Construct a vector with the same element in each position where the
 -- length is given explicitly as a 'Proxy' argument.
-replicate' :: forall n a. (KnownNat n, Storable a)
-           => Proxy n -> a -> Vector n a
+replicate' :: forall n a p. (KnownNat n, Storable a)
+           => p n -> a -> Vector n a
 replicate' = V.replicate'
 {-# inline replicate' #-}
 
@@ -445,8 +467,8 @@
 
 -- | /O(n)/ construct a vector of the given length by applying the function to
 -- each index where the length is given explicitly as a 'Proxy' argument.
-generate' :: forall n a. (KnownNat n, Storable a)
-          => Proxy n -> (Int -> a) -> Vector n a
+generate' :: forall n a p. (KnownNat n, Storable a)
+          => p n -> (Int -> a) -> Vector n a
 generate' = V.generate'
 {-# inline generate' #-}
 
@@ -469,8 +491,8 @@
 
 -- | /O(n)/ Apply function n times to value. Zeroth element is original value.
 -- The length is given explicitly as a 'Proxy' argument.
-iterateN' :: forall n a. (KnownNat n, Storable a)
-          => Proxy n -> (a -> a) -> a -> Vector n a
+iterateN' :: forall n a p. (KnownNat n, Storable a)
+          => p n -> (a -> a) -> a -> Vector n a
 iterateN' = V.iterateN'
 {-# inline iterateN' #-}
 
@@ -487,8 +509,8 @@
 
 -- | /O(n)/ Execute the monadic action @n@ times and store the results in a
 -- vector where @n@ is given explicitly as a 'Proxy' argument.
-replicateM' :: forall n m a. (KnownNat n, Storable a, Monad m)
-            => Proxy n -> m a -> m (Vector n a)
+replicateM' :: forall n m a p. (KnownNat n, Storable a, Monad m)
+            => p n -> m a -> m (Vector n a)
 replicateM' = V.replicateM'
 {-# inline replicateM' #-}
 
@@ -501,8 +523,8 @@
 
 -- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
 -- each index where n is given explicitly as a 'Proxy' argument.
-generateM' :: forall n m a. (KnownNat n, Storable a, Monad m)
-           => Proxy n -> (Int -> m a) -> m (Vector n a)
+generateM' :: forall n m a p. (KnownNat n, Storable a, Monad m)
+           => p n -> (Int -> m a) -> m (Vector n a)
 generateM' = V.generateM'
 {-# inline generateM' #-}
 
@@ -531,14 +553,14 @@
 -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
 -- the generator function to the a seed. The length, @n@, is given explicitly
 -- as a 'Proxy' argument.
-unfoldrN' :: forall n a b. (KnownNat n, Storable a)
-          => Proxy n -> (b -> (a, b)) -> b -> Vector n a
+unfoldrN' :: forall n a b p. (KnownNat n, Storable a)
+          => p n -> (b -> (a, b)) -> b -> Vector n a
 unfoldrN' = V.unfoldrN'
 {-# inline unfoldrN' #-}
 
 --
 -- ** Enumeration
--- 
+--
 
 -- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
 -- etc. The length, @n@, is inferred from the type.
@@ -549,8 +571,8 @@
 
 -- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
 -- etc. The length, @n@, is given explicitly as a 'Proxy' argument.
-enumFromN' :: forall n a. (KnownNat n, Storable a, Num a)
-           => a -> Proxy n -> Vector n a
+enumFromN' :: forall n a p. (KnownNat n, Storable a, Num a)
+           => a -> p n -> Vector n a
 enumFromN' = V.enumFromN'
 {-# inline enumFromN' #-}
 
@@ -563,8 +585,8 @@
 
 -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
 -- @x+y+y@ etc. The length, @n@, is given explicitly as a 'Proxy' argument.
-enumFromStepN' :: forall n a. (KnownNat n, Storable a, Num a)
-               => a -> a -> Proxy n -> Vector n a
+enumFromStepN' :: forall n a p. (KnownNat n, Storable a, Num a)
+               => a -> a -> p n -> Vector n a
 enumFromStepN' = V.enumFromStepN'
 {-# inline enumFromStepN' #-}
 
@@ -574,7 +596,7 @@
 
 -- | /O(n)/ Prepend an element.
 cons :: forall n a. Storable a
-     => a -> Vector n a -> Vector (n+1) a
+     => a -> Vector n a -> Vector (1+n) a
 cons = V.cons
 {-# inline cons #-}
 
@@ -896,7 +918,7 @@
          -> Vector n c
          -> Vector n d
          -> Vector n e
-zipWith4 = V.zipWith4 
+zipWith4 = V.zipWith4
 {-# inline zipWith4 #-}
 
 zipWith5 :: (Storable a,Storable b,Storable c,Storable d,Storable e,Storable f)
@@ -1128,7 +1150,7 @@
 {-# inline foldl #-}
 
 -- | /O(n)/ Left fold on non-empty vectors
-foldl1 :: (Storable a, KnownNat n) => (a -> a -> a) -> Vector (n+1) a -> a
+foldl1 :: (Storable a, KnownNat n) => (a -> a -> a) -> Vector (1+n) a -> a
 foldl1 = V.foldl1
 {-# inline foldl1 #-}
 
@@ -1138,7 +1160,7 @@
 {-# inline foldl' #-}
 
 -- | /O(n)/ Left fold on non-empty vectors with strict accumulator
-foldl1' :: (Storable a, KnownNat n) => (a -> a -> a) -> Vector (n+1) a -> a
+foldl1' :: (Storable a, KnownNat n) => (a -> a -> a) -> Vector (1+n) a -> a
 foldl1' = V.foldl1'
 {-# inline foldl1' #-}
 
@@ -1278,7 +1300,7 @@
 
 -- | /O(n)/ Monadic fold over non-empty vectors
 fold1M :: (Monad m, Storable a, KnownNat n)
-       => (a -> a -> m a) -> Vector (n+1) a -> m a
+       => (a -> a -> m a) -> Vector (1+n) a -> m a
 fold1M = V.fold1M
 {-# inline fold1M #-}
 
@@ -1468,8 +1490,8 @@
 
 -- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
 -- the resultant vector is given explicitly as a 'Proxy' argument.
-fromListN' :: forall n a. (Storable a, KnownNat n)
-           => Proxy n -> [a] -> Maybe (Vector n a)
+fromListN' :: forall n a p. (Storable a, KnownNat n)
+           => p n -> [a] -> Maybe (Vector n a)
 fromListN' = V.fromListN'
 {-# inline fromListN' #-}
 
diff --git a/vector-sized.cabal b/vector-sized.cabal
--- a/vector-sized.cabal
+++ b/vector-sized.cabal
@@ -1,5 +1,5 @@
 name:                vector-sized
-version:             0.5.1.0
+version:             0.6.1.0
 synopsis:            Size tagged vectors
 description:         Please see README.md
 homepage:            http://github.com/expipiplus1/vector-sized#readme
