为什么使用A进行字符串类型检查,但List [Int]不使用List [A]?

时间:2014-09-12 20:14:32

标签: scala type-inference

我正在阅读Scala规范中的本地类型推断部分(第6.26.4节),更具体地说是示例6.26.3。

例如,有以下函数和定义的值:

def cons[A](x: A, xs: List[A]): List[A] = x :: xs
def nil[B]: List[B] = Nil
val xs = cons(1, nil)

其中xs被推断为List[Int]类型。到现在为止还挺好。

然后,该示例使用以下值:

val ys = cons("abc", xs)

反过来推断它是List[Any]类型,这完全有道理。对我来说没有多大意义的是它的推理。它说第二个参数是用预期的类型List[a]键入的(为什么突然小写字母btw。?),据说失败,因为List[Int]xs的类型)是不是List[a]的子类型。因此,他们将其键入List[undefined]重试,然后成功。但是,第一个参数输入为String,没有问题,尽管它的预期类型是a(或A?)。

此外,第二种策略只能通过在类型中用undefined替换类型参数,而不是用undefined替换类型本身(或者暗示某种方式?)。

现在问题是,a是一个类型常量,为什么String(显然)是a的子类型,而List[Int]不是{{1}的子类型即使List[a]是协变的,也是如此?

1 个答案:

答案 0 :(得分:2)

作为类型常量的小写a并将类型参数作为未定义(当使用pt失败时)都出现在第3段中“case 3:methods”的末尾。

您不能说List[Int] <:< List[a]因为a可能会变成String,例如。

Int <:< undefined起,您将xs的类型设为List[Int]。这很好,因为你想要与其他arg类型的最小上限。 (想象一下,另一个arg是一个有趣的列表,a竟然是Foo。这些例子通常涉及动物:狗和猫成为宠物,或其他什么。)

在该步骤中,您真正询问a是什么,因此a?。然后,最好是String <: a?。它只选择String,因为它不是参数化类型。

当然,这只是非专家的措辞。