# Implicit conversion vs operators

version: 2.12.7

Am I doing something wrong or this is a bug, or how can I make the `+` operator work?

``````
def add(s: A, i: Int): A
}

case class MyTest(i: Int)

def add(s: MyTest, i: Int) = MyTest(s.i + i)
}

def +[B](i: B)(implicit n: Numeric[B]) = {
}
def add[B](i: B)(implicit n: Numeric[B]) = {
}
}

val a = MyTest(2)

a + 5
``````

Here the `a.add(5)` works as expected, and the `a + 5` is not working, I think bcs of the needed implicit parameter of the `(5)(numeric[Int])`.

So I went a bit further and refactored it a bit:

``````trait Adder[A] {
def add(s: A, i: Int): A
}

trait NumericForOps[A] {
val a: A
val fa: Numeric[A]
}

object NumericForOps {
def apply[A](s: A)(implicit ev: Numeric[A]): NumericForOps[A] =
new NumericForOps[A] {
val a = s
val fa = ev
}
}

implicit def autoNumericForOps[A](s: A)(implicit ev: Numeric[A]): NumericForOps[A] = NumericForOps(s)

case class MyTest(i: Int)

def add(s: MyTest, i: Int) = MyTest(s.i + i)
}

def +[B](i: NumericForOps[B]) = {
}
}
}

val a = MyTest(2)

a + 5
``````

If I desugar with IntelliJ they both desugared to the “same” code. So why the `a+5` is not working? And how can I make it work?

This works:

``````object any2stringadd

def add(s: A, i: Int): A
}

case class MyTest(i: Int)

def add(s: MyTest, i: Int) = MyTest(s.i + i)
}

def +[B](i: B)(implicit n: Numeric[B]) = {
}
def add[B](i: B)(implicit n: Numeric[B]) = {
}
}

val a = MyTest(2)

a + 5
``````

I only added the first line.

So the reason it didn’t work is that there is an implicit conversion `any2stringadd` which adds a `+` method to `Any`. When the compiler now looks for a `+` method it finds your implicit conversion and `any2stringadd`, doesn’t know which to choose and compilation fails.

The reason my code worked is that my `any2stringadd` shadows `Predef.any2stringadd` so it is no longer eligible as an implicit conversion.

Hmm. In one way: “Clever” In other ways: “Why???” Btw IntelliJ has 0 idea what happens, but the code compiles as expected I started to refactor a codebase which transforms an inner ADT structure to languages, and I didn’t want to break hardly the already existing code, I think this will work as a minimal effort refactor, and I hope nobody uses “+” and “-” between those things.

Thanks the help and the explanation!

Basically, `any2stringadd` seemed like a good idea at the time, back in the early days of the language, since being able to concatenate anything to a String was convenient for building complex Strings. But in the years since, we’ve gained string interpolation (generally a better way to do it), and this has proven to be a frequently inconvenient misfeature.

I think there’s a fair consensus that it’s more trouble than it’s worth. Personally, I’m hoping it goes away in Scala 3.

Note that `any2stringadd` is formally deprecated in Scala 2.13:

``````scala 2.13.0> (new AnyRef) + "foo"
^
warning: method any2stringadd in object Predef is deprecated (since 2.13.0): Implicit injection of + is deprecated. Convert to String to call +
res1: String = java.lang.Object@24e83d19foo
scala 2.13.0> 3 + "foo"
^
warning: method + in class Int is deprecated (since 2.13.0): Adding a number and a String is deprecated. Use the string interpolation `s"\$num\$str"`
res0: String = 3foo
``````
2 Likes