Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala中浮点、双精度和大十进制的抽象_Scala - Fatal编程技术网

Scala中浮点、双精度和大十进制的抽象

Scala中浮点、双精度和大十进制的抽象,scala,Scala,我曾怀疑Scala的类型系统中已经内置了对这一点的支持,但在涉过数字、分数和分数Proxy之后,我无法找到一种方法 我想抽象地定义一个数值模型,这样它可以处理Double、Float和bigdecimal,并对Float和Double进行专门化 我似乎成功了,但付出了很大的努力和样板。首先,有没有(请?)一种不那么麻烦、更简洁的方式?第二,尽管视图边界进行了隐式转换,我对值类型的使用是否能有效地防止专门化为基本类型的代码被包装 非常感谢 object Model { sealed trai

我曾怀疑Scala的类型系统中已经内置了对这一点的支持,但在涉过数字、分数和分数Proxy之后,我无法找到一种方法

我想抽象地定义一个数值模型,这样它可以处理Double、Float和bigdecimal,并对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
   }
}
对象模型{
密封特征值[T]扩展任何{//,包含我使用的所有操作
def值:T;
def+(其他:值[T]):值[T];
def/(其他:值[T]):值[T];
def-(其他:值[T]):值[T];
def*(其他:值[T]):值[T];
def<(其他:值[T]):布尔值;
定义一元数:值[T];
def abs:值[T];
}
隐式def unwrap[T](wrapped:Value[T]):T=wrapped.Value;
隐式类FloatValue(val值:Float)使用值[Float]扩展AnyVal{
def+(其他:值[Float]):值[Float]=新的FloatValue(值+其他.Value)
def/(其他:值[Float]):值[Float]=新的FloatValue(值/other.Value)
def-(其他:值[Float]):值[Float]=新的FloatValue(值-其他.Value)
def*(其他:值[Float]):值[Float]=新的FloatValue(值*other.Value)
def<(其他:值[Float]):布尔=值<其他.Value;
定义一元值:值[Float]=新的FloatValue(-Value);
def abs:Value[Float]=新的FloatValue(math.abs(Value));
}
隐式类DoubleValue(val值:Double)使用值[Double]扩展AnyVal{
//FloatValue的主体重复,但用Double替换Float
}
隐式类BigDecimalValue(val值:BigDecimal)使用值[BigDecimal]扩展AnyVal{
//FloatValue的主体重复,但用BigDecimal替换Float
}
}

类GrossInterestModel[@specialized(Double,Float)TScala内置集合已在中实现了类似的功能。您可以直接使用它们。类似的功能(来自TraversableOnce.Scala):


你可能想看看它是否适合你的用例。哇,谢谢。spire看起来有点不可思议。@huynhjl也许你应该复制你的评论作为答案。我很乐意投票——spire看起来很有趣。是的,我浏览了这些抽象,但奇怪的是,像/这样的普通操作并没有在它们上定义。
def sum[B >: A](implicit num: Numeric[B]): B = foldLeft(num.zero)(num.plus)