I'm implementing reduce
method in Scala as an exercise of Functional Programming in Scala, and I don't think it is running in parallel. How can a create a fully parallel implementation of it?
def reduce[A](pas: IndexedSeq[A])(f: (A, A) => A): Par[A] =
if pas.isEmpty then throw new Exception("Can't reduce empty list")
else if pas.size == 1 then unit(pas.head)
else
val (l, r) = pas.splitAt(pas.size / 2)
reduce(l)(f).map2(reduce(r)(f))(f)
I'm using the Par
class from the book:
object Par:
opaque type Par[A] = ExecutorService => Future[A]
extension [A](pa: Par[A]) def run(s: ExecutorService): Future[A] = pa(s)
def fork[A](a: => Par[A]): Par[A] =
es => es.submit(new Callable[A] { def call = a(es).get })
def lazyUnit[A](a: => A): Par[A] = fork(unit(a))
Well, your entire computation finishes without ever fork
ing, so everything runs linearly, nothing runs in parallel. Did you try
fork(reduce(l)(f)).map2(fork(reduce(r)(f)))(f)
or
else fork {
val (l, r) = pas.splitAt(pas.size / 2)
reduce(l)(f).map2(reduce(r)(f))(f)
}
?