【问题标题】:Understanding type arguments do not conform to class type parameter bounds error when using Higher kinded type parameter使用更高种类的类型参数时,理解类型参数不符合类类型参数边界错误
【发布时间】:2020-05-09 17:37:15
【问题描述】:

我试图理解为什么当我在 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]],它将编译。这是为什么呢?

【问题讨论】:

  • 它不必是Any,你可以将它设为new Bar[MyModel[Int]],它会编译。我认为声明新对象时不能使用通配符,但我可能错了
  • 这能回答你的问题吗? scala - Any vs underscore in generics
  • @user 通配符不能用于第一级,例如new Some[_](???)(因为 Some[_] 不是类类型)但可以更深入地使用,例如new Some[Option[_]](???)(因为Some[T]是一个类类型,T=Option[_]是一个类型)。
  • @DmytroMitin 这很有趣。为什么Option[_] 有通配符时会被视为类型?
  • @user 因为它是一种存在类型,即类型scala-lang.org/files/archive/spec/2.13/…

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


【解决方案1】:

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

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

Bar[MyModel[X] forSome {type X}](又名Bar[MyModel[_]])无法编译,因为MyModel[X] forSome {type X}(又名MyModel[_])不满足Bar的条件TModel &lt;: Model[TModel]。确实可以检查一下

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

不编译(&lt;:&lt; 左侧的X&lt;:&lt; 右侧的X 不相关)。 The thing is 左侧存在类型的skolemization MyModel[X] forSome {type X},即MyModel[X1] 没有连接到右侧的Model[MyModel[X] forSome {type X}],对于不变的Model(从class MyModel[T] extends Model[MyModel[T]] 得出MyModel[X1] &lt;: Model[MyModel[X1]](1 ),还有MyModel[X1] &lt;: (MyModel[X] forSome {type X}) (2),但是对于不变的Model,我们不能将Model 应用于后者的“不等式”)。

但是如果你让Model协变abstract class Model[+M &lt;: Model[M]]那么我们可以将Model应用于“不等式”(2),所以Model[MyModel[X1]] &lt;: Model[MyModel[X] forSome {type X}]和这与(1)一起通过传递性给出MyModel[X1] &lt;: Model[MyModel[X] forSome {type X}]。所以Bar的条件满足,new Bar[MyModel[_]]编译。

Bar[MyModel[Any]] 编译是因为MyModel[Any] 满足Bar 的条件TModel &lt;: Model[TModel]。确实是MyModel[Any] &lt;: Model[MyModel[Any]],因为class MyModel[T] extends Model[MyModel[T]](你可以检查一下

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

编译)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多