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
定义的,而 a
、b
是传递给 A
但实际上不是的一些元素类型 A
。例如。 A
可能是一组矩阵,如果单个矩阵 a
和 b
相差一个标量,即 a*b^-1=sI_n
,则同余。特别是,a
、b
将存在于许多组中,并且一致性将基于此发生变化。所以我不可能简单地在 a
和 b
中添加引用回到 A
。
一些正确的解决方案似乎是数学解决方案,用 A
标记等价性而不是变量 a
和 b
。然而,scala 语法糖可能没有这样的甜头。任何建议表示赞赏。
试试这个:
implicit class ModEquals(a: Int) {
def %%(n: Int) = new { def ===(b: Int) = (a - b) % n == 0 }
}
用法:
7 %% 3 === 10
此解决方案通过采用全等的 %%
方法丰富了 Int
s。在这个例子中,它只是模数,但这可以很容易地扩展到任何东西。返回的对象是一个 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
考虑 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
定义的,而 a
、b
是传递给 A
但实际上不是的一些元素类型 A
。例如。 A
可能是一组矩阵,如果单个矩阵 a
和 b
相差一个标量,即 a*b^-1=sI_n
,则同余。特别是,a
、b
将存在于许多组中,并且一致性将基于此发生变化。所以我不可能简单地在 a
和 b
中添加引用回到 A
。
一些正确的解决方案似乎是数学解决方案,用 A
标记等价性而不是变量 a
和 b
。然而,scala 语法糖可能没有这样的甜头。任何建议表示赞赏。
试试这个:
implicit class ModEquals(a: Int) {
def %%(n: Int) = new { def ===(b: Int) = (a - b) % n == 0 }
}
用法:
7 %% 3 === 10
此解决方案通过采用全等的 %%
方法丰富了 Int
s。在这个例子中,它只是模数,但这可以很容易地扩展到任何东西。返回的对象是一个 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