2017-05-29 87 views
0
def map2[A,B,C] (a: Par[A], b: Par[B]) (f: (A,B) => C) : Par[C] = 
(es: ExecutorService) => { 
    val af = a (es) 
    val bf = b (es) 
    UnitFuture (f(af.get, bf.get)) 
} 

def map3[A,B,C,D] (pa :Par[A], pb: Par[B], pc: Par[C]) (f: (A,B,C) => D) :Par[D] = 
map2(map2(pa,pb)((a,b)=>(c:C)=>f(a,b,c)),pc)(_(_)) 

我有map2,需要根据map2生成map3。我在GitHub中找到了解决方案,但很难理解。任何人都可以看到它,并解释map3,这也是())?map3 in scala in Parallelism

回答

2

在纯粹抽象的层面上,map2意味着您可以并行运行两个任务,这本身就是一项新任务。为map3提供的实现是:并行运行(并行运行两个第一个任务)和(第三个任务)。

现在下降到代码:首先,让我们给名字创建的所有对象(我还延长_符号的清晰度):

def map3[A,B,C,D] (pa :Par[A], pb: Par[B], pc: Par[C]) (f: (A,B,C) => D) :Par[D] = { 
    def partialCurry(a: A, b: B)(c: C): D = f(a, b, c) 
    val pc2d: Par[C => D] = map2(pa, pb)((a, b) => partialCurry(a, b)) 
    def applyFunc(func: C => D, c: C): D = func(c) 
    map2(pc2d, pc)((c2d, c) => applyFunc(c2d, c) 
} 

现在还记得map2需要两个Par[_]和功能相结合最终值,得到Par[_]的结果。

第一次使用map2(里面的那个)时,可以将前两个任务并行化,然后将它们合并为一个函数。事实上,用f,如果你有A类型的值和B类型的值,你只需要C类型的值来构建D类型之一,所以这正是意味着partialCurry(a, b)C => D类型的函数(partialCurry本身是(A, B) => C => D)。 现在您又有了Par[_]类型的两个值,因此您可以再对map2进行设置,并且只有一种自然方法可以将它们组合起来以获得最终值。