You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:24:31