Scala - 路径依赖类型的下界推断

Rui*_*ves 5 scala type-inference path-dependent-type

我试图理解为什么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)
Run Code Online (Sandbox Code Playgroud)

对我来说,直观地说,MyTraitType除了a的子类之外,不能是其他任何东西MyTrait,因为绑定是正确AMyTrait2.如果有,你能给我一个例子或指出我这个代码片段错误的地方吗?

如果这是Scala编译器限制,有人能告诉我使用类型系统实现这一目的吗?注意:

  • 我没有MyTrait物品,也没有物品myMethod;
  • 我不需要myMethod知道具体的类型A; 它需要知道的是A它是一个子类型,MyTrait并且t2是参数化的A;
  • 下划线obj是故意的; 在我打电话的地方myMethod,我不知道具体的类型A(或者它不会是一个问题);
  • 我更喜欢我不需要修改的解决方案myMethod.

sen*_*nia 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)
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,您将收到错误类型的编译错误:

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)
                                        ^
Run Code Online (Sandbox Code Playgroud)

证明它适用于List[MyTrait2]

scala> for {
     |   obj <- List[MyTrait2](
     |            new MyTrait2Impl[MyTraitImpl],
     |            new MyTrait2Impl[MyTraitImpl]
     |          )
     | } myMethod[obj.MyTraitType](obj)
Hi!
Hi!
Run Code Online (Sandbox Code Playgroud)