scala 语法糖可以同余 mod n 吗?

Can scala syntatic sugar make a congruence mod n?

考虑 2+7 == 3+6 (mod 5)。你能知道如何使用 scala 语法糖在 scala 代码中实现相同的目的吗?

请记住,2+7 和 3+6 是常规的 scala Int,因此将 + 或 == 覆盖为 mod 5 是行不通的。我实际上对代数 A 上更复杂的同余感兴趣。我可以做 A.congruent(a,b),并用一些像 A.~(a,b) 这样的漂亮符号来写它,但我对 a == b (A) 或 [=14] 感兴趣=] 或者 A(a == b)。在术语 a 和 b 之间出现一致的东西。

我挣扎的底线是,同余是为类型 A 定义的,而 ab 是传递给 A 但实际上不是的一些元素类型 A。例如。 A 可能是一组矩阵,如果单个矩阵 ab 相差一个标量,即 a*b^-1=sI_n,则同余。特别是,ab 将存在于许多组中,并且一致性将基于此发生变化。所以我不可能简单地在 ab 中添加引用回到 A

一些正确的解决方案似乎是数学解决方案,用 A 标记等价性而不是变量 ab。然而,scala 语法糖可能没有这样的甜头。任何建议表示赞赏。

试试这个:

implicit class ModEquals(a: Int) {
    def %%(n: Int) = new { def ===(b: Int) = (a - b) % n == 0 }
}

用法:

7 %% 3 === 10

此解决方案通过采用全等的 %% 方法丰富了 Ints。在这个例子中,它只是模数,但这可以很容易地扩展到任何东西。返回的对象是一个 class,它定义了一个 === 方法来实现相等性检查。

import scala.languageFeature.implicitConversions
import scala.languageFeature.reflectiveCalls

case class ModuloArg(list: List[Int]) {
  assert(list.size > 1)

  def ==%%?(m: Int) = {
    val hm = list.head % m
    list.tail.filter(i => (i % m) != hm).isEmpty
  }

  def ::%%(n: Int) = ModuloArg(n :: list)

}

implicit class ModuloArgOps(i: Int) {
  def ::%%(n: Int) = ModuloArg(n :: i :: Nil)
}

现在,您可以使用这些来检查模相等性,

// 4 == 10 (mod 3) 
scala> val mod3Equal4And10 = 4 ::%% 10 ==%%? 3
// mod3Equal4And10: Boolean = true

// 4 == 11 (mod 3) 
scala> val mod3Equal4And11 = 4 ::%% 11 ==%%? 3
//mod3Equal4And11: Boolean = false

// 4 == 10 == 13 == 16 (mod 3)
scala> val mod3Equal4And10And13And16 = 4 ::%% 10 ::%% 13 ::%% 16 ==%%? 3
// mod3Equal4And10And13And16: Boolean = true