Reputation: 992
The following does not compile because of extends AnyVal
as it gives the following compilation error:
value class needs to have exactly one val parameter
Here's the code (simplified):
sealed trait Thing[A] {
// stuff
}
object RichThing {
implicit final class Implicits[A: ClassTag](val thing: A) extends AnyVal {
def doSomething[B: ClassTag](f: A => B): Thing[A] = {
// use f internally
}
}
}
The thing is that I cannot touch the library that Thing[A]
is in and I'm trying to extend it so that for our internal users the additional functions feel seamless as per usual for implicit conversions.
I can remove AnyVal
but is there a way around that restriction for my case (in 2.11)?
Upvotes: 1
Views: 260
Reputation: 14224
A value class must have only one argument, and your Implicits
class has two: the explicit val thing: A
and an implicit one with type ClassTag[A]
coming from the context bound [A: ClassTag]
.
To satisfy the value class requirement, you can move the implicit parameter ClassTag[A]
from the context bound to individual functions signatures:
implicit final class Implicits[A](val thing: A) extends AnyVal {
def doSomething[B: ClassTag](f: A => B)(implicit tagA: ClassTag[A]): Thing[A] = {
// use f internally
}
}
You are using this class just to provide rich methods, so it doesn't really matter at what point the implicits get injected.
Of course, you can just remove extends AnyVal
, but then an actual Implcits
object will be instantiated for every doSomething
invocation, which is just needless pessimization.
Upvotes: 5