1

Is there a good Scala-idiomatic way to parameterize math-related classes (like vectors or matrices) to use either Doubles or BigDecimals? The following code seems to work, but it's kind of ugly, only implements addition, and the complexity and ugliness will scale exponentially if I add support for Floats, BigInts, etc.

abstract class Decimal[T] {
    val contents:T

    def +[S](other:Decimal[S]) = (this.contents, other.contents) match {
      case (a:Double,     b:Double)     => BoxedDouble(a+b)
      case (a:BigDecimal, b:Double)     => BoxedBigDecimal(a+b)
      case (a:Double,     b:BigDecimal) => BoxedBigDecimal(a+b)
      case (a:BigDecimal, b:BigDecimal) => BoxedBigDecimal(a+b)
    }
  }
case class BoxedDouble(contents:Double) extends Decimal[Double]
case class BoxedBigDecimal(contents:BigDecimal) extends Decimal[BigDecimal]

val x = BoxedDouble(3.3)
val y = BoxedBigDecimal(4.4)
println(x+y)  //outputs BoxedBigDecimal(7.7)

These classes don't share an interface but it seems like there should be a way to abstract the math you're doing out from the precision you're doing it with. I don't just want to use a BigDecimal for everything because most of the time, I'd rather have the speed and memory efficiencies of using primitive types. However, I'd like to be able to increase the precision sometimes without having to have two copies of my code (one for Double and one for BigDecimal).

John Stanford
  • 993
  • 1
  • 7
  • 18
  • It's not clear why the type class `Numeric` doesn't do what you want. You might study [this question](https://stackoverflow.com/questions/39277033/type-parameters-and-numeric-widening), and its answer, for more details on a possible implementation. – jwvh Feb 20 '18 at 21:10
  • You might want to take a look at [Spire](https://github.com/non/spire). – Andrey Tyukin Feb 20 '18 at 21:32

0 Answers0