在范围内显示时未找到隐式
Implicit not found while it's presented in the scope
考虑以下示例:
sealed trait ST
object ST{
case class ST1() extends ST
case class ST2() extends ST
}
trait TypeClass[A]{
def doSome(a: A): Unit
}
case class Test[T](t: T)
implicit val tp: TypeClass[Test[_ <: ST]] = ??? //the implicit
def foo[A: TypeClass](a: A) = implicitly[TypeClass[A]].doSome(a)
val v: Test[_ <: ST] = ???
foo(v) //error: implicit not found
可以看出,所需的隐式在范围内,但编译器无法识别。
为什么会发生这种情况,是否有调用 foo
的解决方法?
如果您将 foo(v)
更改为 foo(v)(tp)
,它会(稍微)更好地解释为什么它不想使用 tp。
简而言之,def foo[A : TypeClass]
需要类型 TypeClass[A]
的隐式。
当您执行 foo(v)
时,A 变为 Test[_ <: ST]
,这意味着“某些 特定 的 Test
但 ST
的未知子类型”。因此,foo
想要 that 特定类型的隐式。
但是 tp
是 不是 。它是“TypeClass for Test
or any subclass of ST
”(显然 _
在这两种情况下的意思略有不同,因为 v
是具体实例,必须具有 特定 类型)。
长话短说,Test[_ <: ST]
不是 v
的实际类型,而是 超类型它的类型。所以,为了让它工作,你只需要使 TypeClass
逆变(TypeClass[-A]
) - 这将使 foo
接受 tp
作为隐式,因为它的类型将成为它所期望的子类型。
在隐式解析期间不推断存在类型,因此 f(v)
失败,因为它正在寻找具有非推断类型的隐式值
TypeClass[Test[_]]]
|
existential not inferred
但是如果您显式提供类型变量实例 foo[Test[_ <: ST]](v)
那么隐式解析应该可以工作,因为我们已经过了推理阶段。
它在 Scala 3 中工作可能是因为它在内部 rewrites 存在类型到精炼类型。
考虑以下示例:
sealed trait ST
object ST{
case class ST1() extends ST
case class ST2() extends ST
}
trait TypeClass[A]{
def doSome(a: A): Unit
}
case class Test[T](t: T)
implicit val tp: TypeClass[Test[_ <: ST]] = ??? //the implicit
def foo[A: TypeClass](a: A) = implicitly[TypeClass[A]].doSome(a)
val v: Test[_ <: ST] = ???
foo(v) //error: implicit not found
可以看出,所需的隐式在范围内,但编译器无法识别。
为什么会发生这种情况,是否有调用 foo
的解决方法?
如果您将 foo(v)
更改为 foo(v)(tp)
,它会(稍微)更好地解释为什么它不想使用 tp。
简而言之,def foo[A : TypeClass]
需要类型 TypeClass[A]
的隐式。
当您执行 foo(v)
时,A 变为 Test[_ <: ST]
,这意味着“某些 特定 的 Test
但 ST
的未知子类型”。因此,foo
想要 that 特定类型的隐式。
但是 tp
是 不是 。它是“TypeClass for Test
or any subclass of ST
”(显然 _
在这两种情况下的意思略有不同,因为 v
是具体实例,必须具有 特定 类型)。
长话短说,Test[_ <: ST]
不是 v
的实际类型,而是 超类型它的类型。所以,为了让它工作,你只需要使 TypeClass
逆变(TypeClass[-A]
) - 这将使 foo
接受 tp
作为隐式,因为它的类型将成为它所期望的子类型。
在隐式解析期间不推断存在类型,因此 f(v)
失败,因为它正在寻找具有非推断类型的隐式值
TypeClass[Test[_]]]
|
existential not inferred
但是如果您显式提供类型变量实例 foo[Test[_ <: ST]](v)
那么隐式解析应该可以工作,因为我们已经过了推理阶段。
它在 Scala 3 中工作可能是因为它在内部 rewrites 存在类型到精炼类型。