Unable to understand contravariance wrt Function1(-T1,+T1) - scala

I am unable to understand contravariance wrt functiontype 1. The definition of function type1 is as below :
Function1(-T,+T)
The definition clearly says the input type parameter is contravariance. So a superclass type of a type should be allowed as parameter. But why is this giving compiler error.
I have defined below classes
class Animal
class Mammal extends Animal
class Cow extends Mammal
I have defined method as below
def move(m:Mammal) = Unit c
When I am invoking move like in below it gives no error
move (new Cow)
but this gives error
move(new Animal)
Why is that I am not able invoke move() with Animal as param even though Function1 is contravariant[-T] .
I am new to Scala, so please help me out in this

Contravariance does not mean that the function can be provided with a value of "lower" type, but that when comparing the types of two functions
type F = Function1(A, B)
type G = Function1(C, B)
then if A is a super type of C then F is a sub type of G. In essence, the ordering (variance) on types of functions goes against (contra) the ordering of the types in their input positions.
In particular if you imagine a function:
def foo(f : Cow => String) : String = f(new Cow)
Then from the perspective of the body of foo, f can accept a Cow, but then, from the perspective of the caller to foo, a function that accepts Animal would also accept Cow just fine, so it makes sense to allow that:
foo((a : Animal) => "generic animal noise")
foo((c : Cow) => "moo")
In English, the contract for the function foo is:
Give me a thing that when I provide it a Cow, I get given back a String, and in return, I will give you a String.
And in particular, a function that when given an Animal provides a String, fits the bill for "a thing that when given a Cow, returns a String".

Actually, the nature of can be intuitively understood: you cannot pass instance of Animal to move, because function move may rely on some method which is defined in Mammal but is missing in Animal.
Hope this helps

Related

Scala: please explain the generics involved

