我想通过添加一些辅助方法在 Scala 中为自然数创建一个“pimp my type”。
我的第一次尝试是创建一个 forInt
和一个 for Long
(后来BigInt
可能也是)
implicit class SuperInt(n:Int) {
def square = n * n
def pow(m: Int) = math.pow(n,m)
def **(m: Int) = pow(m)
def sqrt = math.sqrt(n)
def isEven = dividesBy(2)
def isOdd = !isEven
def dividesBy(m:Int) = n % m == 0
}
implicit class SuperLong(n:Long) {
def square = n * n
def pow(m: Int) = math.pow(n,m)
def **(m: Int) = pow(m)
def sqrt = math.sqrt(n)
def isEven = dividesBy(2)
def isOdd = !isEven
def dividesBy(m:Int) = n % m == 0
}
当然,完全相同的代码,不会太干,也不会“感觉”正确。
所以我的问题是 - 一次为 Long、Int 和 BigInt 执行此操作的(惯用的)Scala 方式是什么?
ps 这是我到目前为止所尝试的,它有点工作,但我很确定它不是惯用的并且有很多问题。
以下是在这里阅读一些关于“类型类”的结果(我仍然不完全觉得我 100% 理解)所以这就是结果(如果你的眼睛受伤了,请原谅我,我比较陌生斯卡拉)
implicit class SuperNumber[A : Numeric](i: A) {
import Numeric.Implicits._
def squared: A = i * i
def pow(m: Int) = math.pow(i.toDouble(),m)
def **(m: Int) = pow(m)
def sqrt = math.sqrt(i.toDouble())
def isEven = dividesBy(2)
def isOdd = !isEven
def dividesBy(m:Int) = {
i match {
case n @ (_:Int | _:Long) => n.toLong() % m == 0
case other => {
val asDouble = other.toDouble()
val asLong = other.toLong()
if (asDouble == asLong) {
asLong % m == 0
} else {
false
}
}
}
}
}
(我为非 Int 和 Long 添加了“支持”,因为它看起来不太难)