Parallel map2 combines two independent Par computations with a binary function, producing a new Par rather than extracting either result. Its general shape is pa.map2(pb)(f): Par[C], where pa yields A, pb yields B, and f combines A and B into C. Keeping the result inside Par avoids calling run during composition. section 7.1.2 section 7.2
The key design question is evaluation order. A strict map2 follows Scala’s left-to-right argument evaluation, expanding the entire left branch of a recursive sum before considering the right. That conflicts with the intended meaning: the two inputs represent work that can be evaluated in parallel, with neither side privileged by argument order. section 7.1.2
def sum(ints: IndexedSeq[Int]): Par[Int] =
if ints.size <= 1 then
Par.unit(ints.headOption.getOrElse(0))
else
val (l, r) = ints.splitAt(ints.size / 2)
Par.map2(sum(l), sum(r))(_ + _)
A divide-and-combine sum makes the role of map2 concrete: each recursive half returns Par[Int], and map2 adds their eventual results without running them directly. section 7.1.2
map2 is also the primitive from which map can be derived. Pair a computation with unit(()) and ignore the second value; then a function A => B transforms Par[A] into Par[B]. This lets a sorting request remain a Par[List[Int]] rather than running, sorting, and repackaging the list. section 7.2.1
The same combination pattern supports several useful operations:
- Define equality of two parallel computations as a Par[Boolean] with p.map2(p2)(_ == _), then run only the combined comparison. section 8.2.3
- Support parMap by asynchronously lifting each element computation and sequencing the resulting List[Par[B]]. section 7.2.1
- Combine an ExecutorService generator and an input generator when property-testing parallel computations across execution strategies. section 8.2.3
Comparing parallel results
Instead of running both sides separately, equal(Par.unit(1).map(_ + 1), Par.unit(2)) builds one Par[Boolean] through map2. A property can then run that single value under generated executor services. section 8.2.3
