tha*_*_DG 6 functional-programming scala generic-variance
在课程函数式编程课程中,我遇到了一个微妙的概念.
如果A2 <:A1和B1 <:B2,则(A1 => B1)<:( A2 => B2)
理由
如果我们为此画一个维恩图,
参考:Youtube视频
谢谢
我们将 F1 称为 (A1 => B1),将 F2 称为 (A2 => B2)
为了使函数 F1 成为另一个函数 F2 的子类型,我们需要类型系统代替 F2 接受它。
您可以将参数 A 的任何子类型传递给接受 A 的函数,但不能传递超类型。这意味着,要使 F1 成为 F2 的子类型,它必须至少接受 F2 接受的所有参数作为参数,因此 A1 必须是 A2 的超类型。
另一方面,F1 的输出必须至少与 F2 的输出一样详细,以便在可以使用 F2 输出的任何地方都可以使用它。这意味着 B1 必须是 B2 的子类型。
我不确定图表是否是可视化它们如何组合在一起的好方法,但我想说,在这两个图表中,图 1 是最准确的。
让我们看一个例子:假设你有函数f1(s: Set): Set
thenf2(s: Iterable): SortedSet是 f1 的子类型,因为它可以用来代替 f1。
f1 要求其参数为 类型Set或其任何子类型Set。所有这些论点在 f2 中也有效。f1 的输出是 a Set,因此 f2 的输出必须可用作 a Set。由于SortedSet是 的子类型Set,因此这也是正确的。