【发布时间】:2016-07-25 23:11:59
【问题描述】:
我正在使用 Scala 中的一个简单的复数案例类,并希望创建一个在复数、双精度数和整数之间工作的加法函数。下面是一个有效解决方案的简单示例:
case class Complex(re: Double, im: Double)
implicit def toComplex[A](n: A)(implicit f: A => Double): Complex = Complex(n, 0)
implicit class NumberWithAdd[A](n: A)(implicit f: A => Complex) {
def add(m: Complex) = Complex(n.re + m.re, n.im + m.im)
}
注意,我故意不在复杂案例类中包含 add 函数。使用上面我可以做到所有这些:
scala> val z = Complex(1, 2); val w = Complex(2, 3)
z: Complex = Complex(1.0,2.0)
w: Complex = Complex(2.0,3.0)
scala> z add w
res5: Complex = Complex(3.0,5.0)
scala> z add 1
res6: Complex = Complex(2.0,2.0)
scala> 1 add z
res7: Complex = Complex(2.0,2.0)
我想使用“+”而不是“添加”,但这不起作用。我收到以下错误:
Error:(14, 4) value + is not a member of A$A288.this.Complex
z + 1
^
z + w 和 1 + z 仍然有效。
我想知道的是为什么将函数名从“add”更改为“+”会破坏这个?是否有获得此功能的替代途径(而不是将 add 函数简单地放在复杂案例类中)?任何帮助将不胜感激。
编辑 - 动机
我在玩幺半群和其他代数结构。我希望能够概括“...WithAdd”函数以自动适用于具有相应幺半群的任何类:
trait Monoid[A] {
val identity: A
def op(x: A, y: A): A
}
implicit class withOp[A](n: A)(implicit val monoid: Monoid[A]) {
def +(m: A): A = monoid.op(n, m)
}
case class Complex(re: Double, im: Double) {
override def toString: String = re + " + " + im + "i"
}
class ComplexMonoid extends Monoid[Complex] {
val identity = Complex(0, 0)
def op(z: Complex, w: Complex): Complex = {
Complex(z.re + w.re, z.im + w.im)
}
}
implicit val complexMonoid = new ComplexMonoid
使用上面的我现在可以做Complex(1, 2) + Complex(3, 1)给Complex = 4.0 + 3.0i。这对于代码重用非常有用,因为我现在可以向 Monoid 和 withAdd 函数添加额外的函数(例如将 op n 次应用于元素,为乘法提供幂函数),并且它适用于任何具有相应 monoid 的案例类.只有使用复数并尝试合并双精度数、整数等,我才会遇到上述问题。
【问题讨论】:
-
无法通过隐式转换添加已存在的方法stackoverflow.com/a/4444122/1594980
-
您链接到的问题是试图隐式覆盖具有相同签名的函数。类型 Int、Double 或我的 Complex 类都没有一个方法 + 带有一个 Complex 类型的参数。