5

Scala コンパイラーがパス依存型に対する次の制限を推論できない理由を理解しようとしています。

trait MyTrait
class MyTraitImpl extends MyTrait
trait MyTrait2[A <: MyTrait] {
  type MyTraitType = A
}
class MyTrait2Impl[A <: MyTrait] extends MyTrait2[A]

val obj: MyTrait2[_] = new MyTrait2Impl[MyTraitImpl]

def myMethod[A <: MyTrait](t2: MyTrait2[A]) = println("Hi!")

myMethod[obj.MyTraitType](obj)
// <console>:14: error: type arguments [obj.MyTraitType] do not conform to method myMethod's type parameter bounds [A <: MyTrait]
//               myMethod[obj.MyTraitType](obj)

私にとっては、直観的には、MyTraitTypea のサブクラス以外のものになることはできません。ある場合は、例を挙げていただくか、このコード スニペットのどこが間違っているかを教えていただけますか?MyTraitAMyTrait2

これが Scala コンパイラの制限である場合、型システムを使用してこれを達成する方法を誰か教えてもらえますか? ご了承ください:

  • 私はMyTrait物を持っていませんしmyMethod、受け取っていません。
  • ;myMethodの具体的な型を知る必要はありません。A知る必要があるのは、Aそれが のサブタイプでMyTraitあり、t2でパラメータ化されていることだけAです。
  • のアンダースコアobjは意図的なものです。どこで を呼び出すmyMethodか、の具体的な型がわからないA(そうでなければ問題にならない);
  • 変更する必要のないソリューションを好みますmyMethod
4

2 に答える 2

3

MyTrait2宣言の型パラメーターの境界ではなく、型メンバーの制約を使用する必要があります。

trait MyTrait
class MyTraitImpl extends MyTrait
trait MyTrait2 { // Remove [A <: MyTrait]
  type MyTraitType <: MyTrait // add <: MyTrait
}
class MyTrait2Impl[A <: MyTrait] extends MyTrait2 { type MyTraitType = A }

val obj: MyTrait2 = new MyTrait2Impl[MyTraitImpl]

def myMethod[A <: MyTrait](t2: MyTrait2{ type MyTraitType = A }) = println("Hi!")

myMethod[obj.MyTraitType](obj)

予想どおり、間違った型でコンパイル エラーが発生します。

scala> val otherObj: MyTrait2 = new MyTrait2Impl[MyTraitImpl]
otherObj: MyTrait2 = MyTrait2Impl@8afcd0c

scala> myMethod[obj.MyTraitType](otherObj)
<console>:15: error: type mismatch;
 found   : otherObj.type (with underlying type MyTrait2)
 required: MyTrait2{type MyTraitType = obj.MyTraitType}
              myMethod[obj.MyTraitType](otherObj)
                                        ^

それが動作することの証明List[MyTrait2]

scala> for {
     |   obj <- List[MyTrait2](
     |            new MyTrait2Impl[MyTraitImpl],
     |            new MyTrait2Impl[MyTraitImpl]
     |          )
     | } myMethod[obj.MyTraitType](obj)
Hi!
Hi!
于 2013-08-07T11:56:50.980 に答える