diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,37 @@
+# 1.4
+
+- Reorder class hierarchy. `Unzip` is now at the bottom, right above `Functor`.
+  There are two ways things may break:
+  - You may need to add `Unzip` instance if you haven't one already, for example:
+    `instance Unzip ((->) e) where unzip = unzipDefault` was added in this patch.
+  - `Unzip f` doesn't imply whole hierarchy, so you may need to change `Unzip f` to `Zip f`
+    in the constraints of some of your functions.
+- Relax laws of Unalign allowing list-like instances.
+  - Add `Unalign []` and `Unalign Vector` instances.
+
+# 1.3.1
+
+- Support GHC-8.6.5...GHC-9.10.1
+
+# 1.3
+
+- Depend on `bifunctor-classes-compat` instead of `bifunctors`
+  See changelog note in `bifunctors-5.6`: https://hackage.haskell.org/package/bifunctors-5.6/changelog
+  This is breaking change, but affects only GHC-8.0 and older users.
+  In that case you should check various combinations of newer/older
+  `bifunctors`, `these`, and `semialign` packages.
+
+# 1.2.0.1
+
+-  GHC-9.2 support
+
+# 1.2
+
+- Migrate `SemialignWithIndex` and `ZipWithIndex` to this package,
+  using `FunctorWithIndex` from `indexed-traversable`.
+- Add `RepeatWithIndex` type-class.
+- Poly-kinded instances (notably `Tagged`)
+
 # 1.1.0.1
 
 - Drop `base-compat` dependency
diff --git a/semialign.cabal b/semialign.cabal
--- a/semialign.cabal
+++ b/semialign.cabal
@@ -1,10 +1,10 @@
 cabal-version:      >=1.10
 name:               semialign
-version:            1.1.0.1
+version:            1.4
 synopsis:
   Align and Zip type-classes from the common Semialign ancestor.
 
-homepage:           https://github.com/isomorphism/these
+homepage:           https://github.com/haskellari/these
 license:            BSD3
 license-file:       LICENSE
 author:             C. McCann, Oleg Grenrus
@@ -21,21 +21,22 @@
   forming lattice-like structure.
 
 tested-with:
-    GHC ==7.4.2
-     || ==7.6.3
-     || ==7.8.4
-     || ==7.10.3
-     || ==8.0.2
-     || ==8.2.2
-     || ==8.4.4
-     || ==8.6.5
-     || ==8.8.3
-     || ==8.10.1
-  , GHCJS ==8.4
+  GHC ==8.6.5
+   || ==8.8.4
+   || ==8.10.7
+   || ==9.0.2
+   || ==9.2.8
+   || ==9.4.8
+   || ==9.6.6
+   || ==9.8.4
+   || ==9.10.1
+   || ==9.12.4
+   || ==9.14.1
 
 source-repository head
   type:     git
-  location: https://github.com/isomorphism/these.git
+  location: https://github.com/haskellari/these.git
+  subdir:   semialign
 
 flag semigroupoids
   description: Build with semigroupoids dependency
@@ -44,52 +45,37 @@
 
 library
   default-language: Haskell2010
-  ghc-options:      -Wall
+  ghc-options:      -Wall -Wno-trustworthy-safe
 
-  if impl(ghc >=8.0)
-    ghc-options: -Wno-trustworthy-safe
+  if impl(ghc >=9.2)
+    ghc-options: -Wno-noncanonical-monoid-instances
 
   hs-source-dirs:   src
   exposed-modules:
     Data.Align
     Data.Crosswalk
     Data.Semialign
+    Data.Semialign.Indexed
     Data.Zip
 
   other-modules:    Data.Semialign.Internal
 
   -- ghc boot libs
   build-depends:
-      base          >=4.5.1.0 && <4.15
-    , containers    >=0.4.2.1 && <0.7
-    , transformers  >=0.3.0.0 && <0.6
+      base          >=4.12.0.0 && <4.23
+    , containers    >=0.6.0.1  && <0.9
 
   -- These
-  build-depends:    these >=1 && <1.2
+  build-depends:    these >=1.2.1 && <1.3
 
   -- other dependencies
   build-depends:
-      hashable              >=1.2.7.0  && <1.4
-    , tagged                >=0.8.6    && <0.9
-    , unordered-containers  >=0.2.8.0  && <0.3
-    , vector                >=0.12.0.2 && <0.13
-
-  -- base shims
-  if !impl(ghc >=8.2)
-    build-depends: bifunctors >=5.5.4 && <5.6
-
-  if !impl(ghc >=8.0)
-    build-depends:
-        semigroups           >=0.18.5  && <0.20
-      , transformers         >=0.3.0.0 && <0.6
-      , transformers-compat  >=0.6.5   && <0.7
-
-    -- Ensure Data.Functor.Classes is always available
-    if impl(ghc >=7.10)
-      build-depends: transformers >=0.4.2.0
-
-  if impl(ghc <7.5)
-    build-depends: ghc-prim
+      hashable                       >=1.4.4.0  && <1.6
+    , indexed-traversable            >=0.1.4    && <0.2
+    , indexed-traversable-instances  >=0.1.2    && <0.2
+    , tagged                         >=0.8.8    && <0.9
+    , unordered-containers           >=0.2.8.0  && <0.3
+    , vector                         >=0.13.0.0 && <0.14
 
   if flag(semigroupoids)
-    build-depends: semigroupoids >=5.3.2 && <5.4
+    build-depends: semigroupoids >=6.0.1 && <6.1
diff --git a/src/Data/Crosswalk.hs b/src/Data/Crosswalk.hs
--- a/src/Data/Crosswalk.hs
+++ b/src/Data/Crosswalk.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP         #-}
 {-# LANGUAGE Trustworthy #-}
 module Data.Crosswalk (
     -- * Crosswalk
@@ -42,9 +41,7 @@
     sequenceL :: (Align f) => t (f a) -> f (t a)
     sequenceL = crosswalk id
 
-#if __GLASGOW_HASKELL__ >= 707
     {-# MINIMAL crosswalk | sequenceL #-}
-#endif
 
 instance Crosswalk Identity where
     crosswalk f (Identity a) = fmap Identity (f a)
@@ -106,10 +103,7 @@
     bisequenceL :: (Align f) => t (f a) (f b) -> f (t a b)
     bisequenceL = bicrosswalk id id
 
-#if __GLASGOW_HASKELL__ >= 707
     {-# MINIMAL bicrosswalk | bisequenceL #-}
-#endif
-
 
 instance Bicrosswalk Either where
     bicrosswalk f _ (Left x)  = Left  <$> f x
diff --git a/src/Data/Semialign/Indexed.hs b/src/Data/Semialign/Indexed.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Semialign/Indexed.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE Safe #-}
+-- | Zipping and aligning of indexed functors.
+module Data.Semialign.Indexed (
+    SemialignWithIndex (..),
+    ZipWithIndex (..),
+    RepeatWithIndex (..),
+) where
+
+import Data.Semialign.Internal
diff --git a/src/Data/Semialign/Internal.hs b/src/Data/Semialign/Internal.hs
--- a/src/Data/Semialign/Internal.hs
+++ b/src/Data/Semialign/Internal.hs
@@ -1,18 +1,21 @@
 {-# LANGUAGE CPP                        #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE FunctionalDependencies     #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE PolyKinds                  #-}
 {-# LANGUAGE StandaloneDeriving         #-}
 {-# LANGUAGE Trustworthy                #-}
+{-# LANGUAGE UndecidableInstances       #-}
 module Data.Semialign.Internal where
 
 import Prelude
-       (Bool (..), Eq (..), Functor (fmap), Maybe (..), Monad (..), Ord (..),
-       Ordering (..), String, error, flip, fst, id, maybe, snd, uncurry, ($),
-       (++), (.))
+       (Bool (..), Either (..), Eq (..), Functor (fmap), Int, Maybe (..),
+       Monad (..), Ord (..), Ordering (..), String, error, flip, fst, id, maybe,
+       snd, uncurry, ($), (++), (.))
 
 import qualified Prelude as Prelude
 
-import Control.Applicative (ZipList (..), pure, (<$>))
-import Data.Monoid         (Monoid (..))
+import Control.Applicative               (ZipList (..), pure, (<$>))
 import Data.Bifunctor                    (Bifunctor (..))
 import Data.Functor.Compose              (Compose (..))
 import Data.Functor.Identity             (Identity (..))
@@ -21,13 +24,18 @@
 import Data.HashMap.Strict               (HashMap)
 import Data.List.NonEmpty                (NonEmpty (..))
 import Data.Maybe                        (catMaybes)
+import Data.Monoid                       (Monoid (..))
 import Data.Proxy                        (Proxy (..))
-import Data.Semigroup                    (Option (..), Semigroup (..))
+import Data.Semigroup                    (Semigroup (..))
 import Data.Sequence                     (Seq)
 import Data.Tagged                       (Tagged (..))
 import Data.Vector.Fusion.Stream.Monadic (Step (..), Stream (..))
 import Data.Vector.Generic               (Vector, empty, stream, unstream)
+import Data.Void                         (Void)
 
+import Data.Functor.WithIndex           (FunctorWithIndex (imap))
+import Data.Functor.WithIndex.Instances ()
+
 import qualified Data.HashMap.Strict               as HM
 import qualified Data.List.NonEmpty                as NE
 import qualified Data.Sequence                     as Seq
@@ -35,33 +43,21 @@
 import qualified Data.Vector                       as V
 import qualified Data.Vector.Fusion.Stream.Monadic as Stream
 
-#if MIN_VERSION_vector(0,11,0)
 import           Data.Vector.Fusion.Bundle.Monadic (Bundle (..))
 import qualified Data.Vector.Fusion.Bundle.Monadic as Bundle
 import qualified Data.Vector.Fusion.Bundle.Size    as Bundle
-#else
-import qualified Data.Vector.Fusion.Stream.Size as Stream
-#endif
 
-#if MIN_VERSION_containers(0,5,0)
 import           Data.Map.Lazy (Map)
 import qualified Data.Map.Lazy as Map
 
 import           Data.IntMap.Lazy (IntMap)
 import qualified Data.IntMap.Lazy as IntMap
 
-#if MIN_VERSION_containers(0,5,9)
 import qualified Data.IntMap.Merge.Lazy as IntMap
 import qualified Data.Map.Merge.Lazy    as Map
-#endif
 
--- containers <0.5
-#else
-import           Data.Map (Map)
-import qualified Data.Map as Map
-
-import           Data.IntMap (IntMap)
-import qualified Data.IntMap as IntMap
+#if !(MIN_VERSION_base(4,16,0))
+import Data.Semigroup (Option (..))
 #endif
 
 import Data.These
@@ -81,7 +77,7 @@
 -- The laws of 'align' and 'zip' resemble lattice laws.
 -- There is a plenty of laws, but they are simply satisfied.
 --
--- And an addition property if @f@ is 'Foldable',
+-- And an additional property if @f@ is 'Foldable',
 -- which tries to enforce 'align'-feel:
 -- neither values are duplicated nor lost.
 --
@@ -125,17 +121,7 @@
 --          ≡ mapMaybe justHere (toList (align x y))
 -- @
 --
---
--- And an addition property if @f@ is 'Foldable',
--- which tries to enforce 'align'-feel:
--- neither values are duplicated nor lost.
---
--- @
--- toList x = toListOf (folded . here) (align x y)
---          = mapMaybe justHere (toList (align x y))
--- @
---
-class Functor f => Semialign f where
+class Unzip f => Semialign f where
     -- | Analogous to @'zip'@, combines two structures by taking the union of
     --   their shapes and using @'These'@ to hold the elements.
     align :: f a -> f b -> f (These a b)
@@ -146,9 +132,7 @@
     alignWith :: (These a b -> c) -> f a -> f b -> f c
     alignWith f a b = f <$> align a b
 
-#if __GLASGOW_HASKELL__ >= 707
     {-# MINIMAL (align | alignWith) #-}
-#endif
 
 -- | A unit of 'align'.
 --
@@ -172,10 +156,18 @@
 -- == Laws
 --
 -- @
--- uncurry align (unalign xs) ≡ xs
 -- unalign (align xs ys) ≡ (xs, ys)
 -- @
 --
+-- Previously 'Unalign' included a right inverse law
+--
+-- @
+-- uncurry align (unalign xs) ≡ xs
+-- @
+--
+-- But this law was removed in 1.4 to allow list-like instances,
+-- where unalign necessarily loses some information.
+--
 -- == Compatibility note
 --
 -- In version 1 'unalign' was changed to return @(f a, f b)@ pair,
@@ -192,11 +184,8 @@
     unalignWith :: (c -> These a b) -> f c -> (f a, f b)
     unalignWith f fx = unalign (fmap f fx)
 
-#if __GLASGOW_HASKELL__ >= 707
     {-# MINIMAL unalignWith | unalign #-}
-#endif
 
-
 -- | Functors supporting a 'zip' operation that takes the intersection of
 -- non-uniform shapes.
 --
@@ -280,9 +269,7 @@
     zipWith :: (a -> b -> c) -> f a -> f b -> f c
     zipWith f a b = uncurry f <$> zip a b
 
-#if __GLASGOW_HASKELL__ >= 707
     {-# MINIMAL (zip | zipWith) #-}
-#endif
 
 -- | Zippable functors supporting left and right units
 --
@@ -316,24 +303,54 @@
 --
 -- For sequence-like types this holds, but for Map-like it doesn't.
 --
-class Zip f => Unzip f where
+class Functor f => Unzip f where
     unzipWith :: (c -> (a, b)) -> f c -> (f a, f b)
     unzipWith f = unzip . fmap f
 
     unzip :: f (a, b) -> (f a, f b)
     unzip = unzipWith id
 
-#if __GLASGOW_HASKELL__ >= 707
     {-# MINIMAL unzipWith | unzip #-}
-#endif
 
 unzipDefault :: Functor f => f (a, b) -> (f a, f b)
 unzipDefault x = (fst <$> x, snd <$> x)
 
+-- | Indexed version of 'Semialign'.
+--
+-- @since 1.2
+class (FunctorWithIndex i f, Semialign f) => SemialignWithIndex i f | f -> i where
+    -- | Analogous to 'alignWith', but also provides an index.
+    ialignWith :: (i -> These a b -> c) -> f a -> f b -> f c
+    ialignWith f a b = imap f (align a b)
+
+-- | Indexed version of 'Zip'.
+--
+-- @since 1.2
+class (SemialignWithIndex i f, Zip f) => ZipWithIndex i f | f -> i where
+    -- | Analogous to 'zipWith', but also provides an index.
+    izipWith :: (i -> a -> b -> c) -> f a -> f b -> f c
+    izipWith f a b = imap (uncurry . f) (zip a b)
+
+-- | Indexed version of 'Repeat'.
+--
+-- @since 1.2
+class (ZipWithIndex i f, Repeat f) => RepeatWithIndex i f | f -> i where
+    -- | Analogous to 'repeat', but also provides an index.
+    --
+    -- This should be the same as 'tabulate' for representable functors.
+    irepeat :: (i -> a) -> f a
+    irepeat f = imap (\i f' -> f' i) (repeat f)
+
 -------------------------------------------------------------------------------
 -- base
 -------------------------------------------------------------------------------
 
+-- |
+--
+-- @since 1.4
+instance Unzip ((->) e) where
+    unzip = unzipDefault
+
 instance Semialign ((->) e) where
     align f g x = These (f x) (g x)
     alignWith h f g x = h (These (f x) (g x))
@@ -344,6 +361,13 @@
 instance Repeat ((->) e) where
     repeat = pure
 
+instance SemialignWithIndex e ((->) e) where
+    ialignWith h f g x = h x (These (f x) (g x))
+instance ZipWithIndex e ((->) e) where
+    izipWith h f g x = h x (f x) (g x)
+instance RepeatWithIndex e ((->) e) where
+    irepeat = id
+
 instance Semialign Maybe where
     align Nothing Nothing = Nothing
     align (Just a) Nothing = Just (This a)
@@ -370,6 +394,9 @@
 instance Align Maybe where
     nil = Nothing
 
+instance SemialignWithIndex () Maybe
+instance ZipWithIndex () Maybe
+instance RepeatWithIndex () Maybe
 
 instance Semialign [] where
     align xs [] = This <$> xs
@@ -389,7 +416,20 @@
 instance Unzip [] where
     unzip = Prelude.unzip
 
+-- |
+--
+-- @since 1.4
+instance Unalign [] where
+    unalign = Prelude.foldr f ([], []) where
+        f :: These a b -> ([a], [b]) -> ([a], [b])
+        f (This x)    ~(xs, ys) = (x : xs,     ys)
+        f (That y)    ~(xs, ys) = (    xs, y : ys)
+        f (These x y) ~(xs, ys) = (x : xs, y : ys)
 
+instance SemialignWithIndex Int []
+instance ZipWithIndex Int []
+instance RepeatWithIndex Int []
+
 -- | @'zipWith' = 'liftA2'@ .
 instance Semialign ZipList where
     alignWith f (ZipList xs) (ZipList ys) = ZipList (alignWith f xs ys)
@@ -407,6 +447,14 @@
     unzip (ZipList xs) = (ZipList ys, ZipList zs) where
         (ys, zs) = unzip xs
 
+instance Unalign ZipList where
+    unalign (ZipList xs) = (ZipList ys, ZipList zs) where
+        (ys, zs) = unalign xs
+
+instance SemialignWithIndex Int ZipList
+instance ZipWithIndex Int ZipList
+instance RepeatWithIndex Int ZipList
+
 -------------------------------------------------------------------------------
 -- semigroups
 -------------------------------------------------------------------------------
@@ -424,6 +472,11 @@
 instance Unzip NonEmpty where
     unzip = NE.unzip
 
+instance SemialignWithIndex Int NonEmpty
+instance ZipWithIndex Int NonEmpty
+instance RepeatWithIndex Int NonEmpty
+
+#if !(MIN_VERSION_base(4,16,0))
 deriving instance Semialign Option
 deriving instance Align Option
 deriving instance Unalign Option
@@ -431,6 +484,11 @@
 deriving instance Repeat Option
 deriving instance Unzip Option
 
+-- deriving instance SemialignWithIndex () Option
+-- deriving instance ZipWithIndex () Option
+-- deriving instance RepeatWithIndex () Option
+#endif
+
 -------------------------------------------------------------------------------
 -- containers: ListLike
 -------------------------------------------------------------------------------
@@ -462,17 +520,16 @@
     nil = Seq.empty
 
 instance Unzip Seq where
-#if MIN_VERSION_containers(0,5,11)
     unzip     = Seq.unzip
     unzipWith = Seq.unzipWith
-#else
-    unzip = unzipDefault
-#endif
 
 instance Zip Seq where
     zip     = Seq.zip
     zipWith = Seq.zipWith
 
+instance SemialignWithIndex Int Seq
+instance ZipWithIndex Int Seq
+
 instance Semialign T.Tree where
     align (T.Node x xs) (T.Node y ys) = T.Node (These x y) (alignWith (these (fmap This) (fmap That) align) xs ys)
 
@@ -493,17 +550,9 @@
 -------------------------------------------------------------------------------
 
 instance Ord k => Semialign (Map k) where
-#if MIN_VERSION_containers(0,5,9)
     alignWith f = Map.merge (Map.mapMissing (\_ x ->  f (This x)))
                             (Map.mapMissing (\_ y ->  f (That y)))
                             (Map.zipWithMatched (\_ x y -> f (These x y)))
-#elif MIN_VERSION_containers(0,5,0)
-    alignWith f = Map.mergeWithKey (\_ x y -> Just $ f $ These x y) (fmap (f . This)) (fmap (f . That))
-#else
-    align m n = Map.unionWith merge (Map.map This m) (Map.map That n)
-      where merge (This a) (That b) = These a b
-            merge _ _ = oops "Align Map: merge"
-#endif
 
 instance (Ord k) => Align (Map k) where
     nil = Map.empty
@@ -517,17 +566,9 @@
     zipWith = Map.intersectionWith
 
 instance Semialign IntMap where
-#if MIN_VERSION_containers(0,5,9)
     alignWith f = IntMap.merge (IntMap.mapMissing (\_ x ->  f (This x)))
                                (IntMap.mapMissing (\_ y ->  f (That y)))
                                (IntMap.zipWithMatched (\_ x y -> f (These x y)))
-#elif MIN_VERSION_containers(0,5,0)
-    alignWith f = IntMap.mergeWithKey (\_ x y -> Just $ f $ These x y) (fmap (f . This)) (fmap (f . That))
-#else
-    align m n = IntMap.unionWith merge (IntMap.map This m) (IntMap.map That n)
-      where merge (This a) (That b) = These a b
-            merge _ _ = oops "Align IntMap: merge"
-#endif
 
 instance Align IntMap where
     nil = IntMap.empty
@@ -540,6 +581,13 @@
 instance Zip IntMap where
     zipWith = IntMap.intersectionWith
 
+instance SemialignWithIndex Int IntMap
+instance ZipWithIndex Int IntMap where
+    izipWith = IntMap.intersectionWithKey
+instance Ord k => SemialignWithIndex k (Map k) where
+instance Ord k => ZipWithIndex k (Map k) where
+    izipWith = Map.intersectionWithKey
+
 -------------------------------------------------------------------------------
 -- transformers
 -------------------------------------------------------------------------------
@@ -556,6 +604,9 @@
 instance Unzip Identity where
     unzip (Identity ~(a, b)) = (Identity a, Identity b)
 
+instance SemialignWithIndex () Identity
+instance ZipWithIndex () Identity
+instance RepeatWithIndex () Identity
 
 instance (Semialign f, Semialign g) => Semialign (Product f g) where
     align (Pair a b) (Pair c d) = Pair (align a c) (align b d)
@@ -581,7 +632,20 @@
         ~(al, ar) = unzip a
         ~(bl, br) = unzip b
 
+instance (SemialignWithIndex i f, SemialignWithIndex j g) => SemialignWithIndex (Either i j) (Product f g) where
+    ialignWith f (Pair fa ga) (Pair fb gb) = Pair fc gc where
+        fc = ialignWith (f . Left) fa fb
+        gc = ialignWith (f . Right) ga gb
 
+instance (ZipWithIndex i f, ZipWithIndex j g) => ZipWithIndex (Either i j) (Product f g) where
+    izipWith f (Pair fa ga) (Pair fb gb) = Pair fc gc where
+        fc = izipWith (f . Left) fa fb
+        gc = izipWith (f . Right) ga gb
+
+instance (RepeatWithIndex i f, RepeatWithIndex j g) => RepeatWithIndex (Either i j) (Product f g) where
+    irepeat f = Pair (irepeat (f . Left)) (irepeat (f . Right))
+
+
 instance (Semialign f, Semialign g) => Semialign (Compose f g) where
     alignWith f (Compose x) (Compose y) = Compose (alignWith g x y) where
         g (This ga)     = fmap (f . This) ga
@@ -607,22 +671,37 @@
 --     unalignWith f (Compose x) = (Compose y, Compose z) where
 --         ~(y, z) = unalignWith (uncurry These . unalignWith f) x
 
+instance (SemialignWithIndex i f, SemialignWithIndex j g) => SemialignWithIndex (i, j) (Compose f g) where
+    ialignWith f (Compose fga) (Compose fgb) = Compose $ ialignWith g fga fgb where
+        g i (This ga)     = imap (\j -> f (i, j) . This) ga
+        g i (That gb)     = imap (\j -> f (i, j) . That) gb
+        g i (These ga gb) = ialignWith (\j -> f (i, j)) ga gb
+
+instance (ZipWithIndex i f, ZipWithIndex j g) => ZipWithIndex (i, j) (Compose f g) where
+    izipWith f (Compose fga) (Compose fgb) = Compose fgc where
+        fgc = izipWith (\i -> izipWith (\j -> f (i, j))) fga fgb
+
+instance (RepeatWithIndex i f, RepeatWithIndex j g) => RepeatWithIndex (i, j) (Compose f g) where
+    irepeat f = Compose (irepeat (\i -> irepeat (\j -> f (i, j))))
+
 -------------------------------------------------------------------------------
 -- vector
 -------------------------------------------------------------------------------
 
 -- Based on the Data.Vector.Fusion.Stream.Monadic zipWith implementation
+
+-- |
+--
+-- @since 1.4
+instance Monad m => Unzip (Stream m) where
+    unzip = unzipDefault
+
 instance Monad m => Align (Stream m) where
     nil = Stream.empty
 
 instance Monad m => Semialign (Stream m) where
-#if MIN_VERSION_vector(0,11,0)
     alignWith  f (Stream stepa ta) (Stream stepb tb)
       = Stream step (ta, tb, Nothing, False)
-#else
-    alignWith  f (Stream stepa ta na) (Stream stepb tb nb)
-      = Stream step (ta, tb, Nothing, False) (Stream.larger na nb)
-#endif
       where
         step (sa, sb, Nothing, False) = do
             r <- stepa sa
@@ -640,23 +719,62 @@
                 Done -> case (av, adone) of
                     (Just x, False) -> Yield (f $ This x) (sa, sb, Nothing, adone)
                     (_, True)       -> Done
+#if __GLASGOW_HASKELL__ < 902
                     _               -> Skip (sa, sb, Nothing, False)
+#endif
 
+-- |
+--
+-- @since 1.4
+instance Monad m => Unalign (Stream m) where
+    unalign (Stream stepa s) = (Stream stepb s, Stream stepc s)
+      where
+        stepb i = do
+            r <- stepa i
+            return $ case r of
+                Done                -> Done
+                Skip              j -> Skip j
+                Yield (This  x)   j -> Yield x j
+                Yield (These x _) j -> Yield x j
+                Yield (That    _) j -> Skip j
+
+        stepc i = do
+            r <- stepa i
+            return $ case r of
+                Done                -> Done
+                Skip              j -> Skip j
+                Yield (This  _)   j -> Skip j
+                Yield (These _ y) j -> Yield y j
+                Yield (That    y) j -> Yield y j
+
 instance Monad m => Zip (Stream m) where
     zipWith = Stream.zipWith
 
-#if MIN_VERSION_vector(0,11,0)
+-- |
+--
+-- @since 1.4
+instance Monad m => Unzip (Bundle m v) where
+    unzip = unzipDefault
+
 instance Monad m => Align (Bundle m v) where
     nil = Bundle.empty
 
 instance Monad m => Semialign (Bundle m v) where
     alignWith f Bundle{sElems = sa, sSize = na} Bundle{sElems = sb, sSize = nb}
       = Bundle.fromStream (alignWith f sa sb) (Bundle.larger na nb)
-#endif
 
 instance Monad m => Zip (Bundle m v) where
     zipWith = Bundle.zipWith
 
+-- |
+--
+-- @since 1.4
+instance Monad m => Unalign (Bundle m v) where
+    unalign Bundle { sElems = xys, sSize = n } =
+        (Bundle.fromStream xs (Bundle.toMax n), Bundle.fromStream ys (Bundle.toMax n))
+      where
+        ~(xs, ys) = unalign xys
+
 instance Semialign V.Vector where
     alignWith = alignVectorWith
 
@@ -669,10 +787,22 @@
 instance Unzip V.Vector where
     unzip = V.unzip
 
+-- |
+--
+-- @since 1.4
+instance Unalign V.Vector where
+    -- TODO: it would be more efficient to do unalign imperatively.
+    unalign xys = (unstream xs, unstream ys) where
+        ~(xs, ys) = unalign (stream xys)
+
 alignVectorWith :: (Vector v a, Vector v b, Vector v c)
         => (These a b -> c) -> v a -> v b -> v c
 alignVectorWith f x y = unstream $ alignWith f (stream x) (stream y)
 
+instance SemialignWithIndex Int V.Vector where
+instance ZipWithIndex Int V.Vector where
+    izipWith = V.izipWith
+
 -------------------------------------------------------------------------------
 -- unordered-containers
 -------------------------------------------------------------------------------
@@ -693,6 +823,10 @@
 instance (Eq k, Hashable k) => Unalign (HashMap k) where
     unalign xs = (HM.mapMaybe justHere xs, HM.mapMaybe justThere xs)
 
+instance (Eq k, Hashable k) => SemialignWithIndex k (HashMap k) where
+instance (Eq k, Hashable k) => ZipWithIndex k (HashMap k) where
+    izipWith = HM.intersectionWithKey
+
 -------------------------------------------------------------------------------
 -- tagged
 -------------------------------------------------------------------------------
@@ -709,6 +843,9 @@
 instance Unzip (Tagged b) where
     unzip (Tagged ~(a, b)) = (Tagged a, Tagged b)
 
+instance SemialignWithIndex () (Tagged b)
+instance ZipWithIndex () (Tagged b)
+instance RepeatWithIndex () (Tagged b)
 
 instance Semialign Proxy where
     alignWith _ _ _ = Proxy
@@ -729,6 +866,10 @@
 
 instance Unzip Proxy where
     unzip _ = (Proxy, Proxy)
+
+instance SemialignWithIndex Void Proxy
+instance ZipWithIndex Void Proxy
+instance RepeatWithIndex Void Proxy
 
 -------------------------------------------------------------------------------
 -- combinators
diff --git a/src/Data/Zip.hs b/src/Data/Zip.hs
--- a/src/Data/Zip.hs
+++ b/src/Data/Zip.hs
@@ -50,6 +50,4 @@
     Zippy f <*> Zippy x = Zippy $ zipWith ($) f x
 #endif
 
-#if MIN_VERSION_base(4,10,0)
     liftA2 f (Zippy x) (Zippy y) = Zippy $ zipWith f x y
-#endif
