Reputation: 23
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
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
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