Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Numeric type to Double without parameter

Tags:

scala

I am trying to implement a generic method to compute the mean of any kind of sequence (for example: List, Array) which contains any kind of numeric values (Int, Float, Double...), like this:


 def mean[T <: Numeric[T]](data:Seq[T])(implicit number: Numeric[T]): T = {
      data.foldLeft(number.zero)(number.plus) / data.size
  }

However, the division operation cannot be resolved. That is because the Numeric type does not have this operation defined (from the ScalaDoc). I want to convert it to double before proceeding with the division, but the method toDouble(x:T) from Numeric type expects a param. I have seen there is a type member for the Numeric[T] called NumericOps that does implement the toDouble method without receiving any param. Could I call this method.. somehow?

like image 915
Cristina HG Avatar asked Nov 22 '25 03:11

Cristina HG


1 Answers

Here is an example using Fractional, it will preserve the correct precision of the input numbers, and does only one traversal of the data. However, do note that this only works for types that have a "precise" division, like Float, Double & BigDecimal. But does not work for numeric types like Int or Long.

def mean[T](data: Iterable[T])(implicit N: Fractional[T]): T = {
  import N._

  val remaining = data.iterator

  @annotation.tailrec
  def loop(sum: T, count: Int): T =
    if (remaining.hasNext)
      loop(sum + remaining.next(), count + 1)
    else if (count == 0)
      zero
    else
      sum / fromInt(count)

  loop(zero, 0)
}

This was tested on Scala 2.13.

like image 105
Luis Miguel Mejía Suárez Avatar answered Nov 24 '25 21:11

Luis Miguel Mejía Suárez



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!