Scala:为什么存在类型声明中的下界没有强制执行?

时间:2013-04-04 18:48:53

标签: scala types covariance existential-type type-bounds

假设Scala repl中包含以下声明:

class Animal
class Bird extends Animal
class Chicken extends Bird
type SubType = t forSome { type t <: Bird }
type SuperType = t forSome { type t >: Bird }

正如我所料,SubType属于符合Bird的类型。由于AnimalBird的超类,因此SubType类型的变量无法保存Animal类型的值:

scala> val foo: SubType = new Animal
<console>:10: error: type mismatch;
 found   : Animal
 required: SubType
       val foo: SubType = new Animal

然而这个推论并不像我期望的那样:

scala> val foo: SuperType = new Chicken
foo: SuperType = Chicken@1fea8dbd

作业成功,这些也是如此:

scala> val foo: SuperType = 2
foo: SuperType = 2

scala> val foo: SuperType = "wtf?"
foo: SuperType = wtf?

scala>

再次,这里是SuperType

type SuperType = t forSome { type t >: Bird }

根据SLS 4.3

  

类型声明 类型 t [tps]&gt;:L&lt;:U 声明 t 到是一个抽象类型,下限类型为 L ,上限类型为 U

所以我声明t是一个带有下限Bird的抽象类型。 Chicken不是Bird的超类,String也不是Int

我想也许是因为ChickenAnySuperType可以存储Any。但是,如果我将SuperType的声明更改为:

type SuperType = t forSome { type t >: Bird <: Animal}

设置Animal的上限似乎没有任何改变。

问题

第一

我如何将Chicken IntString类型的值分配给存在性条款SuperType{ type t >: Bird }允许的{ type t >: Bird <: Animal}变量?

第二

引用规范中“抽象”一词的含义是什么,“A 类型声明 类型 t [tps]&gt;:L&lt; :U 声明 t 是一个抽象类型......“如果”抽象“这个词不在那里,意义的区别是什么?

1 个答案:

答案 0 :(得分:0)

我认为混淆是使用术语“约束”和“约束”。 “&lt ;:”和“&gt;:”语法结构用于指定类型约束,而不是边界。当你说

{ type t >: Bird } 

你只是在限制类型“t”,这样那种类型的居民必须与Bird共享一个超类。由于Chicken和Bird都扩展了Animal,因此符合约束条件,而Scala允许赋值。这也是你的“虚假”作业的原因(String和Int都与Bird共享超类Any。你提出的后一个约束

{ type t >: Bird <: Animal } 

正确地限制了String和Int的示例,因为在String或Int的类型层次结构中不存在满足作为Bird的超类型的约束的类型,同时也是Animal的子类型。但是,这仍然允许您的初始分配。

编辑:关于SO的其他答案说两者都被称为边界。显示我知道多少。 :)