假設我有一個簡單的類型類,其實例會給我一些類型的值:從實例創建一個協變型類的實例非協變一個
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)
}
現在我有一個類似(但不相關)Type類做同樣的事情,但它的類型參數的協變:
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] = [email protected]
這是儘管事實上我們無法將GiveMeA.fromGiveMeJustA
應用於此實例以獲得GiveMeA[Foo]
(或GiveMeA[Foo]
的任何子類型)。
這對我來說看起來像一個bug,但可能是我錯過了一些東西。這有意義嗎?有沒有合理的解決方法?
解決方案的工作了給出的例子。但就我而言,我正在使用'Generic',其中使用了'GiveMeJustA'。在這種情況下,解決方案似乎不起作用,我猜是因爲宏。 – tksfz 2016-11-29 00:15:41