Reputation: 4239
Scala version: 2.12.4.
Let's say, there's one empty trait and one class with function, which accepts trait instance as implicit parameter:
trait I
class A {
def fa()(implicit i: I): Unit = {}
}
Let's define another class, which invokes this fa()
function. We'll try to import I
instance from its companion object:
class B(a: A) {
import B._
def fb(): Unit = { a.fa() }
}
object B {
private implicit object II extends I
}
But we face an error then!
error: could not find implicit value for parameter i: I
def fb(): Unit = { a.fa() }
^
Let's make implicit val then in class B
:
class B(a: A) {
import B._
private implicit val ii = II
def fb(): Unit = { a.fa() }
}
Suddenly, we still face an error anyway:
error: ambiguous implicit values:
both value ii in class B of type => B.II.type
and object II in object B of type B.II.type
match expected type I
def fb(): Unit = { a.fa() }
^
Upvotes: 1
Views: 380
Reputation: 170735
This is an ordering issue with type inference. There are other similar questions, I don't know if there is an exact duplicate.
The issue is that when class B
is type-checked, type inference hasn't yet run on object B
. Using II
in the body of class B
in the second example triggers this type inference and makes it visible as an implicit I
.
It can be solved by either placing the companion object before the class, or by giving explicit type to II
, e.g.
object B {
private implicit val II: I = new I {}
}
See e.g. Why does this explicit call of a Scala method allow it to be implicitly resolved?
Upvotes: 2