使用更高种类的类型参数时,理解类型参数不符合 class 类型参数边界错误
Understanding type arguments do not conform to class type parameter bounds error when using Higher kinded type parameter
我试图理解为什么当我在 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]]
它会编译。这是为什么?
Bar[MyModel[_]]
is Bar[MyModel[X] forSome {type X}]
.
(不要和Bar[MyModel[X]] forSome {type X}
混淆,也不要和[=15=混淆,后者是is justBar[MyModel[Any]]
,这是三种不同的类型。)
Bar[MyModel[X] forSome {type X}]
(又名 Bar[MyModel[_]]
)无法编译,因为 MyModel[X] forSome {type X}
(又名 MyModel[_]
)不满足 Bar
的条件 TModel <: Model[TModel]
。事实上,你可以检查
implicitly[(MyModel[X] forSome {type X}) <:< Model[MyModel[X] forSome {type X}]]
不编译(<:<
左侧的 X
和 <:<
右侧的 X
不相关)。 The thing is that skolemization左边的存在类型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
应用于后者 "inequality")。
但是如果你让 Model
协变 abstract class Model[+M <: Model[M]]
那么我们可以将 Model
应用到 "inequality" (2),所以 Model[MyModel[X1]] <: Model[MyModel[X] forSome {type X}]
和这个连同 ( 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]]
(你可以检查
implicitly[MyModel[Any] <:< Model[MyModel[Any]]]
编译)。
我试图理解为什么当我在 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]]
它会编译。这是为什么?
Bar[MyModel[_]]
is Bar[MyModel[X] forSome {type X}]
.
(不要和Bar[MyModel[X]] forSome {type X}
混淆,也不要和[=15=混淆,后者是is justBar[MyModel[Any]]
,这是三种不同的类型。)
Bar[MyModel[X] forSome {type X}]
(又名 Bar[MyModel[_]]
)无法编译,因为 MyModel[X] forSome {type X}
(又名 MyModel[_]
)不满足 Bar
的条件 TModel <: Model[TModel]
。事实上,你可以检查
implicitly[(MyModel[X] forSome {type X}) <:< Model[MyModel[X] forSome {type X}]]
不编译(<:<
左侧的 X
和 <:<
右侧的 X
不相关)。 The thing is that skolemization左边的存在类型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
应用于后者 "inequality")。
但是如果你让 Model
协变 abstract class Model[+M <: Model[M]]
那么我们可以将 Model
应用到 "inequality" (2),所以 Model[MyModel[X1]] <: Model[MyModel[X] forSome {type X}]
和这个连同 ( 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]]
(你可以检查
implicitly[MyModel[Any] <:< Model[MyModel[Any]]]
编译)。