user116948
user116948

Reputation: 23

Scala Generic function assuming type

When trying to define a generic method def f[T] (x:T) = x + 1 Scala gives below error

<console>:8: error: type mismatch;
found   : Int(1)
required: String
   def f[T] (x:T) = x + 1
                        ^

The question is why Scala is assuming that it should be a String?

What if we want a function that can do +1 to Int, Char and String. I know I can do something like below, but it would work only on Int and Char.

def f[T <% Int](x:T) = x + 1

So what's the reason of this error and how to handle it in generic way.

Upvotes: 2

Views: 135

Answers (2)

user64287
user64287

Reputation: 53

The return type of the function will always be Int as I assume so it should be that the compiler choose Int but why String.

Upvotes: 0

kdgregory
kdgregory

Reputation: 39606

The question is why Scala is assuming that it should be a String?

I can't guarantee this analysis, but it appears that Scala is applying the Predef.any2stringadd() implicit conversion to x, in an attempt to turn it into something that supports the + operator.

Here's a variant that will compile, and which demonstrates that implicit conversion:

scala> def f(x:Any) = { x + "1" }
f: (x: Any)String

scala> f("foo")
res3: String = foo1

scala> f(123)
res0: String = 1231

scala> f(classOf[String])
res2: String = class java.lang.String1

What if we want a function that can do +1 to Int, Char and String.

What does it mean to add 1 to any of these values?

If you simply want to invoke the + operator, then you need to use the match operator to select different behaviors depending on the actual type. This is because, while the name + is used for both, there's no common behavior between strings and numbers.

On the other hand, perhaps you want to deal with numbers that can be provided as either strings or numeric values (in which case, why Char?). To make that work, you need an implicit function that converts Any to a number.

scala> implicit def any2int(x:Any) : Int = { x.toString.toInt }
warning: there were 1 feature warning(s); re-run with -feature for details
any2int: (x: Any)Int

scala> def f(x:Any) : Int = { x + 1 }
f: (x: Any)Int

scala> f(123)
res0: Int = 124

scala> f("123")
res1: Int = 124

Upvotes: 3

Related Questions