如何在 Scala 中利用 mkNumericOps?

How to take advantage of mkNumericOps in Scala?

我正在尝试定义一种新类型,它的行为本质上可以像数字一样(为了具体起见,假设是 Double)。我想在此类型上重载运算符,我可以明确地这样做,但为了避免重复,我想利用 NumericOps, which are defined in terms of the abstract methods in Numeric 中的方法。我的理解是我应该能够覆盖 Numeric 中的方法并免费获得其他方法。

这是我能想到的最简单的尝试:

class Container(val value: Double) extends Numeric[Container] {
  override def plus(x: Container, y: Container): Container =
    new Container(x.value + y.value)

  // override minus, times, etc.

  override def toString: String = value.toString
}

println(new Container(1) + new Container(1))

但是,这给了我一个类型不匹配错误。

我对隐式的理解仍然很不稳定,但我本以为 Container 继承的 implicit def mkNumericOps(lhs: Container): NumericOps 可以通过隐式转换添加到的两个 Container 对象来挽救局面NumericOps 个对象,然后使用根据 Container.plus.

定义的 + 方法添加它们

我在这里弄错了什么,我该如何解决?

您需要从 Container 的实例导入 mkNumericOps:

val container = new Container(1)
import container.mkNumericOps
println(container + container) 

您可以通过 mkNumericOps 定义自己的 + 方法来省略导入,如下所示:

def +(y: Container): Container = mkNumericOps(this) + y

这里有一个例子来补充 Luis 的类型类注释

final case class Container(value: Double)

object Container {
  implicit val containerNumeric: Numeric[Container] = new Numeric[Container] {
    override def plus(x: Container, y: Container) = Container(x.value + y.value)
    override def minus...
  }
}

import Numeric.Implicits._
Container(1) + Container(1)

输出

res0: Container = Container(2.0)

导入提供infixNumericOps,编译器使用它自动重写为

infixNumericOps(Container(1)) + Container(1)