Search code examples
scalatype-parameterimplicit-parameters

Use of an implicit parameter of type Numeric[A] seems to be ignored


Being new to Scala, I was playing around with fold, reduce and scan. I wanted to see the sequence in which elements are passed on the the function parameter and how the final result was being assembled. Since I planned to use it on lists of numbers and strings, I defined the following helper function with a type parameter:

scala> def vizAdd[A](p1:A, p2:A):A = {
 |   val res:A = p1 + p2
 |   println( s" * ($p1, $p2) => $res" )
 |   res
 | }
<console>:8: error: type mismatch;
 found   : A
 required: String
       val res = p1 + p2
                      ^

Post Addition with generic type parameter in Scala suggest a solution, focusing on the fact that the + method should require a numeric type to operate on, so adding an implicit parameter of type Numeric[A] to the method should do the trick. Unfortunately:

scala> def vizAdd[A](p1:A, p2:A)(implicit n: Numeric[A]):A = {
 |   val res:A = p1 + p2
 |   println( s" * ($p1, $p2) => $res" )
 |   res
 | }
<console>:8: error: type mismatch;
 found   : A
 required: String
         val res:A = p1 + p2
                          ^

The syntax with [A:Numeric] in stead of (implicit n: Numeric[A]) doesn't work either...

Compiling the singleton object “GenericTest” as implemented in the mentioned post (code below) results in the same error: “found: A, required: String”.

object GenericTest extends App {
  def func1[A](x: A, y: A)(implicit n: Numeric[A]): A = x + y    
}

What am I missing here?

I'm using Scala 2.11.5


Solution

  • The Numeric trait has methods like plus, times, etc, which are used like this:

    def func1[A](x: A, y: A)(implicit n: Numeric[A]): A = n.plus(x, y) 
    

    What you're looking for is an implicit conversion that enriches A to have the infix operations like +, *, etc. i.e., this one:

    import scala.math.Numeric.Implicits.infixNumericOps
    
    def func1[A](x: A, y: A)(implicit n: Numeric[A]): A = x + y
    

    Or more with a little syntactic sugar:

    def func1[A: Numeric](x: A, y: A): A = x + y