The following polymorphic methods compile:
import spire.math._
import spire.implicits._
scala> def foo[A:Numeric](d : A) = 2 * d
foo: [A](d: A)(implicit evidence$1: spire.math.Numeric[A])A
scala> def foo[A:Numeric](d : A) = 2 + d
foo: [A](d: A)(implicit evidence$1: spire.math.Numeric[A])A
However, if I change the integer 2
to the double 2.0
the compiler complains about not finding an implicit value
scala> def foo[A:Numeric](d : A) = 2.0 + d
<console>:19: error: could not find implicit value for parameter ev: spire.algebra.Field[A]
def foo[A:Numeric](d : A) = 2.0 + d
^
scala> def foo[A:Numeric](d : A) = 2.0 * d
<console>:19: error: could not find implicit value for parameter ev: spire.algebra.Field[A]
def foo[A:Numeric](d : A) = 2.0 * d
^
I have tried to understand some of the other questions and answers on SO but I am none the wiser on how to solve this.
I find the clearest way to see what's going on with implicits is to use
reify
(your IDE may provide similar functionality):And looking in the spire source we see:
This is an implicit class that makes a
*
method available onInt
s, provided the value on the right (d
in your code) is someA
which forms aRing
(which anyNumeric
A
will). So your first example works. But in the second example there's no such implicit (noLiteralDoubleMultiplicativeSemigroupOps
or the like), so the second example doesn't compile.