2011-01-06 16 views
5

次Scalaのコードは有効であると思わ: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

あなたはCの型パラメータとしてXを宣言していません。以下を試してください:

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

これはどちらでもできません。問題は、Cが型パラメータを持つ型を期待していることです。新しいC [A]を試してみると、Aは型引数を取るので、これはうまくいくはずです。 – tim

+0

これは動作しません - Cは2つの型パラメータを期待しています。 – gpampara

6

この構文を試してみてください。

class C[M <: A[_]] 

これは、CはAのサブクラスでなければならない一種類のパラメータを取得し、いずれかのタイプのパラメータを取るクラスであることを意味します。

15

これは単純な英語の意味を見てみましょう。

class A[X] 

は、1つのタイプパラメータを取るクラスであるとする。

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

手段:Cは、一種類のパラメータと、パラメータをとるクラスでなければならない一種類のパラメーターを、かかるクラスであるものとする、同じタイプのパラメータ化クラスのサブクラスです。あなたは

new C[A] 

を書くとき

あなたは言っている:としてパラメータを使用してCのインスタンスを作成します。 Aは上記の基準に適合していますか?はい、それは1つの型パラメータをとり、それがパラメータ化されたそれ自身のサブクラスであるパラメータ化されたクラスです。あなたがCを与えるためにしようとしているタイプのパラメータ

new C[A[Int]] 

を書くとき

しかし、A [int]は、基準に適合しない:[int]は任意の型パラメータを取りません、コンパイラから親切に伝えられます。 (そして、それはA [X]のサブクラスでもありません)

+1

これは正解です。私が(ウェブ検索を助けるために)追加する唯一のものは、これがより類のない型の例であり、Cの型パラメータがkind * - > *を持つと言われるということです。対照的に[Int]は単にkind *を持っています。 –

+0

「C」の代わりに「A」を意味しましたか? 'A [Int]'は種類が '*'ですが、Aは '* - > *'でなければなりません。 'C'は'(* - > *) - > * 'でなければなりません。 – Emre

0

あなたのクラスは1つの型パラメータを取ることを嫌うわけではありません。 2つの解決策:あなたが行うことができます

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[_]] 
+0

これを簡単にするために、java: class A {...} //と同等です。 クラスC > {...} // first。しかし完璧ではありません。 //秒はできません。 – Anonymous

1

これは、すべてのhereを説明しています、「共通に注力それはかなりのTLTRだから落とし穴のセクション。