user79074
user79074

Reputation: 5280

Covariance in a function reference

Say I define the following list and two function references:

var list = List[Any => String]()

val f1: Any => String = _.toString
val f2: Int => String = _.toString

When I try to add them to the list thus:

list :+= f1
list :+= f2

My second line won't compile with the following error:

found : List[Int => String]

required: List[Any => String]

Is there some way I can define my list to make the Any parameter covariant so I can assign functions other than those with 'Any' parameters?

Upvotes: 1

Views: 27

Answers (1)

Michael Zajac
Michael Zajac

Reputation: 55569

Is there some way I can define my list to make the Any parameter covariant so I can assign functions other than those with 'Any' parameters?

There isn't, because the parameter types of a FunctionN are contravariant. An Any => A is near the bottom of the type tree. An Any => String is an Int => String, but not the other way around.

An Any => String is a function that can accept anything as an argument, and returns a String. It knows what to do in all cases, because every type extends Any. But an Int => String only handles Int arguments, so there are infinitely many types that it cannot handle as arguments, and casting it to Any => String wouldn't make sense. It would fail.

Imagine you change f2 to be:

 val f2: Int => String = i => (i * 2).toString

How can you change that to work with Any? The answer is you can't.

Upvotes: 4

Related Questions