user1147070
user1147070

Reputation: 491

Why am I getting a type-mismatch error, here?

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

Answers (2)

justAbit
justAbit

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

Luka Jacobowitz
Luka Jacobowitz

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

Related Questions