2012-05-16 95 views
6

我想參數化一些非常一般的類型參數的方法。斯卡拉類型:最小上界

作爲一個例子,在REPL我首先定義:

trait Term 
case class FunctionalTerm[+T <: Term](t: T) extends Term 

直觀地說,下面的方法以一個期限和一個FunctionalTerm,並返回一些與類型的最小上界通過術語的類型和FunctionalTerm的參數類型:

def ex1[T1 <: Term, T3 <: X, FunctionalTerm[T1] <: X, X <: R, R <: Term](t1: FunctionalTerm[T1], s: T3): R = sys.error("TODO") 

到目前爲止,在REPL中這麼好。

然後我定義ex2作爲進行相同的操作,ex1一個方便的功能,但與輸入參數交換:

def ex2[T2 <: Term, T3 <: X, FunctionalTerm[T2] <: X, X <: R, R <: Term](s: T3, t2: FunctionalTerm[T2]): R = ex1(t2,s) 

試圖在REPL定義ex2提供了以下錯誤:

error: inferred type arguments [T2,T3,FunctionalTerm,T3,T3] do not conform to method ex1's type parameter bounds [T1 <: Term,T3 <: X,FunctionalTerm[T1] <: X,X <: R,R <: Term] 
     ex1(t2,s) 
     ^
error: type mismatch; 
found : FunctionalTerm[T2] 
required: FunctionalTerm[T1] 
     ex1(t2,s) 
      ^
error: type mismatch; 
found : T3(in method ex2) 
required: T3(in method ex1) 
     ex1(t2,s) 
       ^
error: type mismatch; 
found : R(in method ex1) 
required: R(in method ex2) 
     ex1(t2,s) 
      ^

我花了大約兩天的時間試圖找出解決方案,現在我完全陷入困境。我無法在Google上找到更多內容。

由於ex2類型參數列表相同的ex1T1T2交換,我不明白的是錯的,或如何解決它。

任何幫助將非常感激!

更新

最小上界是一個紅色的鯡魚。該示例可以進一步提煉。

以下兩個功能可以在REPL中定義而不會出現錯誤:

def ex1[T1 <: Term, FunctionalTerm[T1] <: Term](t1: FunctionalTerm[T1]): Term = sys.error("TODO: ex1") 
def ex2[T2 <: Term, FunctionalTerm[T2] <: Term](t2: FunctionalTerm[T2]): Term = ex1(t2) 

介紹額外的參數X似乎會導致問題。我可以定義在REPL如下:

def ex3[T1 <: Term, FunctionalTerm[T1] <: X, X <: Term](t1: FunctionalTerm[T1]): Term = sys.error("TODO: ex3") 

但嘗試之後定義:

def ex4[T2 <: Term, FunctionalTerm[T2] <: X, X <: Term](t2: FunctionalTerm[T2]): Term = ex3(t2) 

給出了錯誤:

error: inferred type arguments [T2,FunctionalTerm,Nothing] do not conform to method ex3's type parameter bounds [T1 <: Term,FunctionalTerm[T1] <: X,X <: Term] 
     def ex4[T2 <: Term, FunctionalTerm[T2] <: X, X <: Term](t2: FunctionalTerm[T2]): Term = ex3(t2) 
                          ^
error: type mismatch; 
found : FunctionalTerm[T2] 
required: FunctionalTerm[T1] 
     def ex4[T2 <: Term, FunctionalTerm[T2] <: X, X <: Term](t2: FunctionalTerm[T2]): Term = ex3(t2) 
                           ^

所以,我想這個問題就變成了:爲什麼簽名中未使用的參數X是否具有此效果?

+0

我忘了說,我使用Scala的2.10-M3。 –

+0

雖然你沒有使用更高的類型:-) –

+0

@oxbow_lakes哦......我會更正 –

回答

5

我不確定你是否遇到了錯誤,但我確定你讓你的生活變得更加困難。你可以依靠協方差和統一做一切爲你努力工作,

scala> trait Term 
defined trait Term 

scala> case class FunctionalTerm[+T <: Term](t: T) extends Term 
defined class FunctionalTerm 

scala> def ex1[T <: Term](t1 : FunctionalTerm[T], s : T) : T = s 
ex1: [T <: Term](t1: FunctionalTerm[T], s: T)T 

scala> class A extends Term ; class B extends A ; class C extends A 
defined class A 
defined class B 
defined class C 
scala> ex1(new FunctionalTerm(new B), new C) 
res0: A = [email protected] 

注推斷結果類型(即相當於原來的更復雜的定義的R)......這是A這是LUB的BC

現在被翻動的版本是微不足道,只是作品,

scala> def ex2[T <: Term](s : T, t1 : FunctionalTerm[T]) : T = s 
ex2: [T <: Term](s: T, t1: FunctionalTerm[T])T 

scala> ex2(new C, new FunctionalTerm(new B)) 
res1: A = [email protected] 
+1

事實證明,報告的行爲不是一個錯誤。在原始示例中使用FunctionalTerm [T1] <:X和FunctionalTerm [T2] <:X聲明瞭一個名爲「FunctionalTerm」的方法類型參數,該參數與具有相同名稱的案例類無關。不過,我將其標記爲答案,因爲提出的建議達到了我需要做的。 –

+0

呃! ...令人驚訝的是我和@oxbow_lakes都沒有注意到! –

2

我打算簡化你的例子(我使用2.9。1):

scala> trait Term; case class FunctionalTerm[+T <: Term](t: T) extends Term; 
defined trait Term 
defined class FunctionalTerm 

scala> def ex1[T1 <: Term, T3 <: X, FunctionalTerm[T1] <: X, X <: R, R <: Term](t1: FunctionalTerm[T1], s: T3): R = sys.error("TODO") 
ex1: [T1 <: Term, T3 <: X, FunctionalTerm[T1] <: X, X <: R, R <: Term](t1: FunctionalTerm[T1], s: T3)R 

現在宣佈第二個方法:

scala> def ex2[T2 <: Term, T3 <: X, FunctionalTerm[T2] <: X, X <: R, R <: Term](s: T3, t2: FunctionalTerm[T2]): R = ex1(t2, s) 
<console>:11: error: inferred type arguments [T2,T3,FunctionalTerm,T3,T3] do not conform to method ex1's type parameter bounds [T1 <: Term,T3 <: X,FunctionalTerm[T1] <: X,X <: R,R <: Term] 
     def ex2[T2 <: Term, T3 <: X, FunctionalTerm[T2] <: X, X <: R, R <: Term](s: T3, t2: FunctionalTerm[T2]): R = ex1(t2, s) 
                                ^

可疑的事情(我)是推斷類型[T2,T3,FunctionalTerm,T3,T3] - 尤其是FunctionalTermFunctionalTerm是一個類型的構造函數* -> *但該方法預計在此位置的類型爲*

我會說,這是(大概)一個bug,因此你應該將其提交到斯卡拉用戶郵件列表(撫養票前) - 阿德里安摩爾萬里薩賓更可能有關於我是否正確的詳細答案。

+0

非常感謝 - 我懷疑這是一個錯誤,但是我對類型的瞭解有限,這讓我非常謹慎。當我解決問題時我會更新。 –