2017-05-29 141 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進行設置,並且只有一種自然方法可以將它們組合起來以獲得最終值。