diff --git a/Data/Vector/Fixed.hs b/Data/Vector/Fixed.hs
--- a/Data/Vector/Fixed.hs
+++ b/Data/Vector/Fixed.hs
@@ -26,6 +26,7 @@
   , N6
     -- ** Type class
   , Vector(..)
+  , VectorN
   , Arity
   , Fun(..)
   , length
@@ -51,16 +52,26 @@
   , map
   , mapM
   , mapM_
+  , imap
+  , imapM
+  , imapM_
+  , sequence
+  , sequence_
     -- ** Folding
   , foldl
   , foldl1
   , foldM
+  , ifoldl
+  , ifoldM
+    -- *** Special folds
   , sum
   , maximum
   , minimum
     -- ** Zips
   , zipWith
+  , zipWithM
   , izipWith
+  , izipWithM
     -- ** Conversion
   , convert
   , toList
@@ -74,7 +85,7 @@
 import qualified Prelude as P
 import Prelude hiding ( replicate,map,zipWith,maximum,minimum
                       , foldl,foldl1,length,sum
-                      , head,tail,mapM,mapM_
+                      , head,tail,mapM,mapM_,sequence,sequence_
                       )
 
 
@@ -325,8 +336,32 @@
                         (T_foldl1 Nothing :: T_foldl1 a (S n))
 
 
+-- | 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 v = inspectV v
+             $ ifoldlF f z
 
+-- | 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 }
 
+data T_ifoldl b n = T_ifoldl {-# UNPACK #-} !Int b
+
+ifoldlF :: forall n a b. Arity n => (b -> Int -> a -> b) -> b -> Fun n a b
+{-# INLINE ifoldlF #-}
+ifoldlF f b = Fun $
+    accum (\(T_ifoldl i r) a -> T_ifoldl (i + 1) (f r i a))
+          (\(T_ifoldl _ r) -> r)
+          (T_ifoldl 0 b :: T_ifoldl b n)
+
+
+
 ----------------------------------------------------------------
 
 -- | Sum all elements in the vector
@@ -342,7 +377,7 @@
 -- | Minimum element of vector
 minimum :: (Vector v a, Dim v ~ S n, Ord a) => v a -> a
 {-# INLINE minimum #-}
-minimum = foldl1 max
+minimum = foldl1 min
 
 
 
@@ -353,8 +388,20 @@
 {-# INLINE map #-}
 map f v = create $ Cont
         $ inspectV v
-        . mapF f
+        . fmap runID
+        . mapFM (return . f)
 
+-- | 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 #-}
@@ -367,62 +414,112 @@
 {-# INLINE mapM_ #-}
 mapM_ f = foldl (\m a -> m >> f a >> return ()) (return ())
 
-newtype T_map b c n = T_map (Fn n b c)
 
-mapF :: forall n a b c. Arity n => (a -> b) -> Fun n b c -> Fun n a c
-mapF f (Fun h) = Fun $ accum (\(T_map g) a -> T_map (g (f a)))
-                             (\(T_map g)   -> g)
-                             (T_map h :: T_map b c n)
+newtype T_map b c n = T_map (Fn n b c)
 
 mapFM :: forall m n a b c. (Arity n, Monad m) => (a -> m b) -> Fun n b c -> Fun n a (m c)
+{-# INLINE mapFM #-}
 mapFM f (Fun h) = Fun $ accumM (\(T_map g) a -> do { b <- f a; return (T_map (g b)) })
                                (\(T_map g) -> return g)
                                (return $ T_map h :: m (T_map b c n))
 
+
+-- | Apply function to every element of the vector and its index.
+imap :: (Vector v a, Vector v b, Monad m) =>
+    (Int -> a -> b) -> v a -> v b
+{-# INLINE imap #-}
+imap f v = create $ Cont
+         $ inspectV v
+         . fmap runID
+         . imapFM (\i a -> return $ f i a)
+
+-- | 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 v = inspectV v
+          $ imapFM f
+          $ construct
+
+-- | 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 ())
+
+
+data T_imap b c n = T_imap {-# UNPACK #-} !Int (Fn n b c)
+
+imapFM :: forall m n a b c. (Arity n, Monad m)
+       => (Int -> a -> m b) -> Fun n b c -> Fun n a (m c)
+{-# INLINE imapFM #-}
+imapFM f (Fun h) = Fun $
+  accumM (\(T_imap i g) a -> do b <- f i a
+                                return (T_imap (i + 1) (g b)))
+         (\(T_imap _ g) -> return g)
+         (return $ T_imap 0 h :: m (T_imap b c n))
+
+
+
 ----------------------------------------------------------------
 
--- | Zip two vector together.
+-- | Zip two vector together using function.
 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 = create $ Cont
               $ inspectV u
               . inspectV v
-              . zipWithF f
-
-data T_zip a c r n = T_zip (VecList n a) (Fn n c r)
-
-zipWithF :: forall n a b c d. Arity n
-         => (a -> b -> c) -> Fun n c d -> Fun n a (Fun n b d)
-zipWithF f (Fun g0) =
-  fmap (\v -> Fun $ accum
-              (\(T_zip (VecList (a:as)) g) b -> T_zip (VecList as) (g (f a b)))
-              (\(T_zip _ x) -> x)
-              (T_zip v g0 :: T_zip a c d n)
-       ) construct
+              . (fmap (fmap runID))
+              . izipWithFM (\_ a b -> return (f a b))
 
+-- | 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 = inspectV u
+               $ inspectV v
+               $ izipWithFM (const f)
+               $ construct
 
--- | Zip two vector together.
+-- | 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 = create $ Cont
                $ inspectV u
                . inspectV v
-               . izipWithF f
+               . fmap (fmap runID)
+               . izipWithFM (\i a b -> return $ f i a b)
 
+-- | 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 = inspectV u
+                $ inspectV v
+                $ izipWithFM f
+                $ construct
+
 data T_izip a c r n = T_izip Int (VecList n a) (Fn n c r)
 
-izipWithF :: forall n a b c d. Arity n
-          => (Int -> a -> b -> c) -> Fun n c d -> Fun n a (Fun n b d)
-izipWithF f (Fun g0) =
-  fmap (\v -> Fun $ accum
-              (\(T_izip i (VecList (a:as)) g) b -> T_izip (i+1) (VecList as) (g (f i a b)))
-              (\(T_izip _ _ x) -> x)
-              (T_izip 0 v g0 :: T_izip a c d n)
+-- FIXME: explain function
+izipWithFM :: forall m n a b c d. (Arity n, Monad m)
+           => (Int -> a -> b -> m c) -> Fun n c d -> Fun n a (Fun n b (m d))
+{-# INLINE izipWithFM #-}
+izipWithFM f (Fun g0) =
+  fmap (\v -> Fun $ accumM
+              (\(T_izip i (VecList (a:as)) g) b -> do x <- f i a b
+                                                      return $ T_izip (i+1) (VecList as) (g x)
+              )
+              (\(T_izip _ _ x) -> return x)
+              (return $ T_izip 0 v g0 :: m (T_izip a c d n))
        ) construct
 
 
+
 ----------------------------------------------------------------
 
 -- | Convert between different vector types
@@ -475,3 +572,14 @@
     f
   {-# INLINE construct #-}
   {-# INLINE inspect   #-}
+instance Arity n => VectorN VecList n a
+
+
+-- String identity monad
+newtype Id a = Id { runID :: a }
+
+instance Monad Id where
+  return     = Id
+  Id a >>= f = f a
+  {-# INLINE return #-}
+  {-# INLINE (>>=)  #-}
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
@@ -82,6 +82,7 @@
   inspect   = inspectVec
   {-# INLINE construct #-}
   {-# INLINE inspect   #-}
+instance (Arity n) => VectorN Vec n a
 
 uninitialised :: a
 uninitialised = error "Data.Vector.Fixed.Boxed: uninitialised element"
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
@@ -23,6 +23,7 @@
     -- * Vector type class
   , Dim
   , Vector(..)
+  , VectorN
   , length
     -- * Deforestation
     -- $deforestation
@@ -139,6 +140,13 @@
   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:
+--
+-- > 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
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
@@ -86,3 +86,4 @@
   inspect   = inspectVec
   {-# INLINE construct #-}
   {-# INLINE inspect   #-}
+instance (Arity n, Prim a) => VectorN Vec n a
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
@@ -132,6 +132,7 @@
   inspect   = inspectVec
   {-# INLINE construct #-}
   {-# INLINE inspect   #-}
+instance (Arity n, Storable a) => VectorN Vec n a
 
 
 
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
@@ -59,6 +59,8 @@
   inspect   = inspectVec
   {-# INLINE construct #-}
   {-# INLINE inspect   #-}
+instance (Unbox n a) => VectorN Vec n a
+
 
 
 ----------------------------------------------------------------
diff --git a/fixed-vector.cabal b/fixed-vector.cabal
--- a/fixed-vector.cabal
+++ b/fixed-vector.cabal
@@ -1,5 +1,5 @@
 Name:           fixed-vector
-Version:        0.1.1
+Version:        0.1.2
 Synopsis:       Generic vectors with fixed length
 Description:
   Generic vectors with fixed length. Package is structured as follows:
