考虑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)
或{感兴趣{1}}或者a ==(A) b
。在条款a和b之间出现同余的东西。
我的斗争的底线是类型A(a == b)
的同义定义,而A
,a
是传递给b
但实际上不是类型的一些元素A
。例如。 A
可能是一组矩阵,如果单个矩阵A
和a
因标量b
而不同,则一致。特别是,a*b^-1=sI_n
,a
将生活在许多群体中,并且一致性将基于此而改变。因此,我无法简单地将b
和a
中的引用添加回b
。
正确的解决方案似乎是数学解决方案,用A
标记等价而不是变量A
和a
。然而,scala语法糖可能没有这么甜的心。任何建议表示赞赏。
答案 0 :(得分:1)
试试这个:
implicit class ModEquals(a: Int) {
def %%(n: Int) = new { def ===(b: Int) = (a - b) % n == 0 }
}
用法:
7 %% 3 === 10
此解决方案使用Int
方法丰富%%
s,该方法采用一致性。在这个例子中,它只是modulu,但这很容易扩展到任何东西。返回的对象是一个定义了===
方法的类,用于实现相等性检查。
答案 1 :(得分:0)
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