Scala 澄清函数返回类型作为外部协变容器函数的参数的逆变性质

Scala 澄清函数返回类型作为外部协变容器函数的参数的逆变性质,scala,generics,covariance,Scala,Generics,Covariance,我们有选择权 def getOrElse[B >: A](default: => B): B = this match { case None => default case Some(a) => a } 在这两方面,我们都有: def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B] 我理解发生了什么以及为什么,一个相当广泛的例子可能是这样的 OrE

我们有选择权

def getOrElse[B >: A](default: => B): B = this match {
        case None => default
        case Some(a) => a
    }
在这两方面,我们都有:

def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B]
我理解发生了什么以及为什么,一个相当广泛的例子可能是这样的

OrElse({Option[B]}).map{..}如果B是这样的A:>B,那么如果 有些(a)你得到一些(a)。映射(f:B=>?)然后

总的来说,我认为我可以接受差异。我没有看到或弄明白什么,因为这不是协方差和逆变的简单示例作为用例所解释的,我想在这里确认一下:

对于外部容器的差异位置,将检查函数作为参数的返回类型

典型的例子是

Container[+A] {
  def outerfunction[B](value: A): B
}
然后我们被解释了,不能做,A的相反方差位置。我不会再做完整的解释来解释为什么。让我们假设我们都理解它

通常不被解释的是:

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

它不仅获取类型为a的参数,还获取返回a的任何函数参数。编译器也会详细检查这一点。我不知道它是否止于此,或者它是否可以产生一个A,作为容器函数的参数。

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

trait Container[+A] {
  def outerfunction(f: String => A): A
}
答案是——全部

因此,当编译器看到
trait Container[+A]
时,它将检查该
容器的主体是否出现了
A
,以查看它们是否在:

  • 参数位置(带来逆变要求)
  • 返回类型位置(协变要求)
  • 两者(不变要求)
  • 都不是(所谓的)
容器[+A]
的情况下,它将要求所有出现的
A
都处于协变位置,这意味着它将出现
String=>A
的问题


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

不确定问题是什么-WDYM:“我想知道它是否停在这里,或者它是否可以产生一个A,作为容器函数的参数。”?一个函数产生一个A,但我不知道,另一个容器可以被视为A的生产者,例如传递列表[A]作为容器[+a]函数的参数,我可以直接测试它,我只是想也许我不会考虑所有的情况。此外,我想确认,确实是因为参数函数返回a,a变为逆变。对不起,我仍然不明白你在说什么。但我会尽我最大的努力:1。确实,您可以将任何协变类型构造函数视为生产者,例如返回
a
s的函数,并且它们中的大多数具有与函数类似的自然操作(甚至大多数都实现了函数特性)这并不意味着您总是可以传递协变类的一个实例,在该实例中需要一个函数本身,但是创建lambda应该很简单(这有意义吗?)。我有另一个案例,这让我重新思考一下。用你自己的话来说,为什么编译器会对
String=>a
有问题。从f的角度看,A处于协变位置,但从容器的角度看,情况就不同了。我明白这可能是显而易见的,但我还是想用你自己的话来确认一下。这正是你所说的
A
是函数
f
的返回类型,返回类型是协变位置。但是整个函数
f
是方法
outerfunction
的参数,这是一个逆变位置。请注意,函数(与方法不同)不能参数化,因此
f
无论如何也不能抱怨。还要注意——这一点非常重要——方差是类的质量,而不是参数的质量。我们说“类容器的类型是协变的”。如果将
[+A]
从类移动到方法,使其成为
def outerfunction[A]
,则无法通过+-.Cristal clear定义差异!!!谢谢你花时间和额外的小费!!!
trait Container[+A] {
  def outerfunction(f: String => A): A
}