比较 Scala 中的自定义双精度类对



我将DoubleIn01类定义为:

implicit class DoubleIn01(val value: Double) extends Ordered[DoubleIn01] {
require(inBounds(0.0, value, 1.0), s"value $value should be in [0,1]")
override def toString: String = value.toString
override def hashCode(): Int = value.hashCode()
override def compare(that: DoubleIn01): Int = value.compare(that.value)
override def equals(obj: Any): Boolean =
obj match {
case o: Double => value.equals(o.asInstanceOf[Double])
case o: DoubleIn01 => value.equals(o.asInstanceOf[DoubleIn01].value)
case _ => false
}
def ==(that: Double): Boolean = value == that
}

以及:

implicit def DoublePairToDoubleIn01Pair(p: (Double, Double)): (DoubleIn01, DoubleIn01) =
(DoubleIn01(p._1), DoubleIn01(p._2))

但这似乎不足以将DoubleIn01Double进行比较,无论哪个位于==标志的左侧或右侧。我错过了什么?

>==不是类型声音运算符。请参阅 http://dotty.epfl.ch/docs/reference/multiversal-equality.html。因此,自动投射双精度可能不是很可能。您可以尝试实现typedEquals[T]方法,或者基于多元相等思想的运算符===[T]

trait Equals[-L, -R] {
def equals(l: L, r: R): Boolean
}
implicit def equalsRev[R,L](implicit eq: Equals[L, R]): Equals[R, L] = new Equals{
def equals(l: R, r: L): Boolean = eq.equals(r,l)
}
implicit class EqualityOps[L](l: L){
def ===[R](r: R)(implicitly eq: Equals[L, R]) = 
eq.equals(l, r)
}
implicit object DoubleIn01DoubleEq extends Equals[DoubleIn01, Double] {
def equals(l: DoubleIn01, r: Double): Boolean = (l % 1.0) == r
}
...
val d: DoubleIn01 = 0.2
if(d === 0.5) ...

你可以摆脱require说所有双精度都根据它们的分数部分划分为等价类:

class DoubleIn01(val value0: Double) extends AnyVal with Ordered[DoubleIn01] {
def value: Double = value0 % 1.0
override def toString: String = value.toString
override def hashCode(): Int = value.hashCode()
override def compare(that: DoubleIn01): Int = value.compare(that.value)
override def equals(obj: Any): Boolean =
obj match {
case o: Double if o >= 0 && o < 1.0 => value.equals(o)
case _ => false
}
}

最新更新