Scala Co and Contravariance

懵懂的女人 提交于 2020-01-07 00:24:51

问题


Yes! Another of this question, and yes i already read alot of this questions in stackoverflow and still don't understand this concept and it's application.

So, i'm i new comer to Scala, and like many people i still didn't get the concept of Contravariance, i'm reading the Programming Scala, 2nd Edition, and on page 283 starts the explanation of co and contravariance with the following example:

gives the hierarchy:

class CSuper { def msuper() = println("CSuper") }
class C extends CSuper { def m() = println("C") }
class CSub extends C { def msub() = println("CSub") }

then there is a function and some examples of use:

var f: C => C = (c: C) => new C
    f         = (c: CSuper) => new CSub
    f         = (c: CSuper) => new C
    f         = (c: C) => new CSub
    f         = (c: CSub) => new CSuper // COMPILATION ERROR!

Thinking in java i know that the last expression won't compile because CSuper is a Supertype of CSub.

What i don't understand is what means a type, in this case the Function1[-C,+C], is contravariant in the first parameter?

The book says that for contravariance is when where X[String] is a supertype of X[Any], for some type X.

The co / contravariance is just appliable in the subclasses of the parameterized types, i mean since we are using a Function1, the variance just applies to subtypes of Function1, would be it?

And how does it actually works, and when should i use / need it?


回答1:


if T’ is a subclass of T, is Container[T’] considered a subclass of Container[T]?

[+T] covariant: C[T’] is a subclass of C[T],
[-T] contravariant: C[T] is a subclass of C[T’]

Function1 is defined as trait Function1[-T1, +R], so parameters are contravariant and result type is covariant.

That means, that functions, which arguments are supertypes of argument type of given function, and which result type is subtype of result type of given function is itself subtype of given function.

In your example, as you are assigning different function declarations to f of type C => C, only assigning of valid subtypes will compile.

Namely, only these function declarations are valid subtypes of C => C:

var f: C => C = (c: C) => new C
f         = (c: C) => new C
f         = (c: C) => new CSub
f         = (c: CSuper) => new C
f         = (c: CSuper) => new CSub

Everything else is either supertype of C => C and can't be assigned to f or unrelated type.



来源:https://stackoverflow.com/questions/36459965/scala-co-and-contravariance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!