scala中的协方差和方差翻转
covariance and variance flip in scala
在Scala for the Impatient据说
函数的参数是逆变的,结果类型是协变的
这很简单易懂,但是在同一个主题中它说
但是在函数参数内部,方差翻转-它的参数是协变的
以foldLeft method of Iterator为例
如:
def foldLeft[B](z : B)(op : (B, A) => B) : B
我不是很清楚它说的是什么。
我尝试了一些博客作为
-
http://blog.kamkor.me/Covariance-And-Contravariance-In-Scala/
http://blogs.atlassian.com/2013/01/covariance-and-contravariance-in-scala/
但是没有搞清楚。
归结为一个函数是另一个函数的子类型意味着什么。如果 C 是 A 的子类型(输入类型中的逆变)并且 B 是 D 的子类型(return 类型中的协变),那么听起来您对 A->B 是 C->D 的子类型感到满意.
现在考虑将其他函数作为参数的函数。例如,考虑 (A->B)->B。我们只是两次应用相同的推理。参数是 A->B 类型的函数,return 类型是 B。提供 C->B 类型的函数作为输入类型需要什么?由于函数在输入类型中是逆变的,因此 C->B 必须是 A->B 的子类型。但正如我们在第一段中讨论的那样,这意味着 A 必须是 C 的子类型。因此在第一段中的推理两次应用之后,我们发现 (A->B)->B 在 A 位置上是协变的。
你可以用更复杂的函数进行类似的推理。事实上,您应该说服自己,如果某个位置位于偶数个箭头的左侧,则该位置是协变的。
首先将函数视为 class 或 typeclass
。想想它的类型Function1[-A,+B]
假设我们有以下内容,
class x<br>
class y 扩展 b
现在我有两个函数,如下所示,
val test1:x=>Int = //do something
val test2:y=>int = //do something
现在如果我有像下面这样的另一种方法,
def acceptFunction(f: y => Unit, b: B) = //do something
根据类型签名 Function1[-A,+B]
我可以将 test2
传递给 acceptFunction
以及 test1
因为 contravariance
。
有点像 test1<:test2
.
这与说函数的参数是协变完全不同。这意味着如果您有以下内容,
class Fruit { def name: String="abstract" }
class Orange extends Fruit { override def name = "Orange" }
class Apple extends Fruit { override def name = "Apple" }
你可以这样写,
testM(new Apple())
def testM(fruit:Fruit)={}
但是你不能这样写,
testM(new Fruit())
def testM(fruit:Apple)={}
一个函数在它的参数类型上总是逆变的,在它的return类型上总是协变的
例如
trait Function1[-T1, +R] extends AnyRef
trait Function2[-T1, -T2, +R] extends AnyRef
这里,T1
,T2
, ..., T
n(其中 n <= 22
)是参数,R
是 return 类型 .
在高阶函数(以函数为参数的函数)中,参数可以具有传递给函数的参数类型
例如
foldLeft
特征 Iterable
Iterable
声明为
trait Iterable[+A] extends AnyRef
和 foldLeft
贴标为
def foldLeft[B](z : B)(op : (B, A) => B) : B
由于 A
被声明为协变的,它可以用作 return 类型。但这里它是一个参数类型,因为
trait Function2[-T1, -T2, +R] extends AnyRef
因为op : (B, A) => B
是Function2
的文字类型。
关键是特征Function2
在其参数类型中是逆变的.
因此,由于
,协方差类型出现在方法参数中
trait Function2 is contravariant in its argument type
这叫做方差翻转:
- 协方差的翻转是逆变。
- 逆变的翻转是协方差。
- 翻转是不变的是不变的。
这就是为什么不变量可能出现在任何位置(covariance/contravariance)
在Scala for the Impatient据说
函数的参数是逆变的,结果类型是协变的
这很简单易懂,但是在同一个主题中它说
但是在函数参数内部,方差翻转-它的参数是协变的
以foldLeft method of Iterator为例 如:
def foldLeft[B](z : B)(op : (B, A) => B) : B
我不是很清楚它说的是什么。
我尝试了一些博客作为
http://blog.kamkor.me/Covariance-And-Contravariance-In-Scala/
http://blogs.atlassian.com/2013/01/covariance-and-contravariance-in-scala/
但是没有搞清楚。
归结为一个函数是另一个函数的子类型意味着什么。如果 C 是 A 的子类型(输入类型中的逆变)并且 B 是 D 的子类型(return 类型中的协变),那么听起来您对 A->B 是 C->D 的子类型感到满意.
现在考虑将其他函数作为参数的函数。例如,考虑 (A->B)->B。我们只是两次应用相同的推理。参数是 A->B 类型的函数,return 类型是 B。提供 C->B 类型的函数作为输入类型需要什么?由于函数在输入类型中是逆变的,因此 C->B 必须是 A->B 的子类型。但正如我们在第一段中讨论的那样,这意味着 A 必须是 C 的子类型。因此在第一段中的推理两次应用之后,我们发现 (A->B)->B 在 A 位置上是协变的。
你可以用更复杂的函数进行类似的推理。事实上,您应该说服自己,如果某个位置位于偶数个箭头的左侧,则该位置是协变的。
首先将函数视为 class 或 typeclass
。想想它的类型Function1[-A,+B]
假设我们有以下内容,
class x<br>
class y 扩展 b
现在我有两个函数,如下所示,
val test1:x=>Int = //do something
val test2:y=>int = //do something
现在如果我有像下面这样的另一种方法,
def acceptFunction(f: y => Unit, b: B) = //do something
根据类型签名 Function1[-A,+B]
我可以将 test2
传递给 acceptFunction
以及 test1
因为 contravariance
。
有点像 test1<:test2
.
这与说函数的参数是协变完全不同。这意味着如果您有以下内容,
class Fruit { def name: String="abstract" }
class Orange extends Fruit { override def name = "Orange" }
class Apple extends Fruit { override def name = "Apple" }
你可以这样写,
testM(new Apple())
def testM(fruit:Fruit)={}
但是你不能这样写,
testM(new Fruit())
def testM(fruit:Apple)={}
一个函数在它的参数类型上总是逆变的,在它的return类型上总是协变的 例如
trait Function1[-T1, +R] extends AnyRef
trait Function2[-T1, -T2, +R] extends AnyRef
这里,T1
,T2
, ..., T
n(其中 n <= 22
)是参数,R
是 return 类型 .
在高阶函数(以函数为参数的函数)中,参数可以具有传递给函数的参数类型
例如
foldLeft
特征 Iterable
Iterable
声明为
trait Iterable[+A] extends AnyRef
和 foldLeft
贴标为
def foldLeft[B](z : B)(op : (B, A) => B) : B
由于 A
被声明为协变的,它可以用作 return 类型。但这里它是一个参数类型,因为
trait Function2[-T1, -T2, +R] extends AnyRef
因为op : (B, A) => B
是Function2
的文字类型。
关键是特征Function2
在其参数类型中是逆变的.
因此,由于
,协方差类型出现在方法参数中trait Function2 is contravariant in its argument type
这叫做方差翻转:
- 协方差的翻转是逆变。
- 逆变的翻转是协方差。
- 翻转是不变的是不变的。
这就是为什么不变量可能出现在任何位置(covariance/contravariance)