Could not find implicit parameter in companion class

128 Views Asked by At

I have a Number Wrapper like this

class NumWrapper[A<:AnyVal](var v: A)(implicit n:Numeric[A]) {
  def +(other: A): NumWrapper[A] = {
    new NumWrapper(n.plus(v, other))
  }

  def -(other: A): NumWrapper[A] = {
    new NumWrapper(n.minus(v, other))
  }
}

All work fine. But when I want to have the implicit conversion, i create a companion class as followed:

object NumWrapper {
  implicit def toNumWrapper[A<:AnyVal](v: A) = new NumWrapper[A](v)
}

But I have the error at compilation:

could not find implicit value for parameter n: Numeric[A]

What is wrong here ? Why it is trying to find the implicit match for type A at compilation?

Thank you very much for your help.

2

There are 2 best solutions below

0
On BEST ANSWER

Implicit checks in Scala are performed at compile time (it is a statically typed language). If the compiler can't identify a single, unambiguous, matching implicit value that will be available at the calling location, it complains.

One way you can fix this here is to add the implicit requirement to the toNumWrapper method:

object NumWrapper {
  implicit def toNumWrapper[A<:AnyVal](v: A)(implicit n:Numeric[A]) = new NumWrapper[A](v)
}

This pushes the requirment for an implicit Numeric out to the location where the implicit conversion is required, eg, in the console, I could then write:

scala> val chk1 = 3L
chk1: Long = 3

scala> val chk2 = NumWrapper.toNumWrapper(chk1)
chk2: NumWrapper[Long] = NumWrapper@1e89017a

And the compiler is happy because (I think - not entirely sure of this) the Long value carries its own implicit Numeric[Long] with it.

0
On

According your code,

class NumWrapper[A<:AnyVal](var v: A)(implicit n:Numeric[A])

to call new NumWrapper[MyType](v) a Numeric[MyType] must be in the scope of implicit resolution.

So when you have

object NumWrapper {
  implicit def toNumWrapper[A<:AnyVal](v: A) = new NumWrapper[A](v)
}

which is calling this NumWrapper constructor, the Numeric[A] must resolved. That's not the case and the compiler raise the mentioned error.