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
,因为绑定是正确A
的MyTrait2
.如果有,你能给我一个例子或指出我这个代码片段错误的地方吗?
如果这是Scala编译器限制,有人能告诉我使用类型系统实现这一目的吗?注意:
MyTrait
物品,也没有物品myMethod
;myMethod
知道具体的类型A
; 它需要知道的是A
它是一个子类型,MyTrait
并且t2
是参数化的A
;obj
是故意的; 在我打电话的地方myMethod
,我不知道具体的类型A
(或者它不会是一个问题);myMethod
.您应该只在声明中对类型成员使用约束,而不是对类型参数进行限制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)