Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Scala 2.10 implicit classes

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)?

like image 400
0__ Avatar asked Aug 13 '12 09:08

0__


People also ask

How do implicit classes work Scala?

Scala 2.10 introduced a new feature called implicit classes. An implicit class is a class marked with the implicit keyword. This keyword makes the class's primary constructor available for implicit conversions when the class is in scope. Implicit classes were proposed in SIP-13.

What is implicit object in Scala?

In Scala, objects and values are treated mostly the same. An implicit object can be thought of as a value which is found in the process of looking up an implicit of its type.

What is implicit conversion in Scala?

Implicit conversions in Scala are the set of methods that are apply when an object of wrong type is used. It allows the compiler to automatically convert of one type to another. Implicit conversions are applied in two conditions: First, if an expression of type A and S does not match to the expected expression type B.


2 Answers

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.

like image 140
Nicolas Avatar answered Oct 12 '22 13:10

Nicolas


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
like image 38
0__ Avatar answered Oct 12 '22 11:10

0__