diff --git a/Data/Vector/Fixed.hs b/Data/Vector/Fixed.hs
--- a/Data/Vector/Fixed.hs
+++ b/Data/Vector/Fixed.hs
@@ -1,10 +1,4 @@
-{-# LANGUAGE EmptyDataDecls        #-}
-{-# LANGUAGE TypeFamilies          #-}
-{-# LANGUAGE Rank2Types            #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE FlexibleContexts      #-}
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE ScopedTypeVariables   #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
 -- |
 -- Generic API for vectors with fixed length.
 --
@@ -46,13 +40,15 @@
     -- ** Functions
   , replicate
   , replicateM
-  , basis
   , generate
   , generateM
+  , unfoldr
+  , basis
     -- * Modifying vectors
     -- ** Transformations
   , head
   , tail
+  , (!)
     -- ** Comparison
   , eq
     -- ** Maps
@@ -93,9 +89,10 @@
   , VecList
   ) where
 
-import Data.Vector.Fixed.Internal
-import Data.Vector.Fixed.Cont     (VecList)
+import Data.Vector.Fixed.Internal.Arity
+import Data.Vector.Fixed.Cont     (VecList,Vector(..),VectorN,Dim,length)
 import qualified Data.Vector.Fixed.Cont as C
+import Data.Vector.Fixed.Internal
 
 import qualified Prelude as P
 import Prelude hiding ( replicate,map,zipWith,maximum,minimum,and,or,all,any
@@ -103,429 +100,31 @@
                       , head,tail,mapM,mapM_,sequence,sequence_
                       )
 
-
-
-----------------------------------------------------------------
--- Generic functions
-----------------------------------------------------------------
-
--- TODO: does not fuse!
-
--- | Generic function for construction of arbitrary vectors. It
---   represents partially constructed vector where /n/ is number of
---   uninitialized elements, /v/ is type of vector and /a/ element type.
---
---   Uninitialized vector could be obtained from 'con' and vector
---   elements could be added from left to right using '|>' operator.
---   Finally it could be converted to vector using 'vec' function.
---
---   Construction of complex number which could be seen as 2-element vector:
---
---   >>> import Data.Complex
---   >>> vec $ con |> 1 |> 3 :: Complex Double
---   1.0 :+ 3.0
-newtype New n v a = New (Fn n a (v a))
-
--- | Convert fully applied constructor to vector
-vec :: New Z v a -> v a
-{-# INLINE vec #-}
-vec (New v) = v
-
--- | Seed constructor
-con :: Vector v a => New (Dim v) v a
-{-# INLINE con #-}
-con = f2n construct
-
--- | Apply another element to vector
-(|>) :: New (S n) v a -> a -> New n v a
-{-# INLINE  (|>) #-}
-New f |> a = New (f a)
-infixl 1 |>
-
-f2n :: Fun n a (v a) -> New n v a
-{-# INLINE f2n #-}
-f2n (Fun f) = New f
-
-
-
-----------------------------------------------------------------
-
 -- $smallDim
 --
 -- Constructors for vectors with small dimensions.
 
-mk1 :: (Vector v a, Dim v ~ C.N1) => a -> v a
-mk1 a1 = C.vector $ C.mk1 a1
-{-# INLINE mk1 #-}
 
-mk2 :: (Vector v a, Dim v ~ C.N2) => a -> a -> v a
-mk2 a1 a2 = C.vector $ C.mk2 a1 a2
-{-# INLINE mk2 #-}
 
-mk3 :: (Vector v a, Dim v ~ C.N3) => a -> a -> a -> v a
-mk3 a1 a2 a3 = C.vector $ C.mk3 a1 a2 a3
-{-# INLINE mk3 #-}
-
-mk4 :: (Vector v a, Dim v ~ C.N4) => a -> a -> a -> a -> v a
-mk4 a1 a2 a3 a4 = C.vector $ C.mk4 a1 a2 a3 a4
-{-# INLINE mk4 #-}
-
-mk5 :: (Vector v a, Dim v ~ C.N5) => a -> a -> a -> a -> a -> v a
-mk5 a1 a2 a3 a4 a5 = C.vector $ C.mk5 a1 a2 a3 a4 a5
-{-# INLINE mk5 #-}
-
-
-
-----------------------------------------------------------------
-
--- | Replicate value /n/ times.
---
---   Examples:
---
---   >>> import Data.Vector.Fixed.Boxed (Vec2)
---   >>> replicate 1 :: Vec2 Int
---   fromList [1,1]
---
---   >>> replicate 2 :: (Double,Double,Double)
---   (2.0,2.0,2.0)
---
---   >>> import Data.Vector.Fixed.Boxed (Vec)
---   >>> replicate "foo" :: Vec N5 String
---   fromList ["foo","foo","foo","foo","foo"]
-replicate :: Vector v a => a -> v a
-{-# INLINE replicate #-}
-replicate
-  = C.vector . C.replicate
-
--- | Execute monadic action for every element of vector.
---
---   Examples:
---
---   >>> import Data.Vector.Fixed.Boxed (Vec2,Vec3)
---   >>> replicateM (Just 3) :: Maybe (Vec3 Int)
---   Just fromList [3,3,3]
---   >>> replicateM (putStrLn "Hi!") :: IO (Vec2 ())
---   Hi!
---   Hi!
---   fromList [(),()]
-replicateM :: (Vector v a, Monad m) => m a -> m (v a)
-{-# INLINE replicateM #-}
-replicateM
-  = C.vectorM . C.replicateM
-
-
-
-----------------------------------------------------------------
-
--- | Unit vector along Nth axis. If index is larger than vector
---   dimensions returns zero vector.
---
---   Examples:
---
---   >>> import Data.Vector.Fixed.Boxed (Vec3)
---   >>> basis 0 :: Vec3 Int
---   fromList [1,0,0]
---   >>> basis 1 :: Vec3 Int
---   fromList [0,1,0]
---   >>> basis 3 :: Vec3 Int
---   fromList [0,0,0]
-basis :: forall v a. (Vector v a, Num a) => Int -> v a
-{-# INLINE basis #-}
-basis = C.vector . C.basis
-
-
-
-----------------------------------------------------------------
-
--- | Generate vector from function which maps element's index to its
---   value.
---
---   Examples:
---
---   >>> import Data.Vector.Fixed.Unboxed (Vec)
---   >>> generate (^2) :: Vec N4 Int
---   fromList [0,1,4,9]
-generate :: forall v a. (Vector v a) => (Int -> a) -> v a
-{-# INLINE generate #-}
-generate = C.vector . C.generate
-
--- | Generate vector from monadic function which maps element's index
---   to its value.
-generateM :: forall m v a. (Monad m, Vector v a) => (Int -> m a) -> m (v a)
-{-# INLINE generateM #-}
-generateM = C.vectorM . C.generateM
-
-
-
-----------------------------------------------------------------
-
--- | First element of vector.
---
---   Examples:
---
---   >>> import Data.Vector.Fixed.Boxed (Vec3)
---   >>> let x = mk3 1 2 3 :: Vec3 Int
---   >>> head x
---   1
-head :: (Vector v a, Dim v ~ S n) => v a -> a
-{-# INLINE head #-}
-head = C.runContVec C.head . C.cvec
-
-
-----------------------------------------------------------------
-
--- | Tail of vector.
---
---   Examples:
---
---   >>> import Data.Complex
---   >>> tail (1,2,3) :: Complex Double
---   2.0 :+ 3.0
-tail :: (Vector v a, Vector w a, Dim v ~ S (Dim w))
-     => v a -> w a
-{-# INLINE tail #-}
-tail = C.vector . C.tail . C.cvec
-
-
-
-----------------------------------------------------------------
-
--- | Left fold over vector
-foldl :: Vector v a => (b -> a -> b) -> b -> v a -> b
-{-# INLINE foldl #-}
-foldl f x = C.runContVec (C.foldl f x)
-          . C.cvec
-
--- | Left fold over vector
-foldr :: Vector v a => (a -> b -> b) -> b -> v a -> b
-{-# INLINE foldr #-}
-foldr f x = C.runContVec (C.foldr f x)
-          . C.cvec
-
--- | Left fold over vector
-foldl1 :: (Vector v a, Dim v ~ S n) => (a -> a -> a) -> v a -> a
-{-# INLINE foldl1 #-}
-foldl1 f = C.runContVec (C.foldl1 f)
-         . C.cvec
-
--- | Left fold over vector
-ifoldr :: Vector v a => (Int -> a -> b -> b) -> b -> v a -> b
-{-# INLINE ifoldr #-}
-ifoldr f x = C.runContVec (C.ifoldr f x)
-           . C.cvec
-
--- | Left fold over vector. Function is applied to each element and
---   its index.
-ifoldl :: Vector v a => (b -> Int -> a -> b) -> b -> v a -> b
-{-# INLINE ifoldl #-}
-ifoldl f z = C.runContVec (C.ifoldl f z)
-           . C.cvec
-
--- | Monadic fold over vector.
-foldM :: (Vector v a, Monad m) => (b -> a -> m b) -> b -> v a -> m b
-{-# INLINE foldM #-}
-foldM f x v = foldl go (return x) v
-  where
-    go m a = do b <- m
-                f b a
-
--- | Left monadic fold over vector. Function is applied to each element and
---   its index.
-ifoldM :: (Vector v a, Monad m) => (b -> Int -> a -> m b) -> b -> v a -> m b
-{-# INLINE ifoldM #-}
-ifoldM f x v = ifoldl go (return x) v
-  where
-    go m i a = do { b <- m; f b i a }
-
-
-
-----------------------------------------------------------------
-
--- | Sum all elements in the vector.
-sum :: (Vector v a, Num a) => v a -> a
-sum = C.runContVec C.sum . C.cvec
-{-# INLINE sum #-}
-
--- | Maximal element of vector.
---
---   Examples:
---
---   >>> import Data.Vector.Fixed.Boxed (Vec3)
---   >>> let x = mk3 1 2 3 :: Vec3 Int
---   >>> maximum x
---   3
-maximum :: (Vector v a, Dim v ~ S n, Ord a) => v a -> a
-maximum = C.runContVec C.maximum . C.cvec
-{-# INLINE maximum #-}
-
--- | Minimal element of vector.
---
---   Examples:
---
---   >>> import Data.Vector.Fixed.Boxed (Vec3)
---   >>> let x = mk3 1 2 3 :: Vec3 Int
---   >>> minimum x
---   1
-minimum :: (Vector v a, Dim v ~ S n, Ord a) => v a -> a
-minimum = C.runContVec C.minimum . C.cvec
-{-# INLINE minimum #-}
-
--- | Conjunction of all elements of a vector.
-and :: (Vector v Bool) => v Bool -> Bool
-and = C.runContVec C.and . C.cvec
-{-# INLINE and #-}
-
--- | Disjunction of all elements of a vector.
-or :: (Vector v Bool) => v Bool -> Bool
-or = C.runContVec C.or . C.cvec
-{-# INLINE or #-}
-
--- | Determines whether all elements of vector satisfy predicate.
-all :: (Vector v a) => (a -> Bool) -> v a -> Bool
-all f = C.runContVec (C.all f) . C.cvec
-{-# INLINE all #-}
-
--- | Determines whether any of element of vector satisfy predicate.
-any :: (Vector v a) => (a -> Bool) -> v a -> Bool
-any f = C.runContVec (C.any f) . C.cvec
-{-# INLINE any #-}
-
-
-----------------------------------------------------------------
-
--- | Test two vectors for equality.
+--------------------------------------------------------------------------------
+-- We are trying to be clever with indexing here. It's not possible to
+-- write generic indexing function. For example it's necessary O(n)
+-- for VecList. It's however possible to write O(1) indexing for some
+-- vectors and we trying to use such functions where possible.
 --
---   Examples:
+-- We try to use presumable more efficient basicIndex
 --
---   >>> import Data.Vector.Fixed.Boxed (Vec2)
---   >>> let v0 = basis 0 :: Vec2 Int
---   >>> let v1 = basis 1 :: Vec2 Int
---   >>> v0 `eq` v0
---   True
---   >>> v0 `eq` v1
---   False
-eq :: (Vector v a, Eq a) => v a -> v a -> Bool
-{-# INLINE eq #-}
-eq v w = C.runContVec (C.foldl (&&) True)
-       $ C.zipWith (==) (C.cvec v) (C.cvec w)
-
-
-----------------------------------------------------------------
-
--- | Map over vector
-map :: (Vector v a, Vector v b) => (a -> b) -> v a -> v b
-{-# INLINE map #-}
-map f = C.vector
-      . C.map f
-      . C.cvec
-
--- | Evaluate every action in the vector from left to right.
-sequence :: (Vector v a, Vector v (m a), Monad m) => v (m a) -> m (v a)
-{-# INLINE sequence #-}
-sequence = mapM id
-
--- | Evaluate every action in the vector from left to right and ignore result
-sequence_ :: (Vector v (m a), Monad m) => v (m a) -> m ()
-{-# INLINE sequence_ #-}
-sequence_ = mapM_ id
-
-
--- | Monadic map over vector.
-mapM :: (Vector v a, Vector v b, Monad m) => (a -> m b) -> v a -> m (v b)
-{-# INLINE mapM #-}
-mapM f = C.vectorM
-       . C.mapM f
-       . C.cvec
-
--- | Apply monadic action to each element of vector and ignore result.
-mapM_ :: (Vector v a, Monad m) => (a -> m b) -> v a -> m ()
-{-# INLINE mapM_ #-}
-mapM_ f = foldl (\m a -> m >> f a >> return ()) (return ())
-
-
--- | Apply function to every element of the vector and its index.
-imap :: (Vector v a, Vector v b) =>
-    (Int -> a -> b) -> v a -> v b
-{-# INLINE imap #-}
-imap f = C.vector
-       . C.imap f
-       . C.cvec
-
--- | Apply monadic function to every element of the vector and its index.
-imapM :: (Vector v a, Vector v b, Monad m) =>
-    (Int -> a -> m b) -> v a -> m (v b)
-{-# INLINE imapM #-}
-imapM f = C.vectorM
-        . C.imapM f
-        . C.cvec
-
--- | Apply monadic function to every element of the vector and its
---   index and discard result.
-imapM_ :: (Vector v a, Monad m) => (Int -> a -> m b) -> v a -> m ()
-{-# INLINE imapM_ #-}
-imapM_ f = ifoldl (\m i a -> m >> f i a >> return ()) (return ())
-
-
-----------------------------------------------------------------
-
--- | Zip two vector together using function.
+--  1. It should not interfere with deforestation. So we should
+--     rewrite only when deforestation rule already fired.
+--     (starting from phase 1).
 --
---   Examples:
+--  2. Creation of vector is costlier than generic indexing so we should
+--     apply rule only when vector is created anyway
 --
---   >>> import Data.Vector.Fixed.Boxed (Vec3)
---   >>> let b0 = basis 0 :: Vec3 Int
---   >>> let b1 = basis 1 :: Vec3 Int
---   >>> let b2 = basis 2 :: Vec3 Int
---   >>> let vplus x y = zipWith (+) x y
---   >>> vplus b0 b1
---   fromList [1,1,0]
---   >>> vplus b0 b2
---   fromList [1,0,1]
---   >>> vplus b1 b2
---   fromList [0,1,1]
-zipWith :: (Vector v a, Vector v b, Vector v c)
-        => (a -> b -> c) -> v a -> v b -> v c
-{-# INLINE zipWith #-}
-zipWith f v u = C.vector
-              $ C.zipWith f (C.cvec v) (C.cvec u)
-
--- | Zip two vector together using monadic function.
-zipWithM :: (Vector v a, Vector v b, Vector v c, Monad m)
-         => (a -> b -> m c) -> v a -> v b -> m (v c)
-{-# INLINE zipWithM #-}
-zipWithM f v u = C.vectorM
-               $ C.zipWithM f (C.cvec v) (C.cvec u)
-
--- | Zip two vector together using function which takes element index
---   as well.
-izipWith :: (Vector v a, Vector v b, Vector v c)
-         => (Int -> a -> b -> c) -> v a -> v b -> v c
-{-# INLINE izipWith #-}
-izipWith f v u = C.vector
-               $ C.izipWith f (C.cvec v) (C.cvec u)
-
--- | Zip two vector together using monadic function which takes element
---   index as well..
-izipWithM :: (Vector v a, Vector v b, Vector v c, Monad m)
-          => (Int -> a -> b -> m c) -> v a -> v b -> m (v c)
-{-# INLINE izipWithM #-}
-izipWithM f v u = C.vectorM
-                $ C.izipWithM f (C.cvec v) (C.cvec u)
-
-
-----------------------------------------------------------------
-
--- | Convert between different vector types
-convert :: (Vector v a, Vector w a, Dim v ~ Dim w) => v a -> w a
-{-# INLINE convert #-}
-convert = C.vector . C.cvec
-
--- | Convert vector to the list
-toList :: (Vector v a) => v a -> [a]
-toList = foldr (:) []
+-- In order to avoid firing this rule on implementation of (!) it has
+-- been necessary to move definition of all functions to internal module.
 
--- | Create vector form list. Will throw error if list is shorter than
---   resulting vector.
-fromList :: (Vector v a) => [a] -> v a
-{-# INLINE fromList #-}
-fromList = C.vector . C.fromList
+{-# RULES
+"fixed-vector:index/basicIndex"[1] forall vv i.
+  runIndex i (C.cvec vv) = C.basicIndex vv i
+ #-}
diff --git a/Data/Vector/Fixed/Boxed.hs b/Data/Vector/Fixed/Boxed.hs
--- a/Data/Vector/Fixed/Boxed.hs
+++ b/Data/Vector/Fixed/Boxed.hs
@@ -18,7 +18,7 @@
 import Prelude hiding (length,replicate,zipWith,map,foldl)
 
 import Data.Vector.Fixed
-import Data.Vector.Fixed.Internal
+import Data.Vector.Fixed.Internal.Arity
 import Data.Vector.Fixed.Mutable
 
 
@@ -78,10 +78,12 @@
 type instance DimM (MVec n) = n
 
 instance (Arity n) => Vector (Vec n) a where
-  construct = constructVec
-  inspect   = inspectVec
-  {-# INLINE construct #-}
-  {-# INLINE inspect   #-}
+  construct  = constructVec
+  inspect    = inspectVec
+  basicIndex = index
+  {-# INLINE construct  #-}
+  {-# INLINE inspect    #-}
+  {-# INLINE basicIndex #-}
 instance (Arity n) => VectorN Vec n a
 
 instance (Arity n, Eq a) => Eq (Vec n a) where
diff --git a/Data/Vector/Fixed/Cont.hs b/Data/Vector/Fixed/Cont.hs
--- a/Data/Vector/Fixed/Cont.hs
+++ b/Data/Vector/Fixed/Cont.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE NoMonomorphismRestriction #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE FlexibleInstances     #-}
 {-# LANGUAGE FlexibleContexts      #-}
@@ -8,8 +7,13 @@
 -- |
 -- Continuations-based API
 module Data.Vector.Fixed.Cont (
+    -- * Vector type class
+    Dim
+  , Vector(..)
+  , VectorN
+  , length
     -- * Vector as continuation
-    ContVecT
+  , ContVecT
   , ContVec
     -- ** Synonyms for small numerals
   , N1
@@ -25,6 +29,7 @@
   , replicateM
   , generate
   , generateM
+  , unfoldr
   , basis
     -- ** Constructors
   , mk1
@@ -39,6 +44,7 @@
   , imapM
   , tail
   , cons
+  , changeMonad
     -- ** Zips
   , zipWith
   , izipWith
@@ -51,6 +57,7 @@
   , runContVec
     -- ** Getters
   , head
+  , index
     -- ** Vector construction
   , vector
   , vectorM
@@ -75,13 +82,49 @@
   ) where
 
 import Control.Applicative
-import Data.Vector.Fixed.Internal
+import Data.Complex (Complex(..))
+import Data.Vector.Fixed.Internal.Arity
+import Data.Vector.Fixed.Internal.Id
 import Prelude hiding ( replicate,map,zipWith,maximum,minimum,and,or,any,all
                       , foldl,foldr,foldl1,length,sum
                       , head,tail,mapM,mapM_,sequence,sequence_
                       )
 
+
 ----------------------------------------------------------------
+-- Type class for fixed vectors
+----------------------------------------------------------------
+
+-- | Size of vector expressed as type-level natural.
+type family Dim (v :: * -> *)
+
+-- | Type class for vectors with fixed length.
+class Arity (Dim v) => Vector v a where
+  -- | N-ary function for creation of vectors.
+  construct :: Fun (Dim v) a (v a)
+  -- | Deconstruction of vector.
+  inspect   :: v a -> Fun (Dim v) a b -> b
+  -- | Optional more efficient implementation of indexing. Shouldn't
+  --   be used directly, use 'Data.Vector.Fixed.!' instead.
+  basicIndex :: v a -> Int -> a
+  basicIndex v i = runContVec (index i) (cvec v)
+  {-# INLINE basicIndex #-}
+
+-- | Vector parametrized by length. In ideal world it should be:
+--
+-- > forall n. (Arity n, Vector (v n) a, Dim (v n) ~ n) => VectorN v a
+--
+-- Alas polymorphic constraints aren't allowed in haskell.
+class (Vector (v n) a, Dim (v n) ~ n) => VectorN v n a
+
+-- | Length of vector. Function doesn't evaluate its argument.
+length :: forall v a. Arity (Dim v) => v a -> Int
+{-# INLINE length #-}
+length _ = arity (undefined :: Dim v)
+
+
+
+----------------------------------------------------------------
 -- Cont. vectors and their instances
 ----------------------------------------------------------------
 
@@ -101,8 +144,25 @@
   {-# INLINE pure  #-}
   {-# INLINE (<*>) #-}
 
+-- | Change monad type for the continuation vector.
+changeMonad :: (Monad p, Monad m, Arity n)
+            => (forall x. p x -> x) -- ^ Function to extract result from monad
+            -> ContVecT p n a -> ContVecT m n a
+{-# INLINE changeMonad #-}
+changeMonad run (ContVecT cont)
+  = ContVecT $ convertCont run return cont
 
+convertCont :: (Arity n)
+            => (b -> c)
+            -> (c -> b)
+            -> (Fun n a b -> b)
+            -> (Fun n a c -> c)
+{-# INLINE convertCont #-}
+convertCont fB2C fC2B cont = \funC ->
+  fB2C $ cont (fmap fC2B funC)
 
+
+
 ----------------------------------------------------------------
 -- Construction
 ----------------------------------------------------------------
@@ -110,7 +170,7 @@
 -- | Convert regular vector to continuation
 cvec :: (Vector v a, Dim v ~ n, Monad m) => v a -> ContVecT m n a
 cvec v = ContVecT (inspect v)
-{-# INLINE[1] cvec #-}
+{-# INLINE[0] cvec #-}
 
 -- | Convert list to continuation-based vector. Will throw error if
 --   list is shorter than resulting vector.
@@ -147,6 +207,7 @@
 
 data T_replicate n = T_replicate
 
+
 -- | Generate vector from function which maps element's index to its value.
 generate :: forall m n a. (Arity n) => (Int -> a) -> ContVecT m n a
 {-# INLINE generate #-}
@@ -167,6 +228,17 @@
 
 newtype T_generate n = T_generate Int
 
+-- | Unfold vector.
+unfoldr :: forall m n b a. Arity n => (b -> (a,b)) -> b -> ContVecT m n a
+{-# INLINE unfoldr #-}
+unfoldr f b0 = ContVecT $ \(Fun fun) ->
+  apply (\(T_unfoldr b) -> let (a,b') = f b in (a, T_unfoldr b'))
+        (T_unfoldr b0 :: T_unfoldr b n)
+         fun
+
+newtype T_unfoldr b n = T_unfoldr b
+
+
 -- | Unit vector along Nth axis.
 basis :: forall m n a. (Num a, Arity n) => Int -> ContVecT m n a
 {-# INLINE basis #-}
@@ -361,11 +433,6 @@
 vectorM = runContVecT construct
 {-# INLINE[1] vectorM #-}
 
-{-# RULES "cvec/vector"
-   forall x. cvec (vector x) = x
-  #-}
-
-
 -- | Finalizer function for getting head of the vector.
 head :: forall n a. Arity (S n) => Fun (S n) a a
 {-# INLINE head #-}
@@ -375,7 +442,25 @@
 
 data T_head a n = T_head (Maybe a)
 
+-- | /O(n)/ Get value at specified index.
+index :: forall n a. Arity n => Int -> Fun n a a
+index n
+  | n < 0     = error "Data.Vector.Fixed.Cont.index: index out of range"
+  | otherwise = Fun $ accum
+     (\(T_Index x) a -> T_Index $ case x of
+                          Left  0 -> Right a
+                          Left  i -> Left (i - 1)
+                          r       -> r
+     )
+     (\(T_Index x) -> case x of
+                        Left  _ -> error "Data.Vector.Fixed.index: index out of range"
+                        Right a -> a
+     )
+     ( T_Index (Left n) :: T_Index a n)
 
+newtype T_Index a n = T_Index (Either Int a)
+
+
 -- | Left fold over continuation vector.
 foldl :: forall n a b. Arity n
       => (b -> a -> b) -> b -> Fun n a b
@@ -480,6 +565,37 @@
 
 
 ----------------------------------------------------------------
+-- Deforestation
+----------------------------------------------------------------
+
+-- Deforestation uses following assertion: if we convert continuation
+-- to vector and immediately back to the continuation we can eliminate
+-- intermediate vector. This optimization can however turn
+-- nonterminating programs into terminating.
+--
+-- > runContVec head $ cvec $ vector $ mk2 () ⊥
+--
+-- If intermediate vector is strict in its elements expression above
+-- evaluates to ⊥ too. But if we apply rewrite rule resuling expression:
+--
+-- > runContVec head $ mk2 () ⊥
+--
+-- will evaluate to () since ContVec is not strict in its elements.
+-- It has been considered acceptable.
+--
+--
+-- In order to get rule fire reliably (it still doesn't). `vector' in
+-- inlined starting from phase 1. `cvec' is inlined even later (only
+-- during phase 0) because it need to participate in rewriting of
+-- indexing functions.
+
+
+{-# RULES
+"cvec/vector" forall v.
+  cvec (vector v) = changeMonad runID v
+  #-}
+
+----------------------------------------------------------------
 -- VecList
 ----------------------------------------------------------------
 
@@ -508,3 +624,55 @@
   {-# INLINE construct #-}
   {-# INLINE inspect   #-}
 instance Arity n => VectorN VecList n a
+
+----------------------------------------------------------------
+-- Instances
+----------------------------------------------------------------
+
+type instance Dim Complex = N2
+
+instance RealFloat a => Vector Complex a where
+  construct = Fun (:+)
+  inspect (x :+ y) (Fun f) = f x y
+
+
+type instance Dim ((,) a) = N2
+
+instance (b~a) => Vector ((,) b) a where
+  construct = Fun (,)
+  inspect (a,b) (Fun f) = f a b
+
+
+type instance Dim ((,,) a b) = N3
+
+instance (b~a, c~a) => Vector ((,,) b c) a where
+  construct = Fun (,,)
+  inspect (a,b,c) (Fun f) = f a b c
+
+
+type instance Dim ((,,,) a b c) = N4
+
+instance (b~a, c~a, d~a) => Vector ((,,,) b c d) a where
+  construct = Fun (,,,)
+  inspect (a,b,c,d) (Fun f) = f a b c d
+
+
+type instance Dim ((,,,,) a b c d) = N5
+
+instance (b~a, c~a, d~a, e~a) => Vector ((,,,,) b c d e) a where
+  construct = Fun (,,,,)
+  inspect (a,b,c,d,e) (Fun f) = f a b c d e
+
+
+type instance Dim ((,,,,,) a b c d e) = N6
+
+instance (b~a, c~a, d~a, e~a, f~a) => Vector ((,,,,,) b c d e f) a where
+  construct = Fun (,,,,,)
+  inspect (a,b,c,d,e,f) (Fun fun) = fun a b c d e f
+
+
+type instance Dim ((,,,,,,) a b c d e f) = S N6
+
+instance (b~a, c~a, d~a, e~a, f~a, g~a) => Vector ((,,,,,,) b c d e f g) a where
+  construct = Fun (,,,,,,)
+  inspect (a,b,c,d,e,f,g) (Fun fun) = fun a b c d e f g
diff --git a/Data/Vector/Fixed/Internal.hs b/Data/Vector/Fixed/Internal.hs
--- a/Data/Vector/Fixed/Internal.hs
+++ b/Data/Vector/Fixed/Internal.hs
@@ -1,213 +1,447 @@
-{-# LANGUAGE EmptyDataDecls        #-}
 {-# LANGUAGE TypeFamilies          #-}
 {-# LANGUAGE Rank2Types            #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE FlexibleContexts      #-}
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE ScopedTypeVariables   #-}
 -- |
--- Type classes for generic vectors. This module exposes type classes
--- and auxiliary functions needed to write generic functions not
--- present in the module "Data.Vector.Fixed".
---
--- Implementation is based on
--- <http://unlines.wordpress.com/2010/11/15/generics-for-small-fixed-size-vectors/>
-module Data.Vector.Fixed.Internal (
-    -- * Type-level naturals
-    Z
-  , S
-    -- ** Synonyms for small numerals
-  , N1
-  , N2
-  , N3
-  , N4
-  , N5
-  , N6
-    -- * N-ary functions
-  , Fn
-  , Fun(..)
-  , Arity(..)
-    -- * Vector type class
-  , Dim
-  , Vector(..)
-  , VectorN
-  , length
-  , Id(..)
-  ) where
+-- Implementation of fixed-vectors
+module Data.Vector.Fixed.Internal where
 
-import Data.Complex
-import Prelude hiding (length)
+import Data.Vector.Fixed.Internal.Arity
+import Data.Vector.Fixed.Cont     (Vector(..),Dim)
+import qualified Data.Vector.Fixed.Cont as C
 
+import qualified Prelude as P
+import Prelude hiding ( replicate,map,zipWith,maximum,minimum,and,or,all,any
+                      , foldl,foldr,foldl1,length,sum
+                      , head,tail,mapM,mapM_,sequence,sequence_
+                      )
 
+
+
 ----------------------------------------------------------------
--- Naturals
+-- Generic functions
 ----------------------------------------------------------------
 
--- | Type level zero
-data Z
--- | Successor of n
-data S n
+-- TODO: does not fuse!
 
-type N1 = S Z
-type N2 = S N1
-type N3 = S N2
-type N4 = S N3
-type N5 = S N4
-type N6 = S N5
+-- | Generic function for construction of arbitrary vectors. It
+--   represents partially constructed vector where /n/ is number of
+--   uninitialized elements, /v/ is type of vector and /a/ element type.
+--
+--   Uninitialized vector could be obtained from 'con' and vector
+--   elements could be added from left to right using '|>' operator.
+--   Finally it could be converted to vector using 'vec' function.
+--
+--   Construction of complex number which could be seen as 2-element vector:
+--
+--   >>> import Data.Complex
+--   >>> vec $ con |> 1 |> 3 :: Complex Double
+--   1.0 :+ 3.0
+newtype New n v a = New (Fn n a (v a))
 
+-- | Convert fully applied constructor to vector
+vec :: New Z v a -> v a
+{-# INLINE vec #-}
+vec (New v) = v
+
+-- | Seed constructor
+con :: Vector v a => New (Dim v) v a
+{-# INLINE con #-}
+con = f2n construct
+
+-- | Apply another element to vector
+(|>) :: New (S n) v a -> a -> New n v a
+{-# INLINE  (|>) #-}
+New f |> a = New (f a)
+infixl 1 |>
+
+f2n :: Fun n a (v a) -> New n v a
+{-# INLINE f2n #-}
+f2n (Fun f) = New f
+
+
+
 ----------------------------------------------------------------
--- N-ary functions
+
+mk1 :: (Vector v a, Dim v ~ C.N1) => a -> v a
+mk1 a1 = C.vector $ C.mk1 a1
+{-# INLINE mk1 #-}
+
+mk2 :: (Vector v a, Dim v ~ C.N2) => a -> a -> v a
+mk2 a1 a2 = C.vector $ C.mk2 a1 a2
+{-# INLINE mk2 #-}
+
+mk3 :: (Vector v a, Dim v ~ C.N3) => a -> a -> a -> v a
+mk3 a1 a2 a3 = C.vector $ C.mk3 a1 a2 a3
+{-# INLINE mk3 #-}
+
+mk4 :: (Vector v a, Dim v ~ C.N4) => a -> a -> a -> a -> v a
+mk4 a1 a2 a3 a4 = C.vector $ C.mk4 a1 a2 a3 a4
+{-# INLINE mk4 #-}
+
+mk5 :: (Vector v a, Dim v ~ C.N5) => a -> a -> a -> a -> a -> v a
+mk5 a1 a2 a3 a4 a5 = C.vector $ C.mk5 a1 a2 a3 a4 a5
+{-# INLINE mk5 #-}
+
+
+
 ----------------------------------------------------------------
 
--- | Type family for n-ary functions.
-type family   Fn n a b
-type instance Fn Z     a b = b
-type instance Fn (S n) a b = a -> Fn n a b
+-- | Replicate value /n/ times.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec2)
+--   >>> replicate 1 :: Vec2 Int
+--   fromList [1,1]
+--
+--   >>> replicate 2 :: (Double,Double,Double)
+--   (2.0,2.0,2.0)
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec)
+--   >>> replicate "foo" :: Vec N5 String
+--   fromList ["foo","foo","foo","foo","foo"]
+replicate :: Vector v a => a -> v a
+{-# INLINE replicate #-}
+replicate
+  = C.vector . C.replicate
 
--- | Newtype wrapper which is used to make 'Fn' injective.
-newtype Fun n a b = Fun (Fn n a b)
 
-newtype T_fmap a b n = T_fmap (Fn n a b)
+-- | Execute monadic action for every element of vector.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec2,Vec3)
+--   >>> replicateM (Just 3) :: Maybe (Vec3 Int)
+--   Just fromList [3,3,3]
+--   >>> replicateM (putStrLn "Hi!") :: IO (Vec2 ())
+--   Hi!
+--   Hi!
+--   fromList [(),()]
+replicateM :: (Vector v a, Monad m) => m a -> m (v a)
+{-# INLINE replicateM #-}
+replicateM
+  = C.vectorM . C.replicateM
 
-instance Arity n => Functor (Fun n a) where
-  fmap (f :: b -> c) (Fun g0 :: Fun n a b)
-     = Fun $ accum
-             (\(T_fmap g) a -> T_fmap (g a))
-             (\(T_fmap x) -> f x)
-             (T_fmap g0 :: T_fmap a b n)
-  {-# INLINE fmap #-}
 
+-- | Unit vector along Nth axis. If index is larger than vector
+--   dimensions returns zero vector.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec3)
+--   >>> basis 0 :: Vec3 Int
+--   fromList [1,0,0]
+--   >>> basis 1 :: Vec3 Int
+--   fromList [0,1,0]
+--   >>> basis 3 :: Vec3 Int
+--   fromList [0,0,0]
+basis :: (Vector v a, Num a) => Int -> v a
+{-# INLINE basis #-}
+basis = C.vector . C.basis
 
--- | Type class for handling /n/-ary functions.
-class Arity n where
-  -- | Left fold over /n/ elements exposed as n-ary function.
-  accum :: (forall k. t (S k) -> a -> t k) -- ^ Fold function
-        -> (t Z -> b)                      -- ^ Extract result of fold
-        -> t n                             -- ^ Initial value
-        -> Fn n a b                        -- ^ Reduction function
 
-  -- | Monadic left fold.
-  accumM :: Monad m
-         => (forall k. t (S k) -> a -> m (t k)) -- ^ Fold function
-         -> (t Z -> m b)                        -- ^ Extract result of fold
-         -> m (t n)                             -- ^ Initial value
-         -> Fn n a (m b)                        -- ^ Reduction function
+-- | Unfold vector.
+unfoldr :: (Vector v a) => (b -> (a,b)) -> b -> v a
+{-# INLINE unfoldr #-}
+unfoldr f = C.vector . C.unfoldr f
 
-  -- | Apply all parameters to the function.
-  apply :: (forall k. t (S k) -> (a, t k)) -- ^ Get value to apply to function
-        -> t n                             -- ^ Initial value
-        -> Fn n a b                        -- ^ N-ary function
-        -> b
 
-  -- | Monadic apply
-  applyM :: Monad m
-         => (forall k. t (S k) -> m (a, t k)) -- ^ Get value to apply to function
-         -> t n                               -- ^ Initial value
-         -> Fn n a (m b)                      -- ^ N-ary function
-         -> m b
-  -- | Arity of function.
-  arity :: n -> Int
+-- | Generate vector from function which maps element's index to its
+--   value.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Unboxed (Vec)
+--   >>> generate (^2) :: Vec N4 Int
+--   fromList [0,1,4,9]
+generate :: (Vector v a) => (Int -> a) -> v a
+{-# INLINE generate #-}
+generate = C.vector . C.generate
 
-instance Arity Z where
-  accum  _ g t = g t
-  accumM _ g t = g =<< t
-  apply  _ _ h = h
-  applyM _ _ h = h
-  arity  _ = 0
-  {-# INLINE accum  #-}
-  {-# INLINE accumM #-}
-  {-# INLINE apply  #-}
-  {-# INLINE arity  #-}
 
-instance Arity n => Arity (S n) where
-  accum  f g t = \a -> accum  f g (f t a)
-  accumM f g t = \a -> accumM f g $ flip f a =<< t
-  apply  f t h = case f t of (a,u) -> apply f u (h a)
-  applyM f t h = do (a,u) <- f t
-                    applyM f u (h a)
-  arity  n = 1 + arity (prevN n)
-    where
-      prevN :: S n -> n
-      prevN _ = undefined
-  {-# INLINE accum  #-}
-  {-# INLINE accumM #-}
-  {-# INLINE apply  #-}
-  {-# INLINE arity  #-}
+-- | Generate vector from monadic function which maps element's index
+--   to its value.
+generateM :: (Monad m, Vector v a) => (Int -> m a) -> m (v a)
+{-# INLINE generateM #-}
+generateM = C.vectorM . C.generateM
 
 
 
 ----------------------------------------------------------------
--- Type class for vectors
-----------------------------------------------------------------
 
--- | Size of vector expressed as type-level natural.
-type family Dim (v :: * -> *)
+-- | First element of vector.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec3)
+--   >>> let x = mk3 1 2 3 :: Vec3 Int
+--   >>> head x
+--   1
+head :: (Vector v a, Dim v ~ S n) => v a -> a
+{-# INLINE head #-}
+head = C.runContVec C.head . C.cvec
 
--- | Type class for vectors with fixed length.
-class Arity (Dim v) => Vector v a where
-  -- | N-ary function for creation of vectors.
-  construct :: Fun (Dim v) a (v a)
-  -- | Deconstruction of vector.
-  inspect   :: v a -> Fun (Dim v) a b -> b
 
--- | Vector parametrized by length. In ideal world it should be:
+-- | Tail of vector.
 --
--- > forall n. (Arity n, Vector (v n) a, Dim (v n) ~ n) => VectorN v a
+--   Examples:
 --
--- Alas polymorphic constraints aren't allowed in haskell.
-class (Vector (v n) a, Dim (v n) ~ n) => VectorN v n a
+--   >>> import Data.Complex
+--   >>> tail (1,2,3) :: Complex Double
+--   2.0 :+ 3.0
+tail :: (Vector v a, Vector w a, Dim v ~ S (Dim w))
+     => v a -> w a
+{-# INLINE tail #-}
+tail = C.vector . C.tail . C.cvec
 
--- | Length of vector. Function doesn't evaluate its argument.
-length :: forall v a. Arity (Dim v) => v a -> Int
-{-# INLINE length #-}
-length _ = arity (undefined :: Dim v)
+-- | Retrieve vector's element at index. Generic implementation is
+--   /O(n)/ but more efficient one is used when possible.
+(!) :: (Vector v a) => v a -> Int -> a
+{-# INLINE (!) #-}
+v ! n = runIndex n (C.cvec v)
 
+-- Used in rewriting of index function.
+runIndex :: Arity n => Int -> C.ContVec n r -> r
+runIndex n = C.runContVec (C.index n)
+{-# INLINE[0] runIndex #-}
 
--- | Strict identity monad
-newtype Id a = Id { runID :: a }
+-- | Left fold over vector
+foldl :: Vector v a => (b -> a -> b) -> b -> v a -> b
+{-# INLINE foldl #-}
+foldl f x = C.runContVec (C.foldl f x)
+          . C.cvec
 
-instance Monad Id where
-  return     = Id
-  Id a >>= f = f a
-  {-# INLINE return #-}
-  {-# INLINE (>>=)  #-}
+-- | Left fold over vector
+foldr :: Vector v a => (a -> b -> b) -> b -> v a -> b
+{-# INLINE foldr #-}
+foldr f x = C.runContVec (C.foldr f x)
+          . C.cvec
 
 
+-- | Left fold over vector
+foldl1 :: (Vector v a, Dim v ~ S n) => (a -> a -> a) -> v a -> a
+{-# INLINE foldl1 #-}
+foldl1 f = C.runContVec (C.foldl1 f)
+         . C.cvec
 
+-- | Left fold over vector
+ifoldr :: Vector v a => (Int -> a -> b -> b) -> b -> v a -> b
+{-# INLINE ifoldr #-}
+ifoldr f x = C.runContVec (C.ifoldr f x)
+           . C.cvec
+
+-- | Left fold over vector. Function is applied to each element and
+--   its index.
+ifoldl :: Vector v a => (b -> Int -> a -> b) -> b -> v a -> b
+{-# INLINE ifoldl #-}
+ifoldl f z = C.runContVec (C.ifoldl f z)
+           . C.cvec
+
+-- | Monadic fold over vector.
+foldM :: (Vector v a, Monad m) => (b -> a -> m b) -> b -> v a -> m b
+{-# INLINE foldM #-}
+foldM f x v = foldl go (return x) v
+  where
+    go m a = do b <- m
+                f b a
+
+-- | Left monadic fold over vector. Function is applied to each element and
+--   its index.
+ifoldM :: (Vector v a, Monad m) => (b -> Int -> a -> m b) -> b -> v a -> m b
+{-# INLINE ifoldM #-}
+ifoldM f x v = ifoldl go (return x) v
+  where
+    go m i a = do { b <- m; f b i a }
+
+
+
 ----------------------------------------------------------------
--- Instances
+
+-- | Sum all elements in the vector.
+sum :: (Vector v a, Num a) => v a -> a
+sum = C.runContVec C.sum . C.cvec
+{-# INLINE sum #-}
+
+-- | Maximal element of vector.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec3)
+--   >>> let x = mk3 1 2 3 :: Vec3 Int
+--   >>> maximum x
+--   3
+maximum :: (Vector v a, Dim v ~ S n, Ord a) => v a -> a
+maximum = C.runContVec C.maximum . C.cvec
+{-# INLINE maximum #-}
+
+-- | Minimal element of vector.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec3)
+--   >>> let x = mk3 1 2 3 :: Vec3 Int
+--   >>> minimum x
+--   1
+minimum :: (Vector v a, Dim v ~ S n, Ord a) => v a -> a
+minimum = C.runContVec C.minimum . C.cvec
+{-# INLINE minimum #-}
+
+-- | Conjunction of all elements of a vector.
+and :: (Vector v Bool) => v Bool -> Bool
+and = C.runContVec C.and . C.cvec
+{-# INLINE and #-}
+
+-- | Disjunction of all elements of a vector.
+or :: (Vector v Bool) => v Bool -> Bool
+or = C.runContVec C.or . C.cvec
+{-# INLINE or #-}
+
+-- | Determines whether all elements of vector satisfy predicate.
+all :: (Vector v a) => (a -> Bool) -> v a -> Bool
+all f = C.runContVec (C.all f) . C.cvec
+{-# INLINE all #-}
+
+-- | Determines whether any of element of vector satisfy predicate.
+any :: (Vector v a) => (a -> Bool) -> v a -> Bool
+any f = C.runContVec (C.any f) . C.cvec
+{-# INLINE any #-}
+
+
 ----------------------------------------------------------------
 
-type instance Dim Complex = N2
+-- | Test two vectors for equality.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec2)
+--   >>> let v0 = basis 0 :: Vec2 Int
+--   >>> let v1 = basis 1 :: Vec2 Int
+--   >>> v0 `eq` v0
+--   True
+--   >>> v0 `eq` v1
+--   False
+eq :: (Vector v a, Eq a) => v a -> v a -> Bool
+{-# INLINE eq #-}
+eq v w = C.runContVec C.and
+       $ C.zipWith (==) (C.cvec v) (C.cvec w)
 
-instance RealFloat a => Vector Complex a where
-  construct = Fun (:+)
-  inspect (x :+ y) (Fun f) = f x y
 
+----------------------------------------------------------------
 
-type instance Dim ((,) a) = N2
+-- | Map over vector
+map :: (Vector v a, Vector v b) => (a -> b) -> v a -> v b
+{-# INLINE map #-}
+map f = C.vector
+      . C.map f
+      . C.cvec
 
-instance (b~a) => Vector ((,) b) a where
-  construct = Fun (,)
-  inspect (a,b) (Fun f) = f a b
+-- | Evaluate every action in the vector from left to right.
+sequence :: (Vector v a, Vector v (m a), Monad m) => v (m a) -> m (v a)
+{-# INLINE sequence #-}
+sequence = mapM id
 
+-- | Evaluate every action in the vector from left to right and ignore result
+sequence_ :: (Vector v (m a), Monad m) => v (m a) -> m ()
+{-# INLINE sequence_ #-}
+sequence_ = mapM_ id
 
-type instance Dim ((,,) a b) = N3
 
-instance (b~a, c~a) => Vector ((,,) b c) a where
-  construct = Fun (,,)
-  inspect (a,b,c) (Fun f) = f a b c
+-- | Monadic map over vector.
+mapM :: (Vector v a, Vector v b, Monad m) => (a -> m b) -> v a -> m (v b)
+{-# INLINE mapM #-}
+mapM f = C.vectorM
+       . C.mapM f
+       . C.cvec
 
+-- | Apply monadic action to each element of vector and ignore result.
+mapM_ :: (Vector v a, Monad m) => (a -> m b) -> v a -> m ()
+{-# INLINE mapM_ #-}
+mapM_ f = foldl (\m a -> m >> f a >> return ()) (return ())
 
-type instance Dim ((,,,) a b c) = N4
 
-instance (b~a, c~a, d~a) => Vector ((,,,) b c d) a where
-  construct = Fun (,,,)
-  inspect (a,b,c,d) (Fun f) = f a b c d
+-- | Apply function to every element of the vector and its index.
+imap :: (Vector v a, Vector v b) =>
+    (Int -> a -> b) -> v a -> v b
+{-# INLINE imap #-}
+imap f = C.vector
+       . C.imap f
+       . C.cvec
 
+-- | Apply monadic function to every element of the vector and its index.
+imapM :: (Vector v a, Vector v b, Monad m) =>
+    (Int -> a -> m b) -> v a -> m (v b)
+{-# INLINE imapM #-}
+imapM f = C.vectorM
+        . C.imapM f
+        . C.cvec
 
-type instance Dim ((,,,,) a b c d) = N5
+-- | Apply monadic function to every element of the vector and its
+--   index and discard result.
+imapM_ :: (Vector v a, Monad m) => (Int -> a -> m b) -> v a -> m ()
+{-# INLINE imapM_ #-}
+imapM_ f = ifoldl (\m i a -> m >> f i a >> return ()) (return ())
 
-instance (b~a, c~a, d~a, e~a) => Vector ((,,,,) b c d e) a where
-  construct = Fun (,,,,)
-  inspect (a,b,c,d,e) (Fun f) = f a b c d e
+
+----------------------------------------------------------------
+
+-- | Zip two vector together using function.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec3)
+--   >>> let b0 = basis 0 :: Vec3 Int
+--   >>> let b1 = basis 1 :: Vec3 Int
+--   >>> let b2 = basis 2 :: Vec3 Int
+--   >>> let vplus x y = zipWith (+) x y
+--   >>> vplus b0 b1
+--   fromList [1,1,0]
+--   >>> vplus b0 b2
+--   fromList [1,0,1]
+--   >>> vplus b1 b2
+--   fromList [0,1,1]
+zipWith :: (Vector v a, Vector v b, Vector v c)
+        => (a -> b -> c) -> v a -> v b -> v c
+{-# INLINE zipWith #-}
+zipWith f v u = C.vector
+              $ C.zipWith f (C.cvec v) (C.cvec u)
+
+-- | Zip two vector together using monadic function.
+zipWithM :: (Vector v a, Vector v b, Vector v c, Monad m)
+         => (a -> b -> m c) -> v a -> v b -> m (v c)
+{-# INLINE zipWithM #-}
+zipWithM f v u = C.vectorM
+               $ C.zipWithM f (C.cvec v) (C.cvec u)
+
+-- | Zip two vector together using function which takes element index
+--   as well.
+izipWith :: (Vector v a, Vector v b, Vector v c)
+         => (Int -> a -> b -> c) -> v a -> v b -> v c
+{-# INLINE izipWith #-}
+izipWith f v u = C.vector
+               $ C.izipWith f (C.cvec v) (C.cvec u)
+
+-- | Zip two vector together using monadic function which takes element
+--   index as well..
+izipWithM :: (Vector v a, Vector v b, Vector v c, Monad m)
+          => (Int -> a -> b -> m c) -> v a -> v b -> m (v c)
+{-# INLINE izipWithM #-}
+izipWithM f v u = C.vectorM
+                $ C.izipWithM f (C.cvec v) (C.cvec u)
+
+
+----------------------------------------------------------------
+
+-- | Convert between different vector types
+convert :: (Vector v a, Vector w a, Dim v ~ Dim w) => v a -> w a
+{-# INLINE convert #-}
+convert = C.vector . C.cvec
+
+-- | Convert vector to the list
+toList :: (Vector v a) => v a -> [a]
+toList = foldr (:) []
+
+-- | Create vector form list. Will throw error if list is shorter than
+--   resulting vector.
+fromList :: (Vector v a) => [a] -> v a
+{-# INLINE fromList #-}
+fromList = C.vector . C.fromList
diff --git a/Data/Vector/Fixed/Internal/Arity.hs b/Data/Vector/Fixed/Internal/Arity.hs
new file mode 100644
--- /dev/null
+++ b/Data/Vector/Fixed/Internal/Arity.hs
@@ -0,0 +1,119 @@
+{-# LANGUAGE EmptyDataDecls        #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE Rank2Types            #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+-- |
+-- Type class for working with N-ary functions
+module Data.Vector.Fixed.Internal.Arity (
+    -- * Type-level naturals
+    Z
+  , S
+    -- ** Synonyms for small numerals
+  , N1
+  , N2
+  , N3
+  , N4
+  , N5
+  , N6
+    -- * N-ary functions
+  , Fn
+  , Fun(..)
+  , Arity(..)
+  ) where
+
+----------------------------------------------------------------
+-- Naturals
+----------------------------------------------------------------
+
+-- | Type level zero
+data Z
+-- | Successor of n
+data S n
+
+type N1 = S Z
+type N2 = S N1
+type N3 = S N2
+type N4 = S N3
+type N5 = S N4
+type N6 = S N5
+
+
+
+----------------------------------------------------------------
+-- N-ary functions
+----------------------------------------------------------------
+
+-- | Type family for n-ary functions.
+type family   Fn n a b
+type instance Fn Z     a b = b
+type instance Fn (S n) a b = a -> Fn n a b
+
+-- | Newtype wrapper which is used to make 'Fn' injective.
+newtype Fun n a b = Fun (Fn n a b)
+
+newtype T_fmap a b n = T_fmap (Fn n a b)
+
+instance Arity n => Functor (Fun n a) where
+  fmap (f :: b -> c) (Fun g0 :: Fun n a b)
+     = Fun $ accum
+             (\(T_fmap g) a -> T_fmap (g a))
+             (\(T_fmap x) -> f x)
+             (T_fmap g0 :: T_fmap a b n)
+  {-# INLINE fmap #-}
+
+
+-- | Type class for handling /n/-ary functions.
+class Arity n where
+  -- | Left fold over /n/ elements exposed as n-ary function.
+  accum :: (forall k. t (S k) -> a -> t k) -- ^ Fold function
+        -> (t Z -> b)                      -- ^ Extract result of fold
+        -> t n                             -- ^ Initial value
+        -> Fn n a b                        -- ^ Reduction function
+
+  -- | Monadic left fold.
+  accumM :: Monad m
+         => (forall k. t (S k) -> a -> m (t k)) -- ^ Fold function
+         -> (t Z -> m b)                        -- ^ Extract result of fold
+         -> m (t n)                             -- ^ Initial value
+         -> Fn n a (m b)                        -- ^ Reduction function
+
+  -- | Apply all parameters to the function.
+  apply :: (forall k. t (S k) -> (a, t k)) -- ^ Get value to apply to function
+        -> t n                             -- ^ Initial value
+        -> Fn n a b                        -- ^ N-ary function
+        -> b
+
+  -- | Monadic apply
+  applyM :: Monad m
+         => (forall k. t (S k) -> m (a, t k)) -- ^ Get value to apply to function
+         -> t n                               -- ^ Initial value
+         -> Fn n a (m b)                      -- ^ N-ary function
+         -> m b
+  -- | Arity of function.
+  arity :: n -> Int
+
+instance Arity Z where
+  accum  _ g t = g t
+  accumM _ g t = g =<< t
+  apply  _ _ h = h
+  applyM _ _ h = h
+  arity  _ = 0
+  {-# INLINE accum  #-}
+  {-# INLINE accumM #-}
+  {-# INLINE apply  #-}
+  {-# INLINE arity  #-}
+
+instance Arity n => Arity (S n) where
+  accum  f g t = \a -> accum  f g (f t a)
+  accumM f g t = \a -> accumM f g $ flip f a =<< t
+  apply  f t h = case f t of (a,u) -> apply f u (h a)
+  applyM f t h = do (a,u) <- f t
+                    applyM f u (h a)
+  arity  n = 1 + arity (prevN n)
+    where
+      prevN :: S n -> n
+      prevN _ = undefined
+  {-# INLINE accum  #-}
+  {-# INLINE accumM #-}
+  {-# INLINE apply  #-}
+  {-# INLINE arity  #-}
diff --git a/Data/Vector/Fixed/Mutable.hs b/Data/Vector/Fixed/Mutable.hs
--- a/Data/Vector/Fixed/Mutable.hs
+++ b/Data/Vector/Fixed/Mutable.hs
@@ -29,7 +29,8 @@
 
 import Control.Monad.ST
 import Control.Monad.Primitive
-import Data.Vector.Fixed.Internal
+import Data.Vector.Fixed.Internal.Arity
+import Data.Vector.Fixed.Cont (Dim)
 import Prelude hiding (read)
 
 
diff --git a/Data/Vector/Fixed/Primitive.hs b/Data/Vector/Fixed/Primitive.hs
--- a/Data/Vector/Fixed/Primitive.hs
+++ b/Data/Vector/Fixed/Primitive.hs
@@ -13,6 +13,8 @@
   , Vec3
     -- * Mutable
   , MVec
+    -- * Type classes
+  , Prim
   ) where
 
 import Control.Monad
@@ -21,7 +23,7 @@
 import Prelude hiding (length,replicate,zipWith,map,foldl)
 
 import Data.Vector.Fixed
-import Data.Vector.Fixed.Internal
+import Data.Vector.Fixed.Internal.Arity
 import Data.Vector.Fixed.Mutable
 
 
@@ -82,10 +84,12 @@
 type instance DimM (MVec n) = n
 
 instance (Arity n, Prim a) => Vector (Vec n) a where
-  construct = constructVec
-  inspect   = inspectVec
-  {-# INLINE construct #-}
-  {-# INLINE inspect   #-}
+  construct  = constructVec
+  inspect    = inspectVec
+  basicIndex = index
+  {-# INLINE construct  #-}
+  {-# INLINE inspect    #-}
+  {-# INLINE basicIndex #-}
 instance (Arity n, Prim a) => VectorN Vec n a
 
 instance (Arity n, Prim a, Eq a) => Eq (Vec n a) where
diff --git a/Data/Vector/Fixed/Storable.hs b/Data/Vector/Fixed/Storable.hs
--- a/Data/Vector/Fixed/Storable.hs
+++ b/Data/Vector/Fixed/Storable.hs
@@ -15,6 +15,8 @@
   , unsafeWith
     -- * Mutable
   , MVec(..)
+    -- * Type classes
+  , Storable
   ) where
 
 import Control.Monad.Primitive
@@ -27,7 +29,7 @@
 import Prelude hiding (length,replicate,zipWith,map,foldl)
 
 import Data.Vector.Fixed
-import Data.Vector.Fixed.Internal
+import Data.Vector.Fixed.Internal.Arity
 import Data.Vector.Fixed.Mutable
 
 
@@ -128,10 +130,12 @@
 type instance DimM (MVec n) = n
 
 instance (Arity n, Storable a) => Vector (Vec n) a where
-  construct = constructVec
-  inspect   = inspectVec
-  {-# INLINE construct #-}
-  {-# INLINE inspect   #-}
+  construct  = constructVec
+  inspect    = inspectVec
+  basicIndex = index
+  {-# INLINE construct  #-}
+  {-# INLINE inspect    #-}
+  {-# INLINE basicIndex #-}
 instance (Arity n, Storable a) => VectorN Vec n a
 
 instance (Arity n, Storable a, Eq a) => Eq (Vec n a) where
diff --git a/Data/Vector/Fixed/Unboxed.hs b/Data/Vector/Fixed/Unboxed.hs
--- a/Data/Vector/Fixed/Unboxed.hs
+++ b/Data/Vector/Fixed/Unboxed.hs
@@ -24,7 +24,7 @@
 import Data.Word (Word,Word8,Word16,Word32,Word64)
 import Prelude hiding (length,replicate,zipWith,map,foldl)
 
-import Data.Vector.Fixed
+import Data.Vector.Fixed (Dim,Arity,Vector(..),VectorN,S,Z,toList,eq)
 import Data.Vector.Fixed.Mutable
 import qualified Data.Vector.Fixed.Primitive as P
 
@@ -55,10 +55,14 @@
 type instance DimM (MVec n) = n
 
 instance (Unbox n a) => Vector (Vec n) a where
-  construct = constructVec
-  inspect   = inspectVec
-  {-# INLINE construct #-}
-  {-# INLINE inspect   #-}
+  construct  = constructVec
+  inspect    = inspectVec
+  basicIndex = index
+  {-# INLINE construct  #-}
+  {-# INLINE inspect    #-}
+  {-# INLINE basicIndex #-}
+
+
 instance (Unbox n a) => VectorN Vec n a
 
 instance (Unbox n a, Eq a) => Eq (Vec n a) where
diff --git a/fixed-vector.cabal b/fixed-vector.cabal
--- a/fixed-vector.cabal
+++ b/fixed-vector.cabal
@@ -1,18 +1,34 @@
 Name:           fixed-vector
-Version:        0.2.0.0
-Synopsis:       Generic vectors with fixed length
+Version:        0.3.0.0
+Synopsis:       Generic vectors with statically known size.
 Description:
-  Generic vectors with fixed length. Package is structured as follows:
+  Generic library for vectors with statically known
+  size. Implementation is based on
+  <http://unlines.wordpress.com/2010/11/15/generics-for-small-fixed-size-vectors/>
+  Same functions could be used to work with both ADT based vector like
   .
+  > data Vec3 a = a a a
+  .
+  Tuples are vectors too:
+  .
+  >>> sum (1,2,3)
+  6
+  .
+  Vectors which are represented internally by arrays are provided by
+  library. Both boxed and unboxed arrays are supported.
+  .
+  Library is structured as follows:
+  .
   [@Data.Vector.Fixed@]
   Generic API. It's suitable for both ADT-based vector like @Complex@
   and array-based ones.
   .
   [@Data.Vector.Fixed.Cont@]
-  Continuation based vectors.
+  Continuation based vectors. Internally all functions use them.
   .
   [@Data.Vector.Fixed.Mutable@]
-  Type classes for array-based implementation.
+  Type classes for array-based implementation and API for working with
+  mutable state.
   .
   [@Data.Vector.Fixed.Unboxed@]
   Unboxed vectors.
@@ -26,6 +42,14 @@
   [@Data.Vector.Fixed.Primitive@]
   Unboxed vectors based on pritimive package.
   .
+  Changes in 0.3.0.0
+  .
+  * @Vector@ type class definition is moved to the @D.V.F.Cont@ module.
+  .
+  * Indexing function restored.
+  .
+  * @unfoldr@ added.
+  .
   Changes in 0.2.0.0
   .
   * Continuation-based vector added.
@@ -73,15 +97,17 @@
     primitive
   Exposed-modules:
     -- API
-    Data.Vector.Fixed
-    Data.Vector.Fixed.Internal
+    Data.Vector.Fixed.Internal.Arity
     Data.Vector.Fixed.Cont
-    Data.Vector.Fixed.Mutable
+    Data.Vector.Fixed
     -- Arrays
+    Data.Vector.Fixed.Mutable
     Data.Vector.Fixed.Boxed
     Data.Vector.Fixed.Primitive
     Data.Vector.Fixed.Unboxed
     Data.Vector.Fixed.Storable
+  Other-modules:
+    Data.Vector.Fixed.Internal
 
 Test-Suite doctests
   Type:           exitcode-stdio-1.0
