sealed trait Sum[+A, +B] {
def flatMap[A, C](f: B => Sum[A, C]): Sum[A, C] =
this match {
case Failure(v) => Failure(v)
case Success(v) => f(v)
}
}
不是说函数参数是相互变化的,结果共同变化了吗?为什么编译器说a处于逆转位置?我希望编译器会抱怨B处于相反的位置。
有人可以向我解释为什么是这样吗?感到困惑。
我假设您实际上是要写的:
sealed trait Sum[+A, +B] {
def flatMap[C](f: B => Sum[A, C]): Sum[A, C] = // No shadowing of A
this match {
case Failure(v) => Failure(v)
case Success(v) => f(v)
}
}
再次查看flatMap
:
def flatMap[C](f: B => Sum[A, C]): Sum[A, C]
让我们重写一点:
def flatMap[C]: (B => Sum[A, C]) => Sum[A, C]
让我们从内而外建立类型。
Sum[A, C]
A
是Sum
的参数,通常是协变位置。
B => Sum[A, C]
Sum[A, C]
是函数的结果,该功能通常是协变位置。这两个组合,您将A
处于协变位置。
(B => Sum[A, C]) => Sum[A, C]
B => Sum[A, C]
也是函数的参数,因此整体 处于违反位置。由于A
以前处于协变量,因此差异组合和A
现在处于违反位置。
查看B
:
B => Sum[A, C]
函数的参数,通常是违反位置。
(B => Sum[A, C]) => Sum[B, C]
整个函数也是另一个函数的参数,因此违规行为取消,B
位于协变量位置。
您也可以进行漂亮的类比。查看协变和逆转的类型参数的定义:
trait Co[+A]; trait Con[-A]
它们看起来像正数和负数,只是一点点。现在,记住乘法规则和您在小学中学到的标志:
-
(+) * (+) = (+)
-
(+) * (-) = (-)
-
(-) * (+) = (-)
-
(-) * (-) = (+)
这类似于(如果您有点to)
-
Co[Co[A]]
=>A
处于协变位置 -
Co[Con[A]]
=>A
处于逆处位置 -
Con[Co[A]]
=>A
处于违反位置 -
Con[Con[A]]
=>A
处于协变量。