关于scala:协变型FParam出现在价值猜测的Seq [FParam]类型的逆变位置

Covariant type FParam occurs in contravariant position in type Seq[FParam] of value guesses

Consider this simple example:

1
2
3
4
5
6
trait Optimizer[+FParam, FRes] {
  def optimize(
    fn: (FParam) => FRes,
    guesses: Seq[FParam] // <--- error
  )
}

它不会编译,因为

Covariant type FParam occurs in contravariant position in type Seq[FParam] of value guesses.

但SEQ是以trait Seq[+A]定义的,所以这一差异的根源是什么?(问题1)

Conversely,consider this simple example with -FParam

ZZU1BLCK1/

同样的矛盾:在Function1[-T1, R]中,第一类参数的变化很明显,所以为什么是FParam?(问题2)

我可以通过惊吓变异来确定这个问题,如描述在下一类边界,但为什么需要这样做是不可理解的。

1
2
3
4
5
6
7
8
trait Optimizer[+FParam, FRes] {
  type U <: FParam

  def optimize(
    fn: (FParam) => FRes,
    guesses: Seq[U]
  )
}


问题1:+FParam是指协变型FParam,因超型而异。对于guesses,预计cotravariant type,对于Seq。因此,您可以通过明确说明EDOCX1的supertypeFPParam来实现,例如:

1
def optimize[B >: FParam](fn: (B) => FRes, guesses: Seq[B]) // B is the super type of FParam

或者像SeqViewLike。

那么,为什么guesses预期cotravariant typeSeq呢?例如:

1
2
3
4
5
6
7
8
trait Animal

case class Dog() extends Animal

case class Cat() extends Animal
val o = new Optimizer2[Dog, Any]
val f: Dog => Any = (d: Dog) =>  ...
o.optimize(f, List(Dog(), Cat())) // if we don't bind B in `guesses` for supertype of `FParam`, it will fail in compile time, since the `guesses` it's expecting a `Dog` type, not the `Animal` type. when we bind it to the supertype of `Dog`, the compiler will infer it to `Animal` type, so `cotravariant type` for `Animal`, the `Cat` type is also matched.

问题2:-FParam是指同变异的FParam型,它从超型FParam到亚型不等,对于fn: Function1[-T1, +R]//(FParam) => FRes型,它期望协变型。所以你可以通过反问题1类型的状态来实现,比如:

1
def optimize[B <: FParam](fn: (B) => FRes, guesses: Seq[B]) // B is the sub type of FParam

问题是fparam没有直接使用。它在EDOCX1的论证中(0),因此它的方差是翻转的。举例来说,让我们看看optimize的类型(参见val optim):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
trait Optimizer[+FParam, FRes] {
  type U <: FParam

  def optimize(
    fn: (FParam) => FRes,
    guesses: Seq[U]
  )

  val optim: Function2[
    Function1[
      FParam,
      FRes
    ],
    Seq[U],
    Unit
  ] = optimize
}