While dealing with some Java code, I wanted to find a way to reduce a Raw Set to include its parameterized type.
I also wanted it to work for Scala sets as well, so I did the following
implicit class Harden[S <% mutable.Set[_]](val set: S) extends AnyVal {
def cast[T] = set.map(_.asInstanceOf[T])
}
That resulted in a compiler error that I didn't expect
Error:(27, 27) field definition is not allowed in value class
implicit class Harden[S <% mutable.Set[_]](val set: S) extends AnyVal {
I didn't find any mention of this type of restriction in the Scala View Bounds or Value Class documentation.
Why is this not allowed? I'm using Scala 2.10.3.
As you can see from this sbt console output:
scala> :type implicit class Harden[S <% mutable.Set[_]](val set: S)
[S]AnyRef {
val set: S
private[this] val set: S
implicit private[this] val evidence$1: S => scala.collection.mutable.Set[_]
def <init>(set: S)(implicit evidence$1: S => scala.collection.mutable.Set[_]): Harden[S]
}
... the actual constructor of Harden
desugars behind the scenes to:
def <init>(set: S)(implicit evidence$1: S => scala.collection.mutable.Set[_]): Harden[S]
... (i.e. takes set
in one argument list and implicit evidence$1
in another).
As described in value classes limitations here:
must have only a primary constructor with exactly one public, val parameter whose type is not a value class.
... whitch means that Harden
violaties this limitation.
You can achieve something similar, howerver. Try to convert your view bound defined on class to implicit evidence on method instead.
Something like this:
scala> implicit class Harden[S](val set: S) extends AnyVal {
| def cast[T](implicit ev: S => scala.collection.mutable.Set[_]) = set.map(_.asInstanceOf[T])
| }
defined class Harden
This will compile:
scala> Set(1,2,3).cast[Any]
res17: scala.collection.mutable.Set[Any] = Set(1, 2, 3)
And this will fail, as expected:
scala> List(1,2,3).cast[Any]
<console>:24: error: No implicit view available from List[Int] => scala.collection.mutable.Set[_].
List(1,2,3).cast[Any]
^
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