Reputation: 491
I am unable to understand why the below code gives type mismatch error - Here I am using generics and at line 11 it is giving type mismatch error. Shouldn't it interpret T as Int.
object FunctionParamGeneric {
def main(args: Array[String]) : Unit= {
exec[Int](Fun[Int])
}
def exec[T]( f:() => T) : T = {
println("Inside exec")
f()
}
def Fun[T]() : T = {
println("Inside Fun with key ")
123
}
}
However, if I do
object FunctionParamGeneric {
def main (args: Array[String]) : Unit= {
exec[Int](() => 1)
}
def exec[T]( f:() => T) : T = {
println("Inside exec")
f()
}
}
It works fine. Because f
is inferred to be called with an Int
in the second snippet, I would expect the same to happen in the in first code snippet, but that's not the case. Why not?
Upvotes: 1
Views: 273
Reputation: 4256
First snippet:
You get error because you have specified generic return type for Fun
while you are returning Int
.
Suppose if this expression was allowed, now consider these two statements:
Fun[Int]() // would have returned 123
Fun[String]() // what would be output?
The first statement would have returned 123
without any problem but what would be the output in second case?
That's why such expressions are not allowed.
Second snippet:
In second snippet it works because when you use exec[Int](() => 1)
, you are passing a literal function as argument while in first snippet you giving definition of Fun
.
To explain it further, if you look at the definition of exec
:
def exec[T]( f:() => T) : T
It takes a Function0
function (which can return any type) as parameter. So when you call exec[Int](() => 1)
, you are passing function () => 1
which returns Int
(Note that this is not a generic function). Hence it works.
While in the first snippet, you were defining a generic function Fun
with generic return type. But from the body of the function you were returning Int
value.
Upvotes: 3
Reputation: 23532
Your problem lies here:
def Fun[T]() : T = {
println("Inside Fun with key ")
123
}
You're implicitly returning 123
. Which isn't of type T
, but of type Int
. So the compiler generates an error.
If you want Fun
to always return an Int
you can do that, by defining it as Fun(): Int = ...
.
Then you should be able to call
exec[Int](Fun)
Upvotes: 1