scala拓宽方法签名

时间:2016-08-08 16:57:45

标签: scala

我写了一个课程,期望获得Option[(E) => Long]

class Whatever[E] (sizeFunction: Option[(E) => Long])

当我尝试使用函数(E) => Int实例化它时:

val sizeFunction = (a: String) => a.length
new Whatever[String](Some(sizeFunction))

我收到编译错误:

type mismatch;
found   : String => Int
required: String => Long

不应该String => Int"满足" String => Long由于扩大了?

2 个答案:

答案 0 :(得分:2)

请记住String => Int本身就是一种类型。 String =>长是一种不同的类型。这对某些程序很重要,对于其他程序并不重要,如您的示例所示。但是编译器做出假设而不是调用类型不匹配会很危险,因为它可能会扩展函数类型的一部分。如果你真的在乎你可以将sizeFunction定义为String =>号。

答案 1 :(得分:2)

在Scala中,函数的返回类型为协变:要使A => B成为A => C的子类型,B必须是{{1}的子类型1}}。但C不是Int的子类型(即“每LongInt”并非如此;)相反,它可以扩展为Long,这是一种不同的关系。

协方差的定义可能可以更改为Long必须弱地符合而不是B(即CB的子类型,或者可以扩展为C,或者CB之间存在一系列中间类型,其中上述类型之一成立。但是为了保持一致,同样必须适用于逆变:C将是Long => A的子类型(通过应用扩展到参数)。这对我来说似乎不是一个好主意(并且只改变协方差,但不是逆变,似乎更糟)。