Could some one please explain the generics involved in the following code from play framework
class AuthenticatedRequest[A, U](val user: U, request: Request[A]) extends WrappedRequest[A](request)
class AuthenticatedBuilder[U](userinfo: RequestHeader => Option[U],
onUnauthorized: RequestHeader => Result = _ => Unauthorized(views.html.defaultpages.unauthorized()))
extends ActionBuilder[({ type R[A] = AuthenticatedRequest[A, U] })#R]
The ActionBuilder actualy has type R[A], it is getting reassigned, this much I understand. please explain the intricacies of the syntax
The bit that's confusing you is called a "type lambda". If you search for "scala type lambda", you'll find lots of descriptions and explanations. See e.g. here, from which I'm drawing a lot of inspiration. (Thank you Bartosz Witkowski!)
To describe it very simply, you can think of it as a way to provide a default argument to a type constructor. I know, huh?
Let's break that down. If we have...
trait Unwrapper[A,W[_]] {
/* should throw an Exception if we cannot unwrap */
def unwrap( wrapped : W[A] ) : A
}
You could define an OptionUnwrapper easily enough:
class OptionUnwrapper[A] extends Unwrapper[A,Option] {
def unwrap( wrapped : Option[A] ) : A = wrapped.get
}
But what if we want to define an unwrapper for the very similar Either class, which takes two type parameters [A,B]. Either, like Option, is often used as a return value for things that might fail, but where you might want to retain information about the failure. By convention, "success" results in a Right object containing a B, while failure yields a Left object containing an A. Let's make an EitherUnwrapper, so we have an interface in common with Option to unwrap these sorts of failable results. (Potentially even useful!)
class EitherUnwrapper[A,B] extends Unwrapper[B,Either] { // unwrap to a successful result of type B
def unwrap( wrapped : Either[A,B] ) : B = wrapped match {
case Right( b ) => b // we ignore the left case, allowing a MatchError
}
}
This is conceptually fine, but it doesn't compile! Why not? Because the second parameter of Unwrapper was W[_], that is a type that accepts just one parameter. How can we "adapt" Either's type constructor to be a one parameter type? If we needed a version of an ordinary function or constructor with fewer arguments, we might supply default arguments. So that's exactly what we'll do.
class EitherUnwrapper[A,B] extends Unwrapper[B,({type L[C] = Either[A,C]})#L] {
def unwrap( wrapped : Either[A,B] ) : B = wrapped match {
case Right( b ) => b
}
}
The type alias part
type L[C] = Either[A,C]
adapts Either into a type that requires just one type parameter rather than two, by supplying A as a default first type parameter. But unfortunately, scala doesn't allow you to define type aliases just anywhere: they have to live in a class, trait, or object. But if you define the trait in an enclosing scope, you might not have access to the default value you need for type A! So, the trick is to define a throwaway inner class in a place where A is defined, just where you need the new type.
A set of curly braces can (depending on context) be interpreted as a type definition in scala, for a structural type. For instance in...
def destroy( rsrc : { def close() } ) = rsrc.close()
...the curly brace defines a structural type meaning any object with a close() function. Structural types can also include type aliases.
So { type L[C] = Either[A,C] } is just the type of any object that contains the type alias L[C]. To extract an inner type from an enclosing type -- rather than an enclosing instance -- in Scala, we have to use a type projection rather than a dot. The syntax for a type projection is EnclosingType#InnerType. So, we have { type L[C] = Either[A,C] }#L. For reasons that elude me, the Scala compiler gets confused by that, but if we put the type definition in parentheses, everything works, so we have ({ type L[C] = Either[A,C] })#L.
Which is pretty precisely analogous to ({ type R[A] = AuthenticatedRequest[A, U] })#R in your question. ActionBuilder needs to be parameterized with a type that takes one parameter. AuthenticatedRequest takes two parameters. To adapt AuthenticatedRequest into a type suitable for ActionBuilder, U is provided as a default parameter in the type lambda.

Contravariance vs Covariance in Scala

I just learned Scala. Now I am confused about Contravariance and Covariance.
From this page, I learned something below:
Covariance
Perhaps the most obvious feature of subtyping is the ability to replace a value of a wider type with a value of a narrower type in an expression. For example, suppose I have some types Real, Integer <: Real, and some unrelated type Boolean. I can define a function is_positive :: Real -> Boolean which operates on Real values, but I can also apply this function to values of type Integer (or any other subtype of Real). This replacement of wider (ancestor) types with narrower (descendant) types is called covariance. The concept of covariance allows us to write generic code and is invaluable when reasoning about inheritance in object-oriented programming languages and polymorphism in functional languages.
However, I also saw something from somewhere else:
scala> class Animal
 defined class Animal
scala> class Dog extends Animal
 defined class Dog
scala> class Beagle extends Dog
 defined class Beagle
scala> def foo(x: List[Dog]) = x
 foo: (x: List[Dog])List[Dog] // Given a List[Dog], just returns it
scala> val an: List[Animal] = foo(List(new Beagle))
 an: List[Animal] = List(Beagle#284a6c0)
Parameter x of foo is contravariant; it expects an argument of type List[Dog], but we give it a List[Beagle], and that's okay
[What I think is the second example should also prove Covariance. Because from the first example, I learned that "apply this function to values of type Integer (or any other subtype of Real)". So correspondingly, here we apply this function to values of type List[Beagle](or any other subtype of List[Dog]). But to my surprise, the second example proves Cotravariance]
I think two are talking the same thing, but one proves Covariance and the other Contravariance. I also saw this question from SO. However I am still confused. Did I miss something or one of the examples is wrong?
A Good recent article (August 2016) on that topic is "Cheat Codes for Contravariance and Covariance" by Matt Handler.
It starts from the general concept as presented in "Covariance and Contravariance of Hosts and Visitors" and diagram from Andre Tyukin and anoopelias's answer.
And its concludes with:
Here is how to determine if your type ParametricType[T] can/cannot be covariant/contravariant:
A type can be covariant when it does not call methods on the type that it is generic over.
If the type needs to call methods on generic objects that are passed into it, it cannot be covariant.
Archetypal examples:
Seq[+A], Option[+A], Future[+T]
A type can be contravariant when it does call methods on the type that it is generic over.
If the type needs to return values of the type it is generic over, it cannot be contravariant.
Archetypal examples:
`Function1[-T1, +R]`, `CanBuildFrom[-From, -Elem, +To]`, `OutputChannel[-Msg]`
Regarding contravariance,
Functions are the best example of contravariance
(note that they’re only contravariant on their arguments, and they’re actually covariant on their result).
For example:
class Dachshund(
name: String,
likesFrisbees: Boolean,
val weinerness: Double
) extends Dog(name, likesFrisbees)
def soundCuteness(animal: Animal): Double =
-4.0/animal.sound.length
def weinerosity(dachshund: Dachshund): Double =
dachshund.weinerness * 100.0
def isDogCuteEnough(dog: Dog, f: Dog => Double): Boolean =
f(dog) >= 0.5
Should we be able to pass weinerosity as an argument to isDogCuteEnough? The answer is no, because the function isDogCuteEnough only guarantees that it can pass, at most specific, a Dog to the function f.
When the function f expects something more specific than what isDogCuteEnough can provide, it could attempt to call a method that some Dogs don’t have (like .weinerness on a Greyhound, which is insane).
That you can pass a List[Beagle] to a function expecting a List[Dog] is nothing to do with contravariance of functions, it is still because List is covariant and that List[Beagle] is a List[Dog].
Instead lets say you had a function:
def countDogsLegs(dogs: List[Dog], legCountFunction: Dog => Int): Int
This function counts all the legs in a list of dogs. It takes a function that accepts a dog and returns an int representing how many legs this dog has.
Furthermore lets say we have a function:
def countLegsOfAnyAnimal(a: Animal): Int
that can count the legs of any animal. We can pass our countLegsOfAnyAnimal function to our countDogsLegs function as the function argument, this is because if this thing can count the legs of any animal, it can count legs of dogs, because dogs are animals, this is because functions are contravariant.
If you look at the definition of Function1 (functions of one parameter), it is
trait Function1[-A, +B]
That is that they are contravariant on their input and covariant on their output. So Function1[Animal,Int] <: Function1[Dog,Int] since Dog <: Animal
Variance is used to indicate subtyping in terms of Containers(eg: List). In most of the languages, if a function requests object of Class Animal, passing any class that inherits Animal(eg: Dog) would be valid. However, in terms of Containers, these need not be valid.
If your function wants Container[A], what are the possible values that can be passed to it? If B extends A and passing Container[B] is valid, then it is Covariant(eg: List[+T]). If, A extends B(the inverse case) and passing Container[B] for Container[A] is valid, then it is Contravariant. Else, it is invariant(which is the default). You could refer to an article where I have tried explaining variances in Scala
https://blog.lakshmirajagopalan.com/posts/variance-in-scala/

How is Scala's Covariance, Contravariance useful?

I've been learning about scala's use of covariance and contravariance parameterized typing; I'm a bit perplexed by the following example code:
class Thing
class Creature extends Thing
class Human extends Creature
class Dog extends Creature
class Home[T >: Creature] {
private var inside = Set[T]()
def enter(entering: T) = inside += entering
def whoIsInside = inside
}
val house = new Home[Thing]
val cage = new Home[Creature]
house enter new Human
cage enter new Dog
As I understand it, the parameterized class Home uses contravariance with a lower bound of Creature, so
val flat = new Home[Human]
causes a compiler error, which is what I expected. My predicament is, I've created a new 'house' but I can put a 'Human' in it! While this also makes sense because a 'Human' is a 'Thing' I was naively expecting it to fail! Putting aside the mechanics, how is covariance, contravariance useful?
In your example, you can put subtypes of T into the collection of T, because U <: T is also a T. That is not covariance or contravariance.
Covariance would be when your House[U] is a subtype of a House[T] for U <: T. So if for example you asked for a House[Creature] you could offer a House[Human] if T was covariant. We use the + on a type parameter for covariance.
Eg,
class Home[+T]
val cage: Home[Creature] = new Home[Human]
The most useful example of this is when you use Nil for a List, because Nil is a List[Nothing] and List is covariant. So a List[Nothing] can substitute for any type of List at all.
Contravariance is the opposite. That a House[U] is a supertype of House[T] if U <: T. We use the - on a type parameter for contravariance.
Eg,
class Home[-T]
val cage: Home[Human] = new Home[Creature]
Before answering the question, I need to note two things:
a) you are not using covariance / contravariance in your example, you merely define a lower bound
b) in the title, you imply that this is a Scala concept. Covariance and contravariance are general concepts in object orientation, and have existed long before Scala.
So regarding your original question, how is it useful? It allows you to specify inheritance for parameterized types. For example, if you defined you type parameter as covariant, maybe with Creature as an upper bound, you could express that a dog's home can stand in for a creature's home:
scala> class Home[+T <: Creature]
defined class Home
scala> var home = new Home[Creature]
home: Home[Creature] = Home#46a32efb
scala> home = new Home[Dog]
home: Home[Creature] = Home#1b955e70
So Home[Dog] is a subtype of of Home[Creature] - covariance allows you to express this.
Also note that in your example just making the type parameter covariant would not compile, as you allow entering. The method parameter can not be covariant, as that would break the substitutability. The Scala compiler will detect this for you.

