Writing a scala function that can be either Int or Double

I wrote a function to accept the following types of values: (1, Array (1.0, 2.0.0.0)) This is a tuple with the first Int value and the next array of paired numbers.

I would also like it to accept an array of integers. The function I wrote is as follows:

def getCountsAndAverages[T](Parameter: Tuple2[Int, Array[T]])(implicit n:Numeric[T]) = { (Parameter._1, (Parameter._2.size, Parameter._2.map(n.toDouble).sum/Parameter._2.size)) } 

The first parameter of the tuple is the number, and then its array from the number of times it appears in the file.

It works great for examples, but I am reading a text file that has data in the same format that is needed for this function to work. I call this function using the "map" operation:

 parsedfile.map(getCountsAndAverages) 

I get the following errors:

 ◾could not find implicit value for parameter n: Numeric[T] ◾not enough arguments for method getCountsAndAverages: (implicit n: Numeric[T])(Int, (Int, Double)). Unspecified value parameter n. 

I would be grateful for any help or suggestions.

+3
scala
source share
2 answers

You can use any of the following syntaxes

 def foo[T](x: T)(implicit n: Numeric[T]) = n.toDouble(x) 

or

 def foo[T : Numeric](x: T) = implicitly[Numeric[T]].toDouble(x) 

In your case

 def getCountsAndAverages[T: Numeric](Parameter: Tuple2[Int, Array[T]]) = { (Parameter._1, (Parameter._2.size, Parameter._2.map(implicitly[Numeric[T]].toDouble(_)).sum / Parameter._2.size)) } 
+1
source share
  • Iterable not Array , so your function cannot work on it. Instead, you can define def getCountsAndAverages[T](Parameter: Tuple2[Int, Iterable[T]])(implicit n:Numeric[T]) . But in this case, Parameter._2.map(n.toDouble).sum/Parameter._2.size may be inefficient, depending on the actual type of execution time of Parameter._2 . You might want to write it as a fold.

  • Change the map call to parsedfile.map(getCountsAndAverages(_)) .

When you write parsedfile.map(getCountsAndAverages) , it is converted to an anonymous function using eta-expansion . But it seems that this happens before the type parameter is output, so you get (x: T) => getCountsAndAverages(x) for an arbitrary T that does not compile. parsedfile.map(getCountsAndAverages[Double]) works as well. This is a known unsolved issue: https://issues.scala-lang.org/browse/SI-7641 .

+1
source share

All Articles