Scala3中Fractional[Int]实现后无法调用算术运算符问题
问题分析与解决方法
核心原因
Scala 中Int类型本身自带+、/等原生运算符,这些原生方法的优先级远高于类型类提供的扩展方法。直接写15 + 12时,会优先调用Int的原生加法逻辑,而非你定义的Fractional[Int]实例中的plus方法。
解决步骤
要让类型类的运算符生效,需要导入Fractional.Implicits中的扩展方法——它会为Int添加基于Fractional[Int]实例的运算符重载,覆盖原生运算符的行为。
修改后的完整代码示例
import scala.math.Fractional.Implicits.infixFractionalOps class IntModp(val p : Int) extends Fractional[Int] { def inverse(a : Int) : Int = { // 快速欧几里得算法实现模逆(假设p为质数) def extendedGcd(a: Int, b: Int): (Int, Int, Int) = if (b == 0) (a, 1, 0) else { val (g, x, y) = extendedGcd(b, a % b) (g, y, x - (a / b) * y) } val (g, x, _) = extendedGcd(a % p, p) if (g != 1) throw new IllegalArgumentException(s"No inverse for $a mod $p") else norm(x) } val inverses : Map[Int, Int] = Map.from( Range(1, p-1).map(j => (j -> inverse(j))) ++ Range(-(p-1), -1).map(j => (j -> -inverse(-j))) ) def norm(a: Int): Int = { val r : Int = a % p r match { case rr if rr < -(p-1)/2 => rr + p case rr if rr > (p-1)/2 => rr - p case rr => rr } } def compare(x: Int, y: Int): Int = Ordering.Int.compare(norm(x), norm(y)) def div(x: Int, y: Int): Int = times(x, inverses(norm(y))) def fromInt(x: Int): Int = norm(x) def minus(x: Int, y: Int): Int = norm(x - y) def negate(x: Int): Int = norm(-x) def parseString(str: String): Option[Int] = scala.math.Numeric.IntIsIntegral.parseString(str).map(j => norm(j)) def plus(x: Int, y: Int): Int = norm(x + y) def times(x: Int, y: Int): Int = norm(x * y) def toDouble(x: Int): Double = scala.math.Numeric.IntIsIntegral.toDouble(norm(x)) def toFloat(x: Int): Float = scala.math.Numeric.IntIsIntegral.toFloat(norm(x)) def toInt(x: Int): Int = scala.math.Numeric.IntIsIntegral.toInt(norm(x)) def toLong(x: Int): Long = scala.math.Numeric.IntIsIntegral.toLong(norm(x)) } // 使用部分 given IntMod17 : Fractional[Int] = new IntModp(17) // 现在直接调用运算符即可得到有限域运算结果 15 + 12 // 结果为-7,符合预期 15 / 12 // 结果为-3,符合预期
补充说明
infixFractionalOps是一个隐式类,它会为任意实现了Fractional类型类的类型(这里是Int)添加+、-、*、/等运算符,这些运算符会自动调用当前上下文里的Fractional[Int]实例对应的方法。- 如果不想全局导入该隐式类,可以将导入语句放在局部作用域中,避免影响其他代码里
Int原生运算符的正常使用。
内容的提问来源于stack exchange,提问作者Mikael Vejdemo-Johansson
相关产品推荐
相关产品推荐

