键入以对double施加所需的约束

时间:2015-06-15 12:50:00

标签: scala implicit-conversion

我希望有一个run time check on a Double,而不必在我的代码中分散检查。 我认为定义一个implicit class would do the job,就行了:

  implicit class Probability(val x: Double) {
    require(x >= 0.0 && x <= 1.0, "Probs are defined btw 0.0 and 1.0")
  }

缺失的部分是告诉Scala在构建之后的任何时候将概率视为DoubleFor this I suppose it is necessary to require a double side conversion

object Foo {

  implicit class Probability(val x: Double) {
    require(x >= 0.0 && x <= 1.0, "Probs are defined btw 0.0 and 1.0")
  }

  implicit def asDouble(e: Probability): Double = e.x

  implicit def asProb(d: Double): Probability = new Probability(d)

  def max_(s: Seq[Double]): Double = {
    s.max
  }

  def max(s: Seq[Probability]): Double = {
    s.max
  }
}

val r1 = Foo.max_(List(2.0, 3.0, 5.0))
val r2 = Foo.max(List[Probability]=(2.0, 3.0, 5.0))

修改

这可能已经成功了。 不确定引擎盖下会发生什么。

trait RangeBound
type Probability = Double with RangeBound
implicit def makeProb(p: Double): Probability = {
  assert (p >= 0.0 && p <= 1.0)
  p.asInstanceOf[Probability]
}

val p = List[Probability](0.1, 0.3, 0.2)
val r = p filter (_ > 0.1)

因为这不起作用:

trait RangeBound
type Probability = Double with RangeBound
implicit def makeProb(p: Double): Probability = {
  assert (p >= 0.0 && p <= 1.0)
  p.asInstanceOf[Probability]
}

val p = List[Probability](0.1, 0.3, 0.2)
val r2 = p.max

错误:

Error:(10, 18) No implicit Ordering defined for Double with A$A288.this.RangeBound.
lazy val r2 = p.max;}
                ^

2 个答案:

答案 0 :(得分:0)

我不明白你想要什么。

但是,万一,这里有一点建议。

  class Probability(val x: Double) extends AnyVal {
    override def toString = s"${x * 100} %"
    def PerCent = x * 100
  }

  object Probability {
    def apply(x: Double) = {
      if (x <= 1.0 && x >= 0.0)
        Some(new Probability(x))
      else
        None
    }
  }

  implicit def asProb(d: Double): Probability = Probability(d).get

只有在使用方法或值时才应调用隐式转换,例如我的示例中的PerCent:

scala> 0.3
res0: Double = 0.3

scala> 0.3.PerCent
res1: Double = 30.0

scala> 1.5
res2: Double = 1.5

scala> 1.5.PerCent
java.util.NoSuchElementException: None.get
  at scala.None$.get(Option.scala:347)
  at scala.None$.get(Option.scala:345)
  at .asProb(<console>:21)
  ... 43 elided

答案 1 :(得分:0)

这启用了基本的运行时检查:

trait RangeBound
type Probability = Double with RangeBound

  implicit def makeProb(p: Double): Probability = {
    assert (p >= 0.0 && p <= 1.0)
    p.asInstanceOf[Probability]
  }

  implicit val probabilityOrdering = Ordering.Double.asInstanceOf[Ordering[Probability]]