Scalac 对具有类型参数的特征隐式值类的限制

Max*_*wer 1 scala

以下内容无法编译,因为extends AnyVal它给出了以下编译错误:

value class needs to have exactly one val parameter
Run Code Online (Sandbox Code Playgroud)

这是代码(简化):

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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

问题是我无法触及Thing[A]其中的库,并且我正在尝试扩展它,以便对于我们的内部用户来说,附加功能就像通常的隐式转换一样无缝。

我可以删除AnyVal,但是有没有办法绕过我的情况的限制(2.11 中)?

Kol*_*mar 5

值类必须只有一个参数,而您的Implicits类有两个:显式参数val thing: A和隐式参数,其类型ClassTag[A]来自上下文绑定[A: ClassTag]

为了满足值类要求,您可以将隐式参数ClassTag[A]从上下文绑定到各个函数签名:

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
  }
}
Run Code Online (Sandbox Code Playgroud)

您使用此类只是为了提供丰富的方法,因此在什么时候注入隐式并不重要。

当然,您可以只删除extends AnyVal,但是Implcits每次调用都会实例化一个实际的对象doSomething,这只是不必要的悲观。