阐明函数的 return 类型的逆变性质作为外部协变容器的函数的参数

Clarifying contravariance nature of the return type of a function as parameter a function of an outer convariant container

在选项中我们有

def getOrElse[B >: A](default: => B): B = this match {
        case None => default
        case Some(a) => a
    }
def orElse[B >: A](obj: => Option[B]): Option[B] = this match {
        case None => obj
        case _ => this
    }

我们有:

def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B]

我明白发生了什么以及为什么,一个相当广泛的例子可能是这个

OrElse( { Option[B]}).map{....} If B is such that A :> B, then if Some(a) you get Some(a).map(f:B => ???) then Kaboom

总的来说,我认为我可以接受差异。我没有看到或弄清楚的是因为这不是协方差和逆变的简单示例解释为用例的内容,并且想在这里确认:

return 类型的函数作为参数检查外部容器的变化位置。

典型的例子是

Container[+A] {
  def outerfunction[B](value: A): B
}

然后我们解释说,不能做,A 的反方差位置。我不会再做完整的解释为什么。假设我们都理解它。

通常不解释的是:

Container[+A] {
      def outerfunction(f: ??? => A): A
    }

它不仅采用类型 A 的参数,而且还采用 return A 的任何函数参数。编译器也会详细检查它。我想知道它是否就此停止,或者它是否可以产生 A 作为 Container 函数的参数。

您的理解完全正确。老实说,我不确定问题到底是什么,但我会假设它是 - 在以下情况下编译器会检查哪些地方:

trait Container[+A] {
  def outerfunction(f: String => A): A
}

答案是 - 所有这些。

因此,当编译器看到 trait Container[+A] 时,它会检查 Container 的正文以查找所有出现的 A,看它们是否在:

  • 参数位置(带来逆变要求)
  • return类型位置(协变要求)
  • 两者(不变要求)
  • 都不是(所谓的phantom variance)。

Container[+A]的情况下,它将要求所有出现的A都处于协变位置,这意味着String => A会出现问题。

就这么简单。不管是“内部函数”还是“外部函数”。