user3025403
user3025403

Reputation: 1080

scala.Any in the Scala Class Hierarchy

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

Answers (1)

dhg
dhg

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

Related Questions