Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

+- Signs in Generic Declaration in Scala

Tags:

generics

scala

I was looking at the documentation for PartialFunction in this link:

trait PartialFunction[-A, +B] extends (A) ⇒ B 

Maybe someone can help clarify the significance of the plus and minus signs in the generic declaration?

like image 741
Ariel T Avatar asked Dec 23 '14 20:12

Ariel T


People also ask

What is Generic types in Scala?

Most Scala generic classes are collections, such as the immutable List, Queue, Set, Map, or their mutable equivalents, and Stack. Collections are containers of zero or more objects. We also have generic containers that aren't so obvious at first.

What is generic function in Scala?

In Scala, forming a Generic Class is extremely analogous to the forming of generic classes in Java. The classes that takes a type just like a parameter are known to be Generic Classes in Scala. This classes takes a type like a parameter inside the square brackets i.e, [ ].

What does <: mean in Scala?

It means an abstract type member is defined (inside some context, e.g. a trait or class), so that concrete implementations of that context must define that type. However, there is a constraint that this type ( Currency ) must actually be a subtype of AbstractCurrency .

What is type in Scala?

Scala is a statically typed programming language. This means the compiler determines the type of a variable at compile time. Type declaration is a Scala feature that enables us to declare our own types.


1 Answers

"+" and "-" mean covariant and contravariant types respectively. In short, it means that:

PartialFunction[-A1, +B1] <: PartialFunction[-A2, +B2] only if A1 :> A2 and B1 <: B2, where <: is a subtyping relationship.

"-" usually applied for input parameters, "+" for output - in C# they even use respective keywords in and out. There is also some more primitive generic variance support in Java built up on existential types - actually you can do it using _ <: SomeType (covariance) or abstract type members type T <: SomeType in Scala as well.

Without modifiers PartialFunction[A1, B1] would have no direct relationship to a PartialFunction[A2, B2] (in other words, it would be invariant).

P.S. There are also some restrictions applied to such types, like covariant("+") type can't be in contravariant position (you can only return it from a method) and vice-versa. This is done in order to support Liskov Substitution Principle and naturally understandable by "in"/"out" interpretation.

Also, it worth noting that A => B (syntax sugar for Function1) itself is using co-/contra-variance:

 trait Function1 [-T1, +R] extends AnyRef 

As those functions can be extended through sub-typing which makes them theoretically partial as well (though it’s not how Scala treats these) - even technically “total” FunctionN in Scala could be extended, redefined, return null and so on.

like image 151
dk14 Avatar answered Sep 22 '22 23:09

dk14