Reputation: 328
I have written a function to accept the below type of values: (1, Array(1.0,2.0,3.0)) That is a Tuple with Int being first value and next being an Array of Doubles.
I would also like it to accept an Array of Integers as well. The function I have written is as below:
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 tuple's first parameter is a number and then its an Array of number of times it appears in the file.
It is working fine for sample cases, however I am reading a text file which has the data in the same format as needed for this function to work. I am calling this function using 'map' operation as:
parsedfile.map(getCountsAndAverages)
I am getting the below 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
Upvotes: 5
Views: 3063
Reputation: 170745
Iterable
isn't Array
, so your function can't work on it. You can define def getCountsAndAverages[T](Parameter: Tuple2[Int, Iterable[T]])(implicit n:Numeric[T])
instead. But in this case Parameter._2.map(n.toDouble).sum/Parameter._2.size
may be inefficient, depending on the actual runtime type of Parameter._2
. You may want to write it as a fold instead.
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 is seems to happen before type parameter inference, so you end up with (x: T) => getCountsAndAverages(x)
for arbitrary T
, which doesn't compile. parsedfile.map(getCountsAndAverages[Double])
works as well. This is a known unresolved issue: https://issues.scala-lang.org/browse/SI-7641.
Upvotes: 1
Reputation: 14825
You can use any one of the following syntax
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))
}
Upvotes: 3