使用更高种类的类型参数时,了解类型参数不符合类类型参数界限错误

时间:2020-05-09 17:37:15

标签: scala generics existential-type f-bounded-polymorphism

我试图理解为什么当我在MyModel中为T使用更高种类的类型参数时,下面的代码为何无法编译

abstract class Model[M <: Model[M]]

class MyModel[T] extends Model[MyModel[T]]

class Bar[TModel <: Model[TModel]]

object Foo extends App {

  new Bar[MyModel[_]]

}

但是如果我将其更改为new Bar[MyModel[Any]],它将进行编译。为什么会这样?

1 个答案:

答案 0 :(得分:4)

Bar[MyModel[_]] is Bar[MyModel[X] forSome {type X}]

(不要与Bar[MyModel[X]] forSome {type X}Bar[MyModel[X forSome {type X}]](后者is just Bar[MyModel[Any]]混淆。这是三种不同的类型。)

Bar[MyModel[X] forSome {type X}](又名Bar[MyModel[_]])无法编译,因为MyModel[X] forSome {type X}(又名MyModel[_])不满足Bar的条件{{1} }。实际上,您可以检查

TModel <: Model[TModel]

不编译(与implicitly[(MyModel[X] forSome {type X}) <:< Model[MyModel[X] forSome {type X}]] 左边的X<:<右边的X无关)。 The thing is表示<:<位于左侧MyModel[X] forSome {type X}的存在类型MyModel[X1]未连接到右侧的Model[MyModel[X] forSome {type X}](对于不变Model(从class MyModel[T] extends Model[MyModel[T]]得出MyModel[X1] <: Model[MyModel[X1]](1),还有MyModel[X1] <: (MyModel[X] forSome {type X})(2),但是对于不变的Model,我们不能将Model应用于后者“不平等”)。

但是,如果您使Model协变abstract class Model[+M <: Model[M]],那么我们可以将Model应用于“不等式”(2),因此Model[MyModel[X1]] <: Model[MyModel[X] forSome {type X}]以及与(1)一起得到{ {1}}的传递性。因此MyModel[X1] <: Model[MyModel[X] forSome {type X}]的条件得到满足,并且Bar得以编译。

new Bar[MyModel[_]]之所以编译,是因为Bar[MyModel[Any]]满足MyModel[Any]的条件Bar。确实TModel <: Model[TModel]是因为MyModel[Any] <: Model[MyModel[Any]](您可以检查

class MyModel[T] extends Model[MyModel[T]]

编译)。

相关问题