假设我有一个简单的类型类,它的实例会给我某种类型的值:
trait GiveMeJustA[X] { def apply(): X }
我有一些例子:
case class Foo(s: String)
case class Bar(i: Int)
implicit object GiveMeJustAFoo extends GiveMeJustA[Foo] {
def apply() = Foo("foo")
}
implicit object GiveMeJustABar extends GiveMeJustA[Bar] {
def apply() = Bar(13)
}
现在我有一个类似(但不相关)的类型类,它做同样的事情,但它的类型参数是协变的:
trait GiveMeA[+X] { def apply(): X }
在它的伴生对象中,我们告诉编译器如何从我们的非协变类型类的实例中创建实例:
object GiveMeA {
implicit def fromGiveMeJustA[X](implicit giveMe: GiveMeJustA[X]): GiveMeA[X] =
new GiveMeA[X] { def apply() = giveMe() }
}
现在我希望implicitly[GiveMeA[Foo]]
编译得很好,因为只有一种方法可以得到GiveMeA[Foo]
我们这里的给定部分。但它没有(至少不是在 2.10.4 或 2.11.2 上):
scala> implicitly[GiveMeA[Foo]]
<console>:16: this.GiveMeA.fromGiveMeJustA is not a valid implicit value for GiveMeA[Foo] because:
hasMatchingSymbol reported error: ambiguous implicit values:
both object GiveMeJustAFoo of type GiveMeJustAFoo.type
and object GiveMeJustABar of type GiveMeJustABar.type
match expected type GiveMeJustA[X]
implicitly[GiveMeA[Foo]]
^
<console>:16: error: could not find implicit value for parameter e: GiveMeA[Foo]
implicitly[GiveMeA[Foo]]
^
如果我们摆脱不相关的GiveMeJustA
实例,它会起作用:
scala> implicit def GiveMeJustABar: List[Long] = ???
GiveMeJustABar: List[Long]
scala> implicitly[GiveMeA[Foo]]
res1: GiveMeA[Foo] = GiveMeA$$anon$1@2a4f2dcc
尽管事实上我们无法应用GiveMeA.fromGiveMeJustA
此实例来获取 a GiveMeA[Foo]
(或 的任何子类型GiveMeA[Foo]
)。
这对我来说似乎是一个错误,但我可能遗漏了一些东西。这有道理吗?有没有合理的解决方法?