《FP in Scala》第七章讲解如何创建用于处理并发的纯函数式库。为此,它定义了一种类型
type Par[A] = ExecutorService => Future[A]
以及一组有用的函数,如fork函数
def fork[A] (a: => Par[A]): Par[A] =
es => es.submit(new Callable[A] {
def call = a(es).get
})
其中一项练习涉及到具有以下签名的函数序列。
def sequence[A](ps: List[Par[A]]): Par[List[A]]
使用foldRight的解决方案很直接。然而,作者还包括了另外两个版本作为答案,其中一个陈述如下:
// This implementation forks the recursive step off to a new logical thread,
// making it effectively tail-recursive. However, we are constructing
// a right-nested parallel program, and we can get better performance by
// dividing the list in half, and running both halves in parallel.
// See `sequenceBalanced` below.
def sequenceRight[A](as: List[Par[A]]): Par[List[A]] =
as match {
case Nil => unit(Nil)
case h :: t => map2(h, fork(sequenceRight(t)))(_ :: _)
}
我不太确定“有效地尾递归”是什么意思。从fork的定义中可以清楚地看出它接受一个按名称传递的参数,因此map2(h, fork(sequenceRight(t)))(_ :: _)不会评估第二个参数(直到提供执行器服务)。但这并不能告诉我它为什么“有效地尾递归”。