缺少reduceLeft扩展函数的参数类型

时间:2018-05-14 03:30:16

标签: scala

对于以下方法转换系列,Intellij IDE似乎"理解"发生了什么:它没有记录任何错误/警告并正确显示数据类型:

  val recsWithNames = recsWithNamesAndCnts.map(_._1)
  .reduceLeft{ case (dfCum: DataFrame,dfNew: DataFrame) => dfCum.union(dfNew)}

以下是type inference

enter image description here

但是它没有编译:

Error:(426, 68) missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: (?, org.apache.spark.sql.DataFrame) => ?
      val recsWithNames = recsWithNamesAndCnts.map(_._1).reduceLeft{ case (dfCum: DataFrame,dfNew: DataFrame) => dfCum.union(dfNew)}

这是reduceLeft的一种模式,所以我通常最终转换为foldLeft。特别是以下 工作:

  val dfs = recsWithNamesAndCnts.map(_._1)
  val recsWithNames = dfs.tail.foldLeft(dfs.head){ case (dfCum: DataFrame,dfNew: DataFrame) => dfCum.union(dfNew)}

但也许在这种情况下,有人可能会对导致此错误的reduceLeft的特定细微差别提供一些见解。

1 个答案:

答案 0 :(得分:3)

reduceLeftfoldLeft具有以下签名:

def reduceLeft[B >: A](op: (B, A) => B): B

def foldLeft[B](z: B)(op: (B, A) => B): B

两者都涉及op Function2,因此两者都可以在没有case匹配的情况下正常工作:

(dfCum: DataFrame, dfNew: DataFrame) => dfCum.union(dfNew)

// Or, shorthanded to: 

_ union _

另一方面,case (dfCum, dfNew) => dfCum.union(dfNew)Function1(特别是Tuple2的部分功能)。编译器能够解释它并在B中推断出类型foldLeft,但不能在reduceLeft中推断(我猜是由于B >: A)。如果你帮助编译器,它将起作用:

reduceLeft[DataFrame]{ case (dfCum, dfNew) => dfCum.union(dfNew) }