scala合成糖可以形成一致吗?

时间:2018-01-17 04:52:13

标签: scala syntax equivalence

考虑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)的同义定义,而Aa是传递给b但实际上不是类型的一些元素A。例如。 A可能是一组矩阵,如果单个矩阵Aa因标量b而不同,则一致。特别是,a*b^-1=sI_na将生活在许多群体中,并且一致性将基于此而改变。因此,我无法简单地将ba中的引用添加回b

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

2 个答案:

答案 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