对于以下方法转换系列,Intellij
IDE似乎"理解"发生了什么:它没有记录任何错误/警告并正确显示数据类型:
val recsWithNames = recsWithNamesAndCnts.map(_._1)
.reduceLeft{ case (dfCum: DataFrame,dfNew: DataFrame) => dfCum.union(dfNew)}
以下是type inference
:
但是它没有编译:
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
的特定细微差别提供一些见解。
答案 0 :(得分:3)
reduceLeft
和foldLeft
具有以下签名:
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) }