6

我有以下解析器来解析包含 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 新手,不知道如何解决这个错误

4

1 回答 1

18

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

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

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

类似地推断出序列的类型:

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

一般来说,任何时候你看到Serializable,你都应该开始寻找类型与其邻居或兄弟姐妹不同的东西。

在您的情况下,这将是andpathxml | num的最小上限,这又是。您应该能够通过在定义中使用更大的类型来解决此问题。Parser[RDDThing]Parser[Float \/ RDDThing]Parser[Serializable]pathxmlfactor2pathxml.map(_.right) | num

于 2015-07-12T21:57:10.727 回答