Ich versuche zu verstehen, warum können nicht die Scala-Compiler die folgende Einschränkung auf einem Pfad abhängigen Typen ableiten:Scala - Untere Grenze Inferenz in pfadabhängigen Arten
trait MyTrait
class MyTraitImpl extends MyTrait
trait MyTrait2[A <: MyTrait] {
type MyTraitType = A
}
class MyTrait2Impl[A <: MyTrait] extends MyTrait2[A]
val obj: MyTrait2[_] = new MyTrait2Impl[MyTraitImpl]
def myMethod[A <: MyTrait](t2: MyTrait2[A]) = println("Hi!")
myMethod[obj.MyTraitType](obj)
// <console>:14: error: type arguments [obj.MyTraitType] do not conform to method myMethod's type parameter bounds [A <: MyTrait]
// myMethod[obj.MyTraitType](obj)
Für mich intuitiv, MyTraitType
kann nichts anderes sein als eine Unterklasse von MyTrait
, da die Grenze direkt an A
in MyTrait2
ist. Wenn ja, kannst du mir ein Beispiel geben oder mich darauf hinweisen, wo dieses Code-Snippet falsch ist?
Wenn dies eine Scala-Compiler-Einschränkung ist, kann mir jemand einen Weg zeigen, dies mit dem Typsystem zu erreichen? Beachten Sie, dass:
- Ich habe keinen
MyTrait
Gegenstand haben, auch nichtmyMethod
ein empfangen; - Ich brauche nicht
myMethod
zu wissen, die konkrete Art vonA
; alles, was es wissen muss, ist, dassA
es ein Subtyp vonMyTrait
ist und dasst2
aufA
parametriert ist; - Der Unterstrich in
obj
ist absichtlich; wo ichmyMethod
rufe, kenne ich den konkreten Typ vonA
nicht (oder sonst wäre es kein Problem); - Ich bevorzuge Lösungen, wo ich
myMethod
nicht ändern muss. verwenden Einschränkungen für Typ-Member
So funktioniert es zwar, aber es ist eine Art Workaround für den Unterstrich in der ursprünglichen Frage.In Ihrer Lösung funktioniert der Aufruf, weil der Compiler den konkreten Typ "A" in "obj" kennt, während er in meinem Beispiel explizit unterdrückt wurde. Stellen Sie sich vor, ich hätte eine 'List [MyTrait2]' und möchte 'myMethod' mit einem der Elemente aufrufen; Es wird nicht mit beiden Lösungen funktionieren. Meiner Meinung nach sollte es meiner Meinung nach auch so sein, denn es gibt konkrete Grenzen ('<: MyTrait') für welche Typen man' A' nehmen kann. –
@RuiGoncalves: Meine Lösung arbeitet mit 'List [MyTrait2]' ganz gut. – senia
@ RuiGonçalves: Ich habe einen Beweis zu meiner Antwort hinzugefügt, siehe Update. – senia