Understanding type arguments do not conform to class type parameter bounds error when using Higher kinded type parameter

你。 提交于 2021-01-29 21:55:54

问题


I am trying to understand why the following piece of code won't compile when I use a higher kinded type parameter for T in MyModel

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[_]]

}

But if i change it to new Bar[MyModel[Any]] it will compile. Why is this ?


回答1:


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

(It should not be confused neither with Bar[MyModel[X]] forSome {type X} nor with Bar[MyModel[X forSome {type X}]], the latter is just Bar[MyModel[Any]]. These are three different types.)

Bar[MyModel[X] forSome {type X}] (aka Bar[MyModel[_]]) doesn't compile because MyModel[X] forSome {type X} (aka MyModel[_]) doesn't satisfy Bar's condition TModel <: Model[TModel]. Indeed you can check that

implicitly[(MyModel[X] forSome {type X}) <:< Model[MyModel[X] forSome {type X}]]

doesn't compile (X to the left from <:< and X to the right from <:< are not related). The thing is that skolemization of existential type on the left MyModel[X] forSome {type X}, namely MyModel[X1] is not connected to Model[MyModel[X] forSome {type X}] on the right, for invariant Model (from class MyModel[T] extends Model[MyModel[T]] it follows that MyModel[X1] <: Model[MyModel[X1]] (1), also MyModel[X1] <: (MyModel[X] forSome {type X}) (2), but for invariant Model we can't apply Model to the latter "inequality").

But if you make Model covariant abstract class Model[+M <: Model[M]] then we can apply Model to "inequality" (2), so Model[MyModel[X1]] <: Model[MyModel[X] forSome {type X}] and this along with (1) gives MyModel[X1] <: Model[MyModel[X] forSome {type X}] by transitivity. So Bar's condition is satisfied and new Bar[MyModel[_]] compiles.

Bar[MyModel[Any]] compiles because MyModel[Any] satisfies Bar's condition TModel <: Model[TModel]. Indeed MyModel[Any] <: Model[MyModel[Any]] because class MyModel[T] extends Model[MyModel[T]] (you can check that

implicitly[MyModel[Any] <:< Model[MyModel[Any]]]

compiles).



来源:https://stackoverflow.com/questions/61701021/understanding-type-arguments-do-not-conform-to-class-type-parameter-bounds-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!