1

I imagined this would work. Am I doing something clearly wrong?

val apply = (f: Any => Any, v: Any) => f(v)
val square = (x: Int) => x * x

I imagined apply(square, 10) would result in 100.

But I get an error:

:15: error: type mismatch;
 found   : Int => Int
 required: Any => Any
       apply(square, 100)

What I am missing here?

1 Answer 1

3

Functions are covariant in their return types, but contravariant in arguments. Int => Int is a subclass of Int => Any, but not of Any => Int or Any => Any (if it was, you could use in a context where, for example, a String parameter is passed in, and it would not be able to handle it, because it wants an Int).

Cosider this:

val foo: Function[Int, Int] = { x => x * x }    
def bar(f: Any => Any)(arg: Any): Any = f(arg) 

bar(foo)("foo") //???

The if Int => Int was a subclass of Any => Any, then the last line would be valid. But it cannot be, because it would result in foo being called with a String parameter.

Note, on the other hand, that Any => Int is a subclass of Int => Int (you can use the former anywhere the latter is required). This is what being "contravariant" means.

Sign up to request clarification or add additional context in comments.

4 Comments

Worth adding: if you change the definition of apply (in the question) to def apply[T] = (f: T => T, v: T) => f(v), it would work, because this way the types of v, f's input and f's output are known to be the same type.
@TzachZohar Not because they are "known to be the same type" (that is the case with the original example as well), but rather because apply[Any] and apply[Int] are essentially two different functions in this case.
@Dima, if functions are contravariant in their arguments, can I say that Any => Int is a subclass of Int => Int?
@RodrigoStv yes, you can. In fact, that is exactly what I said in the last paragraph of my answer ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.