2011-01-06 27 views
5

下面的Scala代碼似乎是有效的:斯卡拉類型系統中的錯誤?

class A[X] 
class C[M[X] <: A[X]] 

class Main 

new C[A] 

我希望編譯器對A型執行類型推斷,但我試過之後執行以下操作:

new C[A[Int]] 

,我得到了以下錯誤消息:

(fragment of Main.scala):11: error: this.A[Int] takes no type parameters, expected: one 
println(new C[A[Int]]) 

回答

2

你沒有申報XC類型參數。請嘗試以下操作:

class C[X, M[X] <: A[X]] 
+0

這也不會做這項工作。問題是C預期帶有類型參數的類型。當你嘗試新的C [A]時,這將會起作用,因爲A需要一個類型參數。 – tim 2011-01-06 13:19:45

+0

這不起作用 - C現在需要兩個類型參數。 – gpampara 2011-01-06 13:20:20

6

試試這個語法。

class C[M <: A[_]] 

這意味着,C是一個類,接受一種類型的參數,這應該是A的子類,並採取一種類型的參數。

15

讓我們來看看,這意味着用簡單的英語。

class A[X] 

表示:設A是一個只帶一個類型參數的類。

class C[M[X] <: A[X]] 

是指:設C是一類,它有一個類型參數,這應該是一類,它有一個類型參數,並且參數化的,是類A參數與同類型的子類。

當你寫

new C[A] 

你說:創建C的實例與作爲參數。 A是否符合上述標準?是的,它是一個接受一個類型參數的類,並且參數化它是參數化的一個子類。

但是,當你寫

new C[A[Int]] 

你試圖給C,A [INT]類型的參數,不符合標準:A [INT]不帶任何類型參數,編譯器會好好告訴你。 (它是不是A [X]的子類無論是。)

+1

這是正確的答案;我唯一要添加的東西(幫助進行網絡搜索)是這是一個更高級的類型的例子,其中C的類型參數被稱爲具有* - > *種類。相比之下,[Int]只是一種*。 – 2011-01-06 16:26:07

0

你不wan't類採取一種類型的參數,你wan't它需要兩個!兩種可能的解決方案:

class A[X] { 
    type T = X 
} 
class C[M <: A[_]] { 
    //use M#T if you want the type T was parameterized with. 
} 

或者,你可以這樣做:

class A[X] 
class C[T, M[A] <: A[A]] { 
    //when you want the type, write M[T], not M. 
} 

不過,你可能想要的是這樣的:

class A[X] 
class C[M <: A[_]] 
1

這一切都說明here,圍繞「共同陷阱「部分,因爲它相當TLTR。