【问题标题】:map3 in scala in Parallelismscala中的map3并行
【发布时间】:2017-10-29 13:56:03
【问题描述】:
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 以及它的作用 (())?

【问题讨论】:

    标签: scala functional-programming


    【解决方案1】:

    在纯粹抽象的层面上,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,并且只有一种自然的方法可以将它们组合起来以获得最终值。

    【讨论】:

      【解决方案2】:

      前面的答案是正确的,但我发现这样想更容易:

        def map3[A, B, C, D](a: Par[A], b: Par[B], c: Par[C])(f: (A, B, C) => D): Par[D] = {
          val f1 = (a: A, b: B) => (c: C) => f(a, b, c)
          val f2: Par[C => D] = map2(a, b)(f1)
          map2(f2, c)((f3: C => D, c: C) => f3(c))
        }
      

      创建一个函数f1,它是f 的一个版本,前两个参数部分应用,然后我们可以map2 使用ab 给我们一个C => D 类型的函数在Par 上下文中 (f1)。

      最后,我们可以使用f2c 作为map2 的参数,然后将f3(C => D) 应用于c,从而在Par 上下文中为我们提供D

      希望这对某人有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-06
        • 2013-06-15
        • 1970-01-01
        • 2014-10-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多