7

我曾怀疑 Scala 的类型系统中已经内置了对此的支持,但是在涉足 Numeric 和 Fractional 和 FractionalProxy 之后,我无法找到方法。

我想抽象地定义一个数值模型,以便它可以与 Doubles、Floats 和 BigDecimals 一起使用,并专门针对 Float 和 Double。

我似乎已经成功了,但是付出了很多努力和样板。首先,有没有(请?)一种不那么笨拙、更简洁的方式?其次,尽管视图边界的隐式转换,我对值类型的使用是否能有效地防止专用类型到原始类型被包装?

非常感谢。

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
   }
}
4

1 回答 1

2

Scala 内置集合已经在Numeric.scala中实现了类似的东西。您可以直接使用它们。类似的东西(来自 TraversableOnce.scala):

def sum[B >: A](implicit num: Numeric[B]): B = foldLeft(num.zero)(num.plus)
于 2013-05-24T07:17:30.783 回答