Scala: Type parameters and inheritance

I'm seeing something I do not understand. I have a hierarchy of (say) Vehicles, a corresponding hierarchy of VehicalReaders, and a VehicleReader object with apply methods:
abstract class VehicleReader[T <: Vehicle] {
...
object VehicleReader {
def apply[T <: Vehicle](vehicleId: Int): VehicleReader[T] = apply(vehicleType(vehicleId))
def apply[T <: Vehicle](vehicleType VehicleType): VehicleReader[T] = vehicleType match {
case VehicleType.Car => new CarReader().asInstanceOf[VehicleReader[T]]
...
Note that when you have more than one apply method, you must specify the return type. I have no issues when there is no need to specify the return type.
The cast (.asInstanceOf[VehicleReader[T]]) is the reason for the question - without it the result is compile errors like:
type mismatch;
found : CarReader
required: VehicleReader[T]
case VehicleType.Car => new CarReader()
^
Related questions:
Why cannot the compiler see a CarReader as a VehicleReader[T]?
What is the proper type parameter and return type to use in this situation?
I suspect the root cause here is that VehicleReader is invariant on its type parameter, but making it covariant does not change the result.
I feel like this should be rather simple (i.e., this is easy to accomplish in Java with wildcards).
The problem has a very simple cause and really doesn't have anything to do with variance. Consider even more simple example:
object Example {
def gimmeAListOf[T]: List[T] = List[Int](10)
}
This snippet captures the main idea of your code. But it is incorrect:
val list = Example.gimmeAListOf[String]
What will be the type of list? We asked gimmeAListOf method specifically for List[String], however, it always returns List[Int](10). Clearly, this is an error.
So, to put it in words, when the method has a signature like method[T]: Example[T] it really declares: "for any type T you give me I will return an instance of Example[T]". Such types are sometimes called 'universally quantified', or simply 'universal'.
However, this is not your case: your function returns specific instances of VehicleReader[T] depending on the value of its parameter, e.g. CarReader (which, I presume, extends VehicleReader[Car]). Suppose I wrote something like:
class House extends Vehicle
val reader = VehicleReader[House](VehicleType.Car)
val house: House = reader.read() // Assuming there is a method VehicleReader[T].read(): T
The compiler will happily compile this, but I will get ClassCastException when this code is executed.
There are two possible fixes for this situation available. First, you can use existential (or existentially quantified) type, which can be though as a more powerful version of Java wildcards:
def apply(vehicleType: VehicleType): VehicleReader[_] = ...
Signature for this function basically reads "you give me a VehicleType and I return to you an instance of VehicleReader for some type". You will have an object of type VehicleReader[_]; you cannot say anything about type of its parameter except that this type exists, that's why such types are called existential.
def apply(vehicleType: VehicleType): VehicleReader[T] forSome {type T} = ...
This is an equivalent definition and it is probably more clear from it why these types have such properties - T type is hidden inside parameter, so you don't know anything about it but that it does exist.
But due to this property of existentials you cannot really obtain any information about real type parameters. You cannot get, say, VehicleReader[Car] out of VehicleReader[_] except via direct cast with asInstanceOf, which is dangerous, unless you store a TypeTag/ClassTag for type parameter in VehicleReader and check it before the cast. This is sometimes (in fact, most of time) unwieldy.
That's where the second option comes to the rescue. There is a clear correspondence between VehicleType and VehicleReader[T] in your code, i.e. when you have specific instance of VehicleType you definitely know concrete T in VehicleReader[T] signature:
VehicleType.Car -> CarReader (<: VehicleReader[Car])
VehicleType.Truck -> TruckReader (<: VehicleReader[Truck])
and so on.
Because of this it makes sense to add type parameter to VehicleType. In this case your method will look like
def apply[T <: Vehicle](vehicleType: VehicleType[T]): VehicleReader[T] = ...
Now input type and output type are directly connected, and the user of this method will be forced to provide a correct instance of VehicleType[T] for that T he wants. This rules out the runtime error I have mentioned earlier.
You will still need asInstanceOf cast though. To avoid casting completely you will have to move VehicleReader instantiation code (e.g. yours new CarReader()) to VehicleType, because the only place where you know real value of VehicleType[T] type parameter is where instances of this type are constructed:
sealed trait VehicleType[T <: Vehicle] {
def newReader: VehicleReader[T]
}
object VehicleType {
case object Car extends VehicleType[Car] {
def newReader = new CarReader
}
// ... and so on
}
Then VehicleReader factory method will then look very clean and be completely typesafe:
object VehicleReader {
def apply[T <: Vehicle](vehicleType: VehicleType[T]) = vehicleType.newReader
}

Scala type parameter bracket

I know trait Foo[T] means T is a parametrized type.
But some times I can see trait Foo[T1,T2], or trait Foo[T1,T2,R], I cannot find anywhere describe the meaning of multiple types inside a type bracket, could you please point me the usages in this case? From what I speculate, Foo[T1,T2] just means, it defined two type parameters, it doesn't have to be take a T1 and return a T2.
When I read playframework documentation today, I again found myself confused about this question. In the documentation, it says:
A BodyParser[A] is basically an Iteratee[Array[Byte],A], meaning that
it receives chunks of bytes (as long as the web browser uploads some
data) and computes a value of type A as result.
This explanation sounds like, the second the type parameter inside a type bracket is a return type.
I also remember that trait Function2 [-T1, -T2, +R] extends AnyRef means a function that takes a T1 and T2, return a R.
Why do they put the return type in the bracket? Does it mean all the last parameter in a bracket is a return type? Or they just happened defined a new type R for the return type?
From what I speculate, Foo[T1,T2] just means, it defined two type parameters, it doesn't have to be take a T1 and return a T2.
A type parameter means nothing more than "I need any type but I'm not interested to know what it is for a concrete type", where 'I' is the programmer who writes the code. Type parameters can used like any other types such as Int, String or Complex - the only difference is that they are not known until one uses them.
See type Map[A, +B]. When you first read this, you can't know what the A and B are for, thus you have to read the documentation:
A map from keys of type A to values of type B.
It explains the types and their meaning. There is nothing more to know or understand. They are just two types. It is possible to call Map something like Map[Key, Value] but inside of source code it is better when type parameters have only one or two letters. This makes it easier to differ between the type parameters and concrete types.
It is the documentation which specifies what a type parameter means. And if there is no documentation you have to take a look to the sources and find their meaning by yourself. For example you have to do this with Function2 [-T1, -T2, +R]. The documentation tells us only this:
A function of 2 parameters.
Ok, we know that two of the three type parameters are parameters the function expects, but what is the third one? We take a look to the sources:
def apply(v1: T1, v2: T2): R
Ah, now we know that T1 and T2 are the parameters and that R is a return type.
Type parameters also can be found in method signatures like map:
class List[+A] {
..
def map[B](f: (A) ⇒ B): List[B]
}
This is how map looks like when you use it with a List. A can be any type - it is the type of the elements a list contains. B is another arbitrary type. When you know what map does then you know what B does. Otherwise you have to understand map before. map expects a function which can transform each element of a List to another element. Because you know that A stands for the elements of the List you can derive from yourself that B have to be the type A is transformed to.
To answer all your other questions: This shouldn't be done in a single answer. There are a lot of other questions and answers on StackOverflow which can also answer your questions.
Summary
When you see some type parameters for example in Foo[T1, T2] you should not start to cry. Think: "Ok, I have a Foo which expects a T1 and a T2 and if I want to know what they do I have to read documentation or the sources."
Multiple types inside a type bracket means type parametrization on multiple types. Take for example
trait Pair[A, B]
This is a pair of values one having type A the other having type B.
Update:
I think you are interpreting too much into the semantics of type parameters. A type parametrized by multiple parameters is just that and nothing more. The position of a specific type parameter in the list of type parameters does not make it special in any way. Specifically the last parameter in a list of type parameters does not need to stand for 'the return type'.
The sentence from the play framework which you quoted explains the semantics of the type parameters for this one specific type. It does not generalize to other types. The same holds for the Function types: here the last type parameter happens to mean 'the return type'. This is not necessarily the case for other types though. The type Pair[A, B] from above is such an example. Here B is the type of the second component of the pair. There is no notion of a 'return type' here at all.
Type parameters of a parametrized type can appear anywhere inside the definition of the parametrized type where a 'regular' type could appear. That is, type parameters are just names for types which are bound to the actual types only when the parametrized type itself is instantiated.
Consider the following definition of a class Tuple:
class Tuple[A, B](a: A, b: B)
It is instantiated to a type of a tuple of Int and String like this:
type TupleIntString = Tuple[Int, String]
Which is essentially the same as
class TupleIntString(a: Int, b: String)
For an official source check the Scala Language Specification. Specifically Section 3.4 "Base Types and Member Definitions" under 1. the 4th bullet point says: "The base types of a parameterized type C[T_1, ..., T_n] are the base types of type C , where every occurrence of a type parameter a_i of C has been replaced by the corresponding parameter type T_i."
I think your question can actually be broken in three separate problems:
What's with the multiple type parameters for classes/traits/etc. ?
A classic example is a map from one type of object to another. If you want the type for the keys to be different from type of the value, but keep both generic, you need two type parameters. So, a Map[A,B] takes keys of generic type A and maps to values of generic type B. A user that wants a map from Bookmarks to Pages would declare it as Map[Bookmark, Page]. Having only one type parameters would not allow this distinction.
From what I speculate, Foo[T1,T2] just means, it defined two type parameters, it doesn't have to be take a T1 and return a T2.
No, all type parameters are equal citizens, though they have a meaning in that direction for function objects. See below.
What are all those +/-'s ?
They limit what the type parameters can bind to. The Scala by Example tutorial has a good explanation. See Section 8.2 Variance Annotations.
What is a function in scala?
Why do they put the return type in the bracket? Does it mean all the
last parameter in a bracket is a return type? Or they just happened
defined a new type R for the return type?
The Scala by Example tutorial explains this well in Section 8.6 Functions.
Their role is a bit similar to the ones (i.e. multiple type parameter) in a class, since traits are, after all, classes (without any constructor) meant to be added to some other class as a mixin.
The Scala spec gives the following example for Trait with multiple parameters:
Consider an abstract class Table that implements maps from a type of keys A to a type of values B.
The class has a method set to enter a new key/value pair into the table, and a method get that returns an optional value matching a given key.
Finally, there is a method apply which is like get, except that it returns a given default value if the table is undefined for the given key. This class is implemented as follows.
abstract class Table[A, B](defaultValue: B) {
def get(key: A): Option[B]
def set(key: A, value: B)
def apply(key: A) = get(key) match {
case Some(value) => value
case None => defaultValue
}
}
Here is a concrete implementation of the Table class.
class ListTable[A, B](defaultValue: B) extends Table[A, B](defaultValue) {
private var elems: List[(A, B)]
def get(key: A) = elems.find(._1.==(key)).map(._2)
def set(key: A, value: B) = { elems = (key, value) :: elems }
}
Here is a trait that prevents concurrent access to the get and set operations of its
parent class
trait Synchronized Table[A, B] extends Table[A, B] {
abstract override def get(key: A): B =
synchronized { super.get(key) }
abstract override def set((key: A, value: B) =
synchronized { super.set(key, value) }
}
Note that SynchronizedTable does not pass an argument to its superclass, Table,
even though Table is defined with a formal parameter.
Note also that the super calls in SynchronizedTable’s get and set methods statically refer to abstract methods in class Table. This is legal, as long as the calling method is labeled abstract override (§5.2).
Finally, the following mixin composition creates a synchronized list table with
strings as keys and integers as values and with a default value 0:
object MyTable extends ListTable[String, Int](0) with SynchronizedTable
The object MyTable inherits its get and set method from SynchronizedTable.
The super calls in these methods are re-bound to refer to the corresponding implementations in ListTable, which is the actual supertype of SynchronizedTable in
MyTable.