liveBook · Manning

Ziplist

As explained in Functional Programming in Scala, Second Edition

ZipList is a wrapper type whose applicative combines corresponding elements of sequences rather than forming their Cartesian product.

ZipList is a wrapper around LazyList that gives sequences a zipping applicative: map2 combines elements at corresponding positions instead of producing every pair. section 12.4.1

Its applicative behavior follows two defining operations:

  • unit creates an infinite sequence by repeating its argument with LazyList.continually. section 12.4.1
  • map2 zips two sequences and maps the combining function over corresponding pairs. section 12.4.1
  • The wrapper selects this behavior when ordinary LazyList also has a Cartesian-product applicative; no compatible flatMap or join can define the same behavior. section 12.4.1

Corresponding elements

For ZipList values containing 1, 2, 3 and 'a', 'b', map2 produces (1, 'a') and (2, 'b'); it does not produce all six combinations. section 12.4.1

opaque type ZipList[+A] = LazyList[A]
object ZipList:
  def fromLazyList[A](la: LazyList[A]): ZipList[A] = la
  extension [A](za: ZipList[A]) def toLazyList: LazyList[A] = za
 
  given zipListApplicative: Applicative[ZipList] with
    def unit[A](a: => A): ZipList[A] =
      LazyList.continually(a)
    extension [A](fa: ZipList[A])
      override def map2[B, C](fb: ZipList[B])(f: (A, B) => C) =
        fa.zip(fb).map(f.tupled)

The implementation shows the opaque wrapper, conversions to and from LazyList, and the given applicative that fixes zipping semantics. section 12.4.1

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Defines unit, map2, wrapping, and the incompatibility with monadic flatMap, but leaves sequence as an exercise.
Examples
Contrasts Cartesian-product LazyList combination with positional zipping and shows the ZipList wrapper implementation.
What it assumes
Assumes LazyList and applicative operations such as unit and map2, while contrasting them with monadic flatMap.
What you can do after
Build it from scratch using an opaque LazyList wrapper and a zipping Applicative instance.
How it connects
Connects applicative functors, LazyList, map2, flatMap, join, and sequence.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Programming in Scala, Second Edition. The section links point to the parts of the book it draws on.