我有以下函数在2个边界之间生成Uniform分布值:
def Uniform(x: Bounded[Double], n: Int): Bounded[Double] = {
val y: Double = (x.upper - x.lower) * scala.util.Random.nextDouble() + x.lower
Bounded(y, x.bounds)
}
和Bounded的定义如下:
trait Bounded[T] {
val underlying: T
val bounds: (T, T)
def lower: T = bounds._1
def upper: T = bounds._2
override def toString = underlying.toString + " <- [" + lower.toString + "," + upper.toString + "]"
}
object Bounded {
def apply[T : Numeric](x: T, _bounds: (T, T)): Bounded[T] = new Bounded[T] {
override val underlying: T = x
override val bounds: (T, T) = _bounds
}
}
但是,我希望Uniform
处理所有Fractional[T]
值,因此我想添加一个上下文绑定:
def Uniform[T : Fractional](x: Bounded[T], n: Int): Bounded[T] = {
import Numeric.Implicits._
val y: T = (x.upper - x.lower) * scala.util.Random.nextDouble().asInstanceOf[T] + x.lower
Bounded(y, x.bounds)
}
这在执行Uniform[Double](x: Bounded[Double])
时会起作用,但其他的是不可能的,并且在运行时获得ClassCastException,因为它们无法进行转换。有办法解决这个问题吗?
答案 0 :(得分:3)
我建议定义一个新类型类,它可以表示可以获得随机实例的类型:
otherclient(myclient, desipaddr, desport)
现在你可以像这样写import scala.util.Random
trait GetRandom[A] {
def next(): A
}
object GetRandom {
def instance[A](a: => A): GetRandom[A] = new GetRandom[A] {
def next(): A = a
}
implicit val doubleRandom: GetRandom[Double] = instance(Random.nextDouble())
implicit val floatRandom: GetRandom[Float] = instance(Random.nextFloat())
// Define any other instances here
}
:
Uniform
并像这样使用它:
def Uniform[T: Fractional: GetRandom](x: Bounded[T], n: Int): Bounded[T] = {
import Numeric.Implicits._
val y: T = (x.upper - x.lower) * implicitly[GetRandom[T]].next() + x.lower
Bounded(y, x.bounds)
}
像rng这样的库可以为你提供类似的类型,但是它们往往专注于使用随机数字的纯函数方式,所以如果你想要更简单的东西你可能是最好的写你自己的。