13

I thought this would be correct usage of the new implicit classes of Scala 2.10:

implicit case class IntOps(i: Int) extends AnyVal {
  def twice = i * 2
}

11.twice

Apparently not:

<console>:13: error: value twice is not a member of Int
              11.twice
                 ^

Am I missing something (Scala 2.10.0-M6)?

0__
  • 66,707
  • 21
  • 171
  • 266

2 Answers2

21

A clue is the desugaring of implicit classes, explained in the SIP-13:

implicit class RichInt(n: Int) extends Ordered[Int] {
def min(m: Int): Int = if (n <= m) n else m
...
}

will be transformed by the compiler as follows:

class RichInt(n: Int) extends Ordered[Int] {
def min(m: Int): Int = if (n <= m) n else m
...
}
implicit final def RichInt(n: Int): RichInt = new RichInt(n)

As you can see, the implicit function that is created has the same name as the original classes. I guess it's done like this to make implicit classes easier to import.

Thus in your case, when you create an implicit case class, there is a conflict between the method name created by the implicit keyword and the companion object created by the case keyword.

Nicolas
  • 24,509
  • 5
  • 60
  • 66
  • To me, this looks more like a bug. `case` creates an `apply` method, implicit a method with the name of the class. – soc Aug 13 '12 at 12:14
  • @Nicolas sorry for asking after 3+ years. But I would appreciate if you can show how to obtain the desugared code. Thanks – Polymerase Nov 16 '16 at 14:59
  • @Polymerase In that cas, I took the definition from the SIP. You can however, use `scalac -Xprint:parse ` to see how the code is desugared. You can see [this answer](http://stackoverflow.com/a/9892350/1730) and its comment. – Nicolas Nov 17 '16 at 09:51
2

This shows there is an ambiguity:

val ops: IntOps = 11

<console>:11: error: ambiguous reference to overloaded definition,
both method IntOps of type (i: Int)IntOps
and  object IntOps of type IntOps.type
match argument types (Int) and expected result type IntOps
       val ops: IntOps = 11
                         ^

Not sure what exactly happens. But when not using a case class it seems fine:

implicit class IntOps(val i: Int) extends AnyVal {
  def twice = i * 2
}

11.twice  // ok
0__
  • 66,707
  • 21
  • 171
  • 266