Angenommen, ich habe eine einfache Art Klasse, deren Instanzen bekam gibt mir einen Wert von etwas Art:Erstellen von Instanzen einer kovarianten Typklasse von Instanzen eines nicht covariant ein
trait GiveMeJustA[X] { def apply(): X }
Und ich habe einige Fälle:
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)
}
Jetzt habe ich eine ähnliche (aber nicht verwandten) Klasse geben, die das gleiche tut, aber in seiner Art Parameter kovariant:
trait GiveMeA[+X] { def apply(): X }
In seinem Begleitobjekt sagen wir dem Compiler, wie Instanzen von Instanzen unserer nicht-kovarianten Typklasse erstellen:
object GiveMeA {
implicit def fromGiveMeJustA[X](implicit giveMe: GiveMeJustA[X]): GiveMeA[X] =
new GiveMeA[X] { def apply() = giveMe() }
}
Jetzt würde ich implicitly[GiveMeA[Foo]]
erwarte einfach gut zu kompilieren, da eine Möglichkeit gibt es nur eine bekommen GiveMeA[Foo]
gegeben die Stücke, die wir hier haben. Aber es funktioniert nicht (zumindest nicht auf entweder 2.10.4 oder 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]]
^
Wenn wir unsere irrelevant GiveMeJustA
Instanz loszuwerden, es funktioniert:
scala> implicit def GiveMeJustABar: List[Long] = ???
GiveMeJustABar: List[Long]
scala> implicitly[GiveMeA[Foo]]
res1: GiveMeA[Foo] = [email protected]
Dies ist in Trotz der Tatsache, dass es keine Möglichkeit gibt, GiveMeA.fromGiveMeJustA
auf diese Instanz anzuwenden, um eine GiveMeA[Foo]
(oder einen beliebigen Subtyp von GiveMeA[Foo]
) zu erhalten.
Das sieht für mich wie ein Fehler aus, aber es ist möglich, dass ich etwas vermisse. Macht das irgendeinen Sinn? Gibt es eine angemessene Problemumgehung?
Die Lösung arbeitet für die Einführung gegebenes Beispiel. Aber in meinem Fall verwende ich 'Generic', wo' GiveMeJustA' verwendet wird. Und in diesem Fall scheint die Lösung nicht zu funktionieren, ich vermute wegen der Makros. – tksfz