Closed kubukoz closed 4 years ago
You can unimport it: import Predef.{any2stringadd => _}
.
And you can use -Yimports
project-wide.
Nope, that still shows the same type mismatch error... and -Yimports
isn't an option in 2.12 which I'm currently stuck on :(
Do you get something else? 🤔
❯ scala
Welcome to Scala 2.12.11 (OpenJDK 64-Bit Server VM, Java 12.0.2).
Type in expressions for evaluation. Or try :help.
scala> object A
defined object A
scala> A + ""
res0: String = A$@2d119405
scala> import Predef.{any2stringadd => _}
import Predef.{any2stringadd=>_}
scala> A + ""
<console>:14: error: value + is not a member of object A
A + ""
^
I get the same in the REPL, but not in the normal compilations. I think that's on purpose: https://github.com/scala/scala/pull/4554
This also doesn't compile for me:
import Predef.{any2stringadd => _}
object Scratch {
object A
A + ""
}
Okay, I actually hadn't checked that (just extrapolated a bit from the newtype example, sorry!).
That works. But not on a newtype...
This is an annoying problem with Scala's implicit resolution precedence (and stdlib). Here are three ways around it.
First, @joroKr21's solution seems to work for me -
import Predef.{any2stringadd => _}
import io.estatico.newtype.macros.newtype
object Main {
@newtype case class Demo(value: Int) {
def +(another: Demo): Demo = Demo(value + another.value)
}
def main(args: Array[String]): Unit = {
val demo: Demo = Demo(1) + Demo(2)
System.out.println(demo)
}
}
Second, create your own implicit which has higher precedence than any2stringadd
-
import io.estatico.newtype.macros.newtype
object Main {
@newtype case class Demo(value: Int)
implicit final class Ops(private val demo: Demo) extends AnyVal {
def +(another: Demo): Demo = Demo(demo.value + another.value)
}
def main(args: Array[String]): Unit = {
val demo: Demo = Demo(1) + Demo(2)
System.out.println(demo)
}
}
Third, import the macro-generated Ops$newtype
class explicitly -
import io.estatico.newtype.macros.newtype
import Main.Demo.Ops$newtype
object Main {
@newtype case class Demo(value: Int) {
def +(another: Demo): Demo = Demo(value + another.value)
}
def main(args: Array[String]): Unit = {
val demo: Demo = Demo(1) + Demo(2)
System.out.println(demo)
}
}
I'm going to go ahead and close this, but if there are still unresolved issues, please re-open.
Hi! Thanks for a wonderful library.
We're hitting an interesting issue:
If I just say
d +
, I getmissing argument list for method + in class any2stringadd
. As far as I could find out, that method gets special treatment and can't be unimported.I took a look at the implementation of newtypes and as far as I could tell methods from the class are moved to an implicit class next to it, to which a conversion called
Demo.Ops$newtype
is applied - when I apply it manually, or import it (import Demo._
or by exact name) it compiles as expected. I assumeany2stringadd
just has higher precedence because it's imported.Is there something scala-newtype can do to allow this name in methods on newtypes?