zip package:semialign

Combines two structures by taking the intersection of their shapes and using pair to hold the elements.
Functors supporting a zip operation that takes the intersection of non-uniform shapes. Minimal definition: either zip or zipWith. Idempotency
join zip   ≡ fmap (join (,))
Commutativity
zip x y ≡ swap <$> zip y x
Associativity
zip x (zip y z) ≡ assoc <$> zip (zip x y) z
Absorption
fst    <$> zip xs (align xs ys) ≡ xs
toThis <$> align xs (zip xs ys) ≡ This <$> xs
where
toThis (This a)    = This a
toThis (These a _) = This a
toThis (That b)    = That b
With
zipWith f a b ≡ f <$> zip a b
Functoriality
zip (f <$> x) (g <$> y) ≡ bimap f g <$> zip x y
Zippyness
fmap fst (zip x x) ≡ x
fmap snd (zip x x) ≡ x
zip (fmap fst x) (fmap snd x) ≡ x
Distributivity
align (zip xs ys) zs ≡ undistrThesePair <$> zip (align xs zs) (align ys zs)
distrPairThese <$> zip (align xs ys) zs ≡                      align (zip xs zs) (zip ys zs)
zip (align xs ys) zs ≡ undistrPairThese <$> align (zip xs zs) (zip ys zs)
Note, the following doesn't hold:
distrThesePair <$> align (zip xs ys) zs ≢ zip (align xs zs) (align ys zs)
when xs = [] and ys = zs = [0], then the left hand side is "only" [(That 0, That 0)], but the right hand side is [(That 0, These 0 0)].
Zipping and unzipping of functors with non-uniform shapes.
Combines two structures by taking the intersection of their shapes and combining the elements with the given function.
Indexed version of Zip.
Left-padded zip.
Left-padded zipWith.
Align two structures as in zip, but filling in blanks with Nothing.
Align two structures as in zipWith, but filling in blanks with Nothing.
Right-padded zip.
Right-padded zipWith.
Right inverse of zip. This class is definable for every Functor. See unzipDefault.

Laws

uncurry zip (unzip xs) ≡ xs
unzip (zip xs xs) ≡ (xs, xs)
Note:
unzip (zip xs ys) ≢ (xs, _) or (_, ys)
For sequence-like types this holds, but for Map-like it doesn't.
Analogous to zipWith, but also provides an index.