2013-08-06 14 views
6

は、私が持っていると言う:私はそれがこのようになりますようにコードを修正しかしこの型のパラメータ構文がコンパイルされない理由は何ですか?

kinds of the type arguments (cspsolver.Thing) do not conform to the expected kinds of the type parameters (type CC) in class Class. cspsolver.
Thing's type parameters do not match type CC's expected parameters: type C's bounds <: Int are stricter than type B's declared bounds >: Nothing <: Any

class Class[CC[A, B]] 
class Thing[A, B] { 
    type B <: Int 
} 
class Test extends Class[Thing] 

それは罰金コンパイル

class Class[CC[A, B]] 
class Thing[A, B <: Int] 
class Test extends Class[Thing] // compile error here 

私はコンパイラエラーを取得します。両方とも機能的に同等ではありませんか?

+5

最後の例では、パラメータ 'B'とタイプメンバー 'B'を入力しています。彼らは同じ名前(1つだけが見える)を持っている、彼らは同じではないボット。 – senia

+0

@senia、同じ名前を使用すると便利な場合はありますか? – huynhjl

+0

@huynhjl:そうは思いません。しかし、場合によってはシャドウイングが便利です。名前を再利用することができます。暗黙のうちにシャドーイングの部分的な有用な乱用もあります:[この回答](http://stackoverflow.com/a/17852226/406435)。 – senia

答えて

1

理由はコンパイラのメッセージで示されています。 Classでは、制限されていないCCが、Thingには、第2の型の引数が<: Intでなければならないという制約があります。一つの可能​​性はここでは、ペトルスキー - パドラックの説明にエラボレーション

class Class[CC[A,B <: Int]] 
class Thing[A, B <: Int] 
class Test extends Class[Thing] 
+0

なぜこの制限があるのか​​はわかりません;なぜコンパイラは2つを下限で調整できませんか? –

0

にとClassに同じ制約を追加することで、私はが起こると仮定ものです:コンパイラはThing[A, B <: Int]CC[A, B]を統一しようとします。 Bの宣言によれば、Bをインスタンス化するために選択されたAnyは、Bの上限バインドがAnyです。ただしBThingには、その上限の型にバインドされたIntがあると予想され、コンパイラはエラーメッセージが表示されて失敗します。

これは、次のスケッチに示すように、タイプシステムの健全性を維持するために必要です。あなたは文句コンパイラなし

class Test extends Class[Thing] { 
    val t: Thing 
} 

として

class Class[CC[A,B]] { 
    val c: CC 
} 

TestとしてClassを宣言した場合は、

class Thing[A, B <: Int] { 
    def f(b: B) = 2 * b 
} 

ThingはそのB <: Int、例えばその事実に依存する操作を定義すると仮定、次の電話をかけることができます

new Test().t.f(true) 

これは明らかに安全ではありません。

+0

私はあなたがなぜ "そのような型制約をコンパイルするのを許す"が失敗するのかという正当な例を持っているとは確信していませんが、コンパイルされないので、それが間違っている理由を正確に突き止めるのは難しいです。 –

+0

しかし私はとにかく試してみます: 'def f(b:B)...'は 'B <:Int'の文脈にあります。だから私はどんな状況でもそれを買わず、 'f(true)'がコンパイルされる可能性があります。 –

+0

なぜ 'new Test()。t(true)'がコンパイル時に捕まえられないのかわかりません。 'Test'では' t'型の型の型パラメータは必要ありませんか?そしてもしそれがしなかったなら、 'new Test()'は 'B <:Int'をとります。 'Boolean'は' <:Int'ではないのですか? – eddiemundorapundo

関連する問題