gpt4 book ai didi

Scala 隐式转换函数名称冲突

转载 作者:行者123 更新时间:2023-12-01 19:42:21 26 4
gpt4 key购买 nike

我正在 Scala 中使用一个简单的复数案例类,并想创建一个在复数、 double 数和整数之间工作的加法函数。下面是一个工作解决方案的简单示例:

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 + w1 + 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 的 case 类.只有使用复数并尝试合并 double 数、整数等,我才会遇到上述问题。

最佳答案

我会使用普通的 class ,不是 case class .然后很容易创建方法来添加或减去这些复数,例如:

class Complex(val real : Double, val imag : Double) {

def +(that: Complex) =
new Complex(this.real + that.real, this.imag + that.imag)

def -(that: Complex) =
new Complex(this.real - that.real, this.imag - that.imag)

override def toString = real + " + " + imag + "i"

}

the source page显示,它现在将支持看起来像运算符重载的东西(它不是,因为 +- 是函数而不是运算符)。
implicit class NumberWithAdd 的问题及其方法 +是同样的方法也存在于 Int等数字类中。和 Double . + NumberWithAdd的方法基本上允许您从可以转换为 Complex 的数字开始并添加一个 Complex反对第一项。也就是说,左手值可以是任何东西(只要可以转换),右手值必须是 Complex .

这对 w + z 很有用(无需转换 w )和 1 + z (从 IntComplex 的隐式转换是可用的)。 z + 1 失败因为 +在类 Complex 中不可用.
z + 1实际上是 z.+(1) , Scala 将为 +(i: Int) 寻找其他可能的匹配项在 Complex 的类(class)中可以转换成。它还检查 NumberWithAdd ,它确实有一个 +功能,但需要一个 Complex作为右手值。 (它将匹配需要 Int 作为右手值的函数。)还有其他名为 + 的函数。接受 Int ,但没有来自 Complex 的转换这些函数想要什么作为左手值。
+的相同定义当它在(案例)类中时确实有效 Complex .在这种情况下, w + zz + 1只需使用该定义。案例 1 + z现在有点复杂。自 Int没有功能 +接受 Complex值,Scala 会找到那个(在 Complex 中)并确定是否可以转换 Int进入 Complex .这可以使用隐式函数,转换发生并执行函数。

当函数 +在类(class) NumberWithAdd更名 add , 与 Int 中的函数没有混淆因为 Int没有功能 + .所以Scala会更加努力地应用函数 add它会做 IntComplex转换。当您尝试 1 add 2 时,它甚至会进行这种转换。 .

注意:我的解释可能无法完全描述实际的内部工作原理。

关于Scala 隐式转换函数名称冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36436061/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com