diff --git a/contiguous.cabal b/contiguous.cabal
--- a/contiguous.cabal
+++ b/contiguous.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.0
 name: contiguous
-version: 0.5
+version: 0.5.1
 homepage: https://github.com/andrewthad/contiguous
 bug-reports: https://github.com/andrewthad/contiguous/issues
 author: Andrew Martin
diff --git a/src/Data/Primitive/Contiguous.hs b/src/Data/Primitive/Contiguous.hs
--- a/src/Data/Primitive/Contiguous.hs
+++ b/src/Data/Primitive/Contiguous.hs
@@ -83,6 +83,7 @@
     -- ** Zipping
   , zip
   , zipWith
+  , izipWith
 
     -- ** Specific elements
   , swap
@@ -421,13 +422,13 @@
   resize = resizeMutablePrimArray
   size = sizeofPrimArray
   sizeMutable = getSizeofMutablePrimArray
-  freeze = freezePrimArray
+  freeze = freezePrimArrayShim
   unsafeFreeze = unsafeFreezePrimArray
   thaw = thawPrimArray
   copy = copyPrimArray
   copyMutable = copyMutablePrimArray
-  clone = clonePrimArray
-  cloneMutable = cloneMutablePrimArray
+  clone = clonePrimArrayShim
+  cloneMutable = cloneMutablePrimArrayShim
   equals = (==)
   unlift (PrimArray x) = unsafeCoerce# x
   lift x = PrimArray (unsafeCoerce# x)
@@ -631,12 +632,12 @@
 errorThunk = error "Contiguous typeclass: unitialized element"
 {-# noinline errorThunk #-}
 
-freezePrimArray :: (PrimMonad m, Prim a) => MutablePrimArray (PrimState m) a -> Int -> Int -> m (PrimArray a)
-freezePrimArray !src !off !len = do
+freezePrimArrayShim :: (PrimMonad m, Prim a) => MutablePrimArray (PrimState m) a -> Int -> Int -> m (PrimArray a)
+freezePrimArrayShim !src !off !len = do
   dst <- newPrimArray len
   copyMutablePrimArray dst 0 src off len
   unsafeFreezePrimArray dst
-{-# inline freezePrimArray #-}
+{-# inline freezePrimArrayShim #-}
 
 resizeArray :: PrimMonad m => MutableArray (PrimState m) a -> Int -> m (MutableArray (PrimState m) a)
 resizeArray !src !sz = do
@@ -967,19 +968,19 @@
   pure marr
 {-# inline thawPrimArray #-}
 
-clonePrimArray :: Prim a => PrimArray a -> Int -> Int -> PrimArray a
-clonePrimArray !arr !off !len = runST $ do
+clonePrimArrayShim :: Prim a => PrimArray a -> Int -> Int -> PrimArray a
+clonePrimArrayShim !arr !off !len = runST $ do
   marr <- newPrimArray len
   copyPrimArray marr 0 arr off len
   unsafeFreezePrimArray marr
-{-# inline clonePrimArray #-}
+{-# inline clonePrimArrayShim #-}
 
-cloneMutablePrimArray :: (PrimMonad m, Prim a) => MutablePrimArray (PrimState m) a -> Int -> Int -> m (MutablePrimArray (PrimState m) a)
-cloneMutablePrimArray !arr !off !len = do
+cloneMutablePrimArrayShim :: (PrimMonad m, Prim a) => MutablePrimArray (PrimState m) a -> Int -> Int -> m (MutablePrimArray (PrimState m) a)
+cloneMutablePrimArrayShim !arr !off !len = do
   marr <- newPrimArray len
   copyMutablePrimArray marr 0 arr off len
   pure marr
-{-# inline cloneMutablePrimArray #-}
+{-# inline cloneMutablePrimArrayShim #-}
 
 -- | @'replicate' n x@ is an array of length @n@ with @x@ the value of every element.
 replicate :: (Contiguous arr, Element arr a) => Int -> a -> arr a
@@ -2060,18 +2061,33 @@
     -> arr1 a
     -> arr2 b
     -> arr3 c
-zipWith f as bs = create $ do
+zipWith f = izipWith (\_ a b -> f a b)
+{-# inline zipWith #-}
+
+-- | Variant of 'zipWith' that provides the index of each pair of elements.
+izipWith ::
+  ( Contiguous arr1
+  , Contiguous arr2
+  , Contiguous arr3
+  , Element arr1 a
+  , Element arr2 b
+  , Element arr3 c
+  ) => (Int -> a -> b -> c)
+    -> arr1 a
+    -> arr2 b
+    -> arr3 c
+izipWith f as bs = create $ do
   let !sz = min (size as) (size bs)
   !marr <- new sz
   let go !ix = when (ix < sz) $ do
         a <- indexM as ix
         b <- indexM bs ix
-        let !g = f a b
+        let !g = f ix a b
         write marr ix g
         go (ix + 1)
   go 0
   pure marr
-{-# inline zipWith #-}
+{-# inline izipWith #-}
 
 -- | 'zip' takes two arrays and returns an array of
 --   corresponding pairs.
