In Scala, covariance, inversion, upper bounds, nether, etc.

Source: Internet
Author: User

Directory of covariance, inversion, upper bound, nether, etc. in Scala[−]
    1. Covariance and Contravariance in Java
    2. Scala's co-transformation
    3. Scala's Contravariance
    4. Nether Lower Bounds
    5. Upper bound Upper Bounds
    6. Integrated covariance, inversion, upper bound, lower bound
    7. View Bound <%
    8. Context Bound
    9. Reference documents

The covariant contravariance in Scala is not the same as covariant contravariance in Java, and looks more complex. This article summarizes these concepts in Scala.
First look at several concepts:

    • covariant covariant. Enables you to use subclasses of a type other than the original specified
    • contravariance inversion. Enables you to use a parent class that is more than the original specified type.
    • invariance not change. You can only use the original specified type, not covariant and contravariant
    • Upper bounds Upper bound.
    • Lower bounds Nether.
Covariance and Contravariance in Java

First, let's review the covariance and contravariance in Java so that we can easily understand the covariance and contravariance in Scala.
1 co-change

123456 Class Super {Object getsomething () {}}class Sub extends Super {String getsomething () {}}

Sub.getsomething () is a covariant type because its return type is a subclass of the super.getsomething return type.

2 Inversion

123456 Class super{ void dosomething (String parameter)}class Sub extends super{ void dosomething (Object parameter) }

Sub.getsomething () is a contravariant type because its input parameter is the parent class of the super.getsomething input parameter.

3 generic type
Covariance and contravariance are also found in generics.

12345678910 List<string> alist ... list<? Extends object> covariantlist = alist; list<? Super string> contravariantlist = alist; Covariantlist.add ("D"); //wrong Object a = Covariantlist.get (0); contravariantlist.add ("D"); //ok String B = Contravariantlist.get (1); //wrong Object C = Contravariantlist.get (2);

You can call covariantList all methods that do not require a generic parameter, because the generic parameter must extends Object, but at compile time you do not know its exact type. However, you can call the Getter method because the return type always conforms to the object type.
contravariantListOn the contrary, you can call all methods with generic parameters, because you can explicitly pass in a string's parent class. But the getter method does not work.

Scala's co-transformation

The first thing we need to know is the subtype (subtyping). A class can be a subclass of another class (sub-) or a parent class (super-). We can use the mathematical concept (partial order) to define:

1 A- b iff a <: b

When we define a covariant type List[A+] , List[child] can be a subtype of list[parent].
When we define an contravariant type List[-A] , List[child] can be the parent type of list[parent].

Look at the following example:

12345678910 class animal {} class bird extends animal {}  class consumer[t]  }class test extends app { val c:consumer[bird] = new consumer[bird] (new Bird) val c2:consumer[animal] = c }

ccannot be assigned to c2 because it Consumer is defined as an immutable type.

Change it a little bit:

12345678910 class animal {} class bird extends animal {}  class consumer[+t]  }class test extends app { val c:consumer[bird] = new consumer[bird] (new Bird) val c2:consumer[animal] = c }

Because Consumer it is defined as a covariant type, Consumer[Bird] it is a Consumer[Animal] subtype, so it can be assigned a value c2 .

Scala's Contravariance

Change the example above:

12345678910 class animal {} class bird extends animal {}  class consumer[-t]  }class test extends app { val c:consumer[bird] = new consumer[bird] (new Bird) val c2:consumer[hummingbird] = c }

This is Consumer[-T] defined as an inverse type, so it can be assigned Consumer[Bird] Consumer[Hummingbird] to a sub-type c c2 .

Nether Lower Bounds

If the covariant class contains a method with a type parameter:

123456 class Animal {}  class Bird extends Animal {} class consumer[+T](t:t) { def use (t:t) = {}}

The compilation will be faulted. The error message is "covariant type T occurs in contravariant position in type T of Value T".
However, there is no problem if you return the result as a type parameter.

123456 class Animal {}  class Bird extends Animal {} class consumer[+t](t:t) { def get (): t = {new T}}

In order to use type parameters in the parameters of a method, you need to define the nether:

123456 class Animal {}  class Bird extends Animal {} class consumer[+t](t:t) {def use[u;: t] (u:u) = {println (U)}}
Upper bound Upper Bounds

Take a look at an example of an upper bound used in an inverter class:

123456 class Animal {}  class Bird extends Animal {} class consumer[-T](t:t) {def get[u <: t] (): U = {new u} }

To see where the return value of the method is covariant, the parameter of the method is the position of the inverse.
Therefore, the type parameter of the covariant class can be used in the type of the return value of the method, and must be bound using the nether binding on the method's parameter type >: .
The type parameter of the Contravariant class can be used on the parameter type of the method, and must be bound with the upper bound when used as the return value type of the method <: .

Integrated covariance, inversion, upper bound, lower bound

A comprehensive example:

1234567891011121314 class Animal {} class Bird extends Animal {} class consumer[-s,+T]() { def M1[u;: t] (u:u): t = {new T} //covariant, Nether def m2[u <: S] (s:s): U = {new u} //Invert, upper bound }class Test extends App { val C:consumer[animal,bird] = new Consumer[animal,bird] () val C2:consumer[bird,animal] = cC2.M1 (new Animal)C2.M2 (new Bird)}
View Bound <%

Scala also has a view binding feature, such as

123456 class Bird {def sing = {}}  class Toy {} class consumer[T <% Bird]() {def use (t:t) = T.sing }

or the type parameter on the method:

1234567891011 class Bird {def sing = {}}  class Toy {} class Consumer() {def use[t <% Bird] (t:t) = t.sing} class Test extends App { val c = new Consumer ()c.use (new Toy)}

It requires that T must have an implicit conversion to convert to bird, T => Bird that is, otherwise the above code compiles an error:

1 No implicit view available from Toy = Bird.

Add an implicit conversion, compile through.

1234567891011121314 import Scala.language.implicitConversions  class bird {def sing = {}} class toy {}   class consumer () { def use[t <% Bird] (t:t) = t.sing } < span class= "keyword" >class test extends app { implicit def toy2bird (T:toy) = new Bird val c = new Consumer () c.use (new Toy) }
Context Bound

The context bound is introduced in Scala 2.8.0 and is also known as type class pattern.
The view bound A <% String is used, and the context bound requires a parameterized type, such as Ordered[A] .
It declares a type A , implicitly having a type B[A] , with the following syntax:

1 def F[a:b] (a:a) = g (A) //Where g requires an implicit value of type B[a]

A clearer example:

1 def F[a:classmanifest] (n:int) = new Array[a] (n)

Another example

1 def F[a:ordering] (a:a, b:a) = Implicitly[ordering[a]].compare (A, B)

Covariance, inversion, upper bounds, nether, etc. in Scala

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.