我正在使用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)
}
注意,我故意没有在复杂情况类中包括添加功能。利用上述内容,我可以完成以下所有操作:
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)
我想使用“+”代替“add”,但是这并不起作用。我遇到了以下错误:
Error:(14, 4) value + is not a member of A$A288.this.Complex
z + 1
^
无论是z + w
还是1 + z
,都可以正常工作。
我想知道为什么将函数名称从“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的case类。只有当涉及到复数和试图结合双精度浮点数、整数等时,我才遇到上述问题。