比较Scala中的一对自定义Double类

时间:2018-10-02 01:54:56

标签: 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 进行比较,无论它们位于==符号的左侧还是右侧< / em>。我想念什么?

2 个答案:

答案 0 :(得分:1)

==不是类型正确的运算符。参见http://dotty.epfl.ch/docs/reference/multiversal-equality.html。因此,自动转换为double的可能性很小。相反,您可以尝试基于多重相等的思想来实现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) ...

答案 1 :(得分:1)

您可能会摆脱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
    }
}