当编译器找到可序列化而不是匹配类型时,如何解决类型不匹配?

How to solve type mismatch when compiler finds Serializable instead of the match type?

我有以下解析器来解析包含 Float 和 RDD 的算术表达式:

 import scalaz._
 import Scalaz._

 def term2: Parser[List[\/[Float, RDD[(Int,Array[Float])]]]] = rep(factor2)
 def factor2: Parser[\/[Float, RDD[(Int,Array[Float])]]] = pathxml | num
 def pathxml: Parser[ RDD[(Int,Array[Float])]] = pathIdent ^^ { s => pathToRDD(s)} //pathToRDD is a function that gets the path in string and create an RDD from the file inside that path and pathIdent parse to see whether the input string is a path or not
 def num: Parser[\/[Float, RDD[(Int,Array[Float])]]] = floatingPointNumber ^^ (n => n.left[RDD[(Int,Array[Float])]].toFloat)

出现以下错误:

  [error]  type mismatch;   
  [error]  found   : ParseExp.this.Parser[Serializable]
  [error]  required: ParseExp.this.Parser[scalaz.\/[Float,org.apache.spark.rdd.RDD[(Int, Array[Float])]]]
  [error]   def factor2: Parser[\/[Float, RDD[(Int,Array[Float])]]] = pathxml | num
  [error]                                                                     ^

我是 Scala 的新手,don/t 知道如何解决这个错误

Serializable(或类似的 Product,或两者一起)几乎总是表明您试图将两种类型视为相同,而实际上它们并不相同。例如:

scala> if (true) "a" else List(1)
res0: java.io.Serializable = a

条件表达式的类型是其两个分支类型的最小上限——即分支机构共有的最具体的类型。这里我们有一个 String 和一个 List[Int],它们都是 AnyRef 的实例,但除了 Serializable 之外没有任何共同点。它们都是 Serializable 的事实比它们都是 AnyRef 的子类型这一事实更具体,所以这是推断的类型。

序列的类型推断类似:

scala> List("a", "b", "c", 'd)
res1: List[java.io.Serializable] = List(a, b, c, 'd)

一般来说,只要您看到 Serializable,您就应该开始寻找与其邻居或兄弟姐妹类型不同的东西。

在您的情况下,pathxml | num 将是 Parser[RDDThing]Parser[Float \/ RDDThing] 的最小上限,这又是 Parser[Serializable]。您应该能够通过使用 pathxml.map(_.right) | num.

pathxml 提升到 factor2 定义中的较大类型来解决此问题