我希望有一个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在构建之后的任何时候将概率视为Double
。 For 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;}
^
答案 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]]