zip package:universum

zip takes two lists and returns a list of corresponding pairs.
>>> zip [1, 2] ['a', 'b']
[(1,'a'),(2,'b')]
If one input list is shorter than the other, excess elements of the longer list are discarded, even if one of the lists is infinite:
>>> zip [1] ['a', 'b']
[(1,'a')]

>>> zip [1, 2] ['a']
[(1,'a')]

>>> zip [] [1..]
[]

>>> zip [1..] []
[]
zip is right-lazy:
>>> zip [] undefined
[]

>>> zip undefined []
*** Exception: Prelude.undefined
...
zip is capable of list fusion, but it is restricted to its first list argument and its resulting list.
zip3 takes three lists and returns a list of triples, analogous to zip. It is capable of list fusion, but it is restricted to its first list argument and its resulting list.
zipWith generalises zip by zipping with the function given as the first argument, instead of a tupling function.
zipWith (,) xs ys == zip xs ys
zipWith f [x1,x2,x3..] [y1,y2,y3..] == [f x1 y1, f x2 y2, f x3 y3..]
For example, zipWith (+) is applied to two lists to produce the list of corresponding sums:
>>> zipWith (+) [1, 2, 3] [4, 5, 6]
[5,7,9]
zipWith is right-lazy:
>>> let f = undefined

>>> zipWith f [] undefined
[]
zipWith is capable of list fusion, but it is restricted to its first list argument and its resulting list.
The zipWithM function generalizes zipWith to arbitrary applicative functors.
zipWithM_ is the extension of zipWithM which ignores the final result.
Lists, but with an Applicative functor based on zipping.
unzip transforms a list of pairs into a list of first components and a list of second components.
>>> unzip []
([],[])

>>> unzip [(1, 'a'), (2, 'b')]
([1,2],"ab")
The unzip3 function takes a list of triples and returns three lists, analogous to unzip.
>>> unzip3 []
([],[],[])

>>> unzip3 [(1, 'a', True), (2, 'b', False)]
([1,2],"ab",[True,False])
The mapAndUnzipM function maps its first argument over a list, returning the result as a pair of lists. This function is mainly used with complicated data structures or a state monad.