微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

错误,更高的Kinded类型Scala:类型参数不符合.类型T的边界比类型T的声明边界更严格

这是 Scala REPL中的一个简单实验:

scala> trait A; trait B extends A; trait C extends B
defined trait A
defined trait B
defined trait C

scala> trait TC[T]
defined trait TC

scala> trait TC2[T <: B]
defined trait TC2

scala> class Test[TC[T]]
warning: there was one feature warning; re-run with -feature for details
defined class Test

scala> new Test[TC]
res1: Test[TC] = Test@6f195bc3

scala> new Test[TC2]



<console>:11: error: kinds of the type arguments (TC2) do not conform to the expected kinds of the type parameters (type TC) in class Test.
TC2's type parameters do not match type TC's expected parameters:
type T (in trait TC2)'s bounds <: B are stricter than type T's declared bounds >: nothing <: Any
       val res2 =
           ^
<console>:12: error: kinds of the type arguments (TC2) do not conform to the expected kinds of the type parameters (type TC) in class Test.
TC2's type parameters do not match type TC's expected parameters:
type T (in trait TC2)'s bounds <: B are stricter than type T's declared bounds >: nothing <: Any
              new Test[TC2]
                  ^

问题1:

如何根据Scala语言规范解释这些错误消息?

换句话说,SLS的哪些部分解释了这些错误消息?

问题2:如何用简单的术语(不是基于SLS)解释这些错误消息?

用编译器的话来描述上一个问题:

为什么TC2的类型参数与TC类型的预期参数不匹配是一个问题,即类型T(在特性TC2中)的界限<:B比类型T的声明边界更严格>:什么都没有?

是否有任何书或文章解释了此错误消息背后的原因?

或许在皮尔斯的TAPL书中某处?

解决方法

正如我在上面的注释中所注意到的,Test的类型参数列表中的TC(以及错误消息中的TC)不是您之前定义的几行TC – 它是一个新的类型构造函数参数,它隐藏了特征TC.

(作为旁注,我强烈建议不要遮蔽类型参数.值级别的阴影变量可能会让人感到困惑,但阴影类型参数几乎总是混淆的.)

类型构造函数参数在规范的4.4节中讨论.从那一节:

A type constructor parameter adds a nested type parameter clause to
the type parameter… The above scoping restrictions are generalized
to the case of nested type parameter clauses,which declare
higher-order type parameters. Higher-order type parameters (the type
parameters of a type parameter t) are only visible in their
immediately surrounding parameter clause (possibly including clauses
at a deeper nesting level) and in the bounds of t.

这里的T是这些高阶类型参数之一.它可以是有界的(像任何其他类型参数一样),但事实并非如此.这就是导致错误的原因:您正在尝试提供一种类型构造函数,该类型构造函数将其类型参数(TC2)约束为不共享约束的类型构造函数参数的值(实际上它没有任何约束)所有).

要直观地了解这是一个问题,请考虑以下特征:

trait Foo[X[_]] {
  def create[A]: X[A]
}

这是一个非常合理的事情 – 我可以像这样创建一个实例:

object ListFoo extends Foo[List] {
  def create[A]: List[A] = Nil
}

现在假设我有一个带约束的类型构造函数

trait MyIntOptionThingy[A <: Option[Int]]

编译器禁止我实例化Foo [MyIntOptionThingy],因为MyIntOptionThingy的类型参数比Foo类型参数列表中X的类型参数更严格地受约束.如果你考虑一下这是有道理的:当我对MyIntOptionThingy起作用的唯一As是Some [Int],None.type和Option [Int]时,我怎么能为任何A定义create?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