这种类型参数语法不能编译的原因是什么?

时间:2013-08-06 06:34:12

标签: scala generics types scala-2.10

说我有:

class Class[CC[A, B]]
class Thing[A, B <: Int]
class Test extends Class[Thing] // compile error here

我收到编译错误:

  

类型参数(cspsolver.Thing)的类型不符合类Class中类型参数(类型CC)的预期种类。 cspsolver。
  Thing的类型参数与CC类型的预期参数不匹配:类型C的边界&lt ;: Int比B类声明的边界更严格&gt;:Nothing&lt ;: Any

然而,当我修改代码时,它看起来像这样:

class Class[CC[A, B]]
class Thing[A, B] {
  type B <: Int
}
class Test extends Class[Thing]

它编译得很好。它们在功能上是否相同?

2 个答案:

答案 0 :(得分:1)

原因在编译器消息中给出。在Class中,您希望不受限制CC,而Thing则限制第二种类型参数必须为<: Int。一种可能性是将相同的约束添加到Class,如

class Class[CC[A,B <: Int]]
class Thing[A, B <: Int]
class Test extends Class[Thing]

答案 1 :(得分:0)

阐述PetrPudlák的解释,这是我假设发生的事情:编译器试图将CC[A, B]Thing[A, B <: Int]统一起来。根据{{​​1}}中B的声明,CC的上限类型为B,其被选中以实例化Any。但是,B中的B应该Thing为其上限类型,因此编译器会因您收到的错误消息而失败。

为了保持类型系统的健全性,这是必要的,如下图所示。假设Int定义了一个依赖于Thing事实的操作,例如,

B <: Int

如果您将class Thing[A, B <: Int] { def f(b: B) = 2 * b } 声明为

Class

class Class[CC[A,B]] { val c: CC }

Test

没有编译器抱怨,那么你可以进行以下调用

class Test extends Class[Thing] {
  val t: Thing
}

这显然不安全。