我正在尝试在 Scala 3 中创建一个
Fractional[Int]
实例,我想将其用于有限域算术。
我有一个类,其实例可以作为
Fractional[Int]
实现:
class IntModp(val p : Int) extends Fractional[Int] {
def inverse(a : Int) : Int = {
// implementation of modular inverse with fast Euclidean algorithm here
}
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
return r match {
case rr : Int if (rr < -(p-1)/2) => rr + p
case rr : Int if (rr > (p-1)/2) => rr-p
case rr : Int => 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] =
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 = IntIsIntegral.toDouble(norm(x))
def toFloat(x: Int): Float = IntIsIntegral.toFloat(norm(x))
def toInt(x: Int): Int = IntIsIntegral.toInt(norm(x))
def toLong(x: Int): Long = IntIsIntegral.toLong(norm(x))
}
根据我对 Scala 3 类型类和
scala.math.Fractional.Implicits
的理解,我现在应该能够执行以下操作:
given IntMod17 : Fractional[Int] = new IntModp(17)
15 + 12 // expect to see -7, instead see 27
15 / 12 // expect to see -3, instead see 1
但是相反,每当我实际使用任何算术运算符时,我都会得到“正常”
Int
行为。我当然可以做类似的事情
given IntMod17 : Fractional[Int] = new IntModp(17)
val fr = summon[Fractional[Int]] // fr is now this IntMod17 object
fr.plus(15, 12) // expect to see -7, and see -7
fr.div(15, 12) // expect to see -3, and see -3