我曾怀疑Scala的类型系统已经内置了这种支持,但在浏览了Numeric和Fractional以及FractionalProxy后,我无法找到方法。
我想抽象地定义一个数值模型,这样它就可以使用Doubles,Floats和BigDecimals,具有Float和Double的特化。
我似乎已经使它工作,但需要付出很多努力和样板。首先,是否(请?)一个较少的kludgey,更简洁的方式?其次,尽管视图边界的隐式转换,我对值类型的使用是否有效保持专用原始类型不被包装?
非常感谢。
object Model {
sealed trait Value[T] extends Any { //contains all the operations I use
def value : T;
def + ( other : Value[T]) : Value[T];
def / ( other : Value[T]) : Value[T];
def - ( other : Value[T]) : Value[T];
def * ( other : Value[T]) : Value[T];
def < ( other : Value[T]) : Boolean;
def unary_- : Value[T];
def abs : Value[T];
}
implicit def unwrap[T]( wrapped : Value[T]) : T = wrapped.value;
implicit class FloatValue( val value : Float ) extends AnyVal with Value[Float] {
def + ( other : Value[Float]) : Value[Float] = new FloatValue(value + other.value)
def / ( other : Value[Float]) : Value[Float] = new FloatValue(value / other.value)
def - ( other : Value[Float]) : Value[Float] = new FloatValue(value - other.value)
def * ( other : Value[Float]) : Value[Float] = new FloatValue(value * other.value)
def < ( other : Value[Float]) : Boolean = value < other.value;
def unary_- : Value[Float] = new FloatValue( -value );
def abs : Value[Float] = new FloatValue( math.abs( value ) );
}
implicit class DoubleValue( val value : Double ) extends AnyVal with Value[Double] {
// body of FloatValue repeated, but with Double replacing Float
}
implicit class BigDecimalValue( val value : BigDecimal ) extends AnyVal with Value[BigDecimal] {
// body of FloatValue repeated, but with BigDecimal replacing Float
}
}
class GrossInterestModel[@specialized(Double,Float) T <% Value[T]]( zero : T ) {
def runModel( a : T, b : T ) : T = {
//do math here, using the operations defined in Value above
}
}
答案 0 :(得分:2)
Scala内置集合已经在Numeric.scala中实现了类似的功能。您可以直接使用它们。有点像(来自TraversableOnce.scala):
def sum[B >: A](implicit num: Numeric[B]): B = foldLeft(num.zero)(num.plus)