ZipList

Lists, but with an Applicative functor based on zipping.

Examples

In contrast to the Applicative for List:
>>> (+) <$> [1, 2, 3] <*> [4, 5, 6]
[5,6,7,6,7,8,7,8,9]
The Applicative instance of ZipList applies the operation by pairing up the elements, analogous to zipWithN
>>> (+) <$> ZipList [1, 2, 3] <*> ZipList [4, 5, 6]
ZipList {getZipList = [5,7,9]}
>>> (,,,) <$> ZipList [1, 2] <*> ZipList [3, 4] <*> ZipList [5, 6] <*> ZipList [7, 8]
ZipList {getZipList = [(1,3,5,7),(2,4,6,8)]}
>>> ZipList [(+1), (^2), (/ 2)] <*> ZipList [5, 5, 5]
ZipList {getZipList = [6.0,25.0,2.5]}
Lists, but with an Applicative functor based on zipping.
Lists, but with an Applicative functor based on zipping.
Similar to ZipList in base: a newtype wrapper over ListT that overrides its normal Applicative instance (combine every combination) with one that "zips" outputs together one at a time.
>>> let xs = do x <- select [1,2,3,4]; liftIO (print x)

>>> let ys = do y <- select [5,6]; liftIO (print y)

>>> runListT (xs *> ys)
1
5
6
2
5
6
3
5
6
4
5
6

>>> runListT (getZipListT (ZipListT xs *> ZipListT ys))
1
5
2
6
3
Note that the final "3" is printed even though it isn't paired with anything. While this can be used to do zipping, it is usually more convenient to just use zip. This is more useful if you are working with a function that expects "an Applicative instance", written to be polymorphic over all Applicatives.