2016-12-05 18 views

答えて

8

コンパイラの一つの特定のインスタンスに属するTはS#Ttestの引数として使用できることがない十分な証拠を持っています具体的には

のでB[A2]が正確Integer独自のtest実装

ためのあなたがコンクリートをキャッチすることができます<: AnyRefA3しばらくニーズであるものと一緒にA3のインスタンスを受け入れるべき弱体化Scalaのコンパイラ

trait A2 extends A{ 
    type T <: AnyRef 
} 

class A3 extends A2{ 
    override type T = Integer 

    def test(t: Integer): Unit = println(t * 2) 
} 

ため、このhypotecical例を考えてみましょうBの定義を入力し、使用するタイプを確認してください

case class B[S <: A, ST](a: S {type T = ST}, t: ST) { 
    def test() = a.test(t) 
} 
+2

しかし、 'B [A2](新しいA3()、") 'はコンパイルされません...それは私のコードでどういう意味ですか? そうしないと、あなたのソリューションはまさに私が必要としていたものです。 – JbGi

+0

ハ、巧妙なトリック!私は、洗練された右手の視界にタイプパラメータを使用できるかどうかはわかりませんでした。 – Haspemulator

+0

@JbGiはい、私は実際にコンパイルする例でこれを実証する方法をたくさん考えましたが、ここではscalaコンパイラは非常に制限的です。これは、元のソースをコンパイルすることができる仮想のscalaのようなコンパイラの想像上の例であるようにしておきましょう。 – Odomontois

2

私は、エンコーディング(簡略化のために型パラメータを削除)を思い付くことができます:

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

def test0(a: A)(t : a.T) = a.test(t) 

abstract class B{ 
    val a: A 
    val t: a.T 
    def test = a.test(t) 
} 

// Exiting paste mode, now interpreting. 

test0: (a: A)(t: a.T)Unit 
defined class B 

これは、一方ケースクラスの引数(もそのことについては、クラス)で動作しませんでした。あなたのエンコーディングが動作しない理由の

ワン:(A#T対)

scala> def test1(a: A)(t : A#T) = a.test(t) 
<console>:12: error: type mismatch; 
found : t.type (with underlying type A#T) 
required: a.T 
     def test1(a: A)(t : A#T) = a.test(t) 

重要な部分がrequired: a.Tです。 Aのテスト方法は、それがT this.T、かかる換言すれば、任意のTを取らない、A.

+0

をありがとう!それが私の理解を助けました!だから 'a.T'は「パス依存型」と呼ばれるものです。 – JbGi

+0

正確には、パスに依存するタイプです。 – pedrofurla

1

代わりにあなたが依存の型a.T使用できるタイプの投影:

trait A { 
    type T 
    def test(t: T): Unit 
} 

case class B[S <: A](a: S)(t : a.T) { 
    def test() = a.test(t) 
} 
関連する問題