Reputation: 1080
In Scala, many types extend Any. Click here for a diagram of the Scala Class Hierarchy.
For instance, Double and Tuple both extend Any and the code below works as expected:
def foo(x: Any) { println(x.toString) }
foo(3.0) // prints: 3.0
foo((2,3)) //prints: (2,3)
However, I don't understand why the following doesn't work, since it follows all the logic above:
def bar(fn: Any => String) { println(fn.toString) }
def dub(d: Double): String = "dub"
def tup(tup: (Int, Int)): String = "tup"
bar(dub) // ERROR
bar(tup) // ERROR
Calling bar(dub) and bar(tup) both result in a type mismatch error. For bar(dub) the compiler says:
error: type mismatch;
found: Double => String
required: Any => String
Can someone explain to me why there is a type mismatch in the second case even though Any is a supertype?
Upvotes: 0
Views: 102
Reputation: 52681
Because Double => String
is not a subtype of Any => String
.
Think of it this way: bar
requires an argument that is a function that can turn anything into a string. You are giving it a function that can turn a double into a string, but it's not able to turn anything else into a string. Thus, it's not what bar
is looking for.
Note that the reverse would hold: a Double => String
argument would be able to accept an Any => String
function.
The reason for this is that Function1
is defined as Function1[-T1, +R]
, and the -T1
means that the first type parameter is contravariant (the second is covariant). You can read more here or here.
Upvotes: 8