功能类型之间的子类型

tha*_*_DG 6 functional-programming scala generic-variance

在课程函数式编程课程中,我遇到了一个微妙的概念.

如果A2 <:A1B1 <:B2,则(A1 => B1)<:( A2 => B2)

理由

  • 当我们将参数传递给A2并且由于子类型关系时,我们可以将相同的参数传递给A1.
  • 然后应用函数A1 => B1
  • 然后该函数给出B1,因为子类型符合B2

如果我们为此画一个维恩图,

  • 图1 图1

  • 图2 图2

    • 这是正确的图表?
    • 如何使用维恩图解释结果?

参考:Youtube视频

谢谢

Buh*_*uhb 4

我们将 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,因此这也是正确的。