2015-07-12 93 views
4

我有以下解析器解析含有浮球RDD算術表達式:如何解決編譯器發現Serializable而不是匹配類型時的類型不匹配?

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和唐新/噸知道如何解決這個錯誤

回答

10

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升級到factor2定義中的較大類型來修復此問題,其中pathxml.map(_.right) | num

+1

謝謝你的完整解釋。我做了建議並更改了代碼,現在我收到以下錯誤:找到類型不匹配「Product with Serializable」,爲什麼? – Rubbic

+0

@Rubbic如果您嘗試添加一個新的(可能是暫時的)'val'爲'pathxml.map會發生什麼(_。右)'?你可以輸入「Parser [Float \/RDDThing]」嗎?您可能需要使用'pathxml.map(_。right [Float])''。 –

+0

如果我添加「[浮點]」它會給我以下錯誤: 方法類型scala.util.Either.RightProjection [浮點的右,org.apache.spark.rdd.RDD [(中等,數組[浮點型]) ]]不帶類型參數。 – Rubbic