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)?
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With