2014-04-30 11 views
5

In Scala 2.10.4 dies kompiliert:Scala 2.11 Typ Variance Änderungen

trait Foo[-U,T]{ 
    type Contra = U 
} 

aber 2.11.0 in der gleichen nicht mit:

kontra Typ U tritt in unveränderliche Position in Typ U Geben Sie ein Contra Merkmal Foo [-U, T] {Typ Contra = U}

Gibt es einen Workaround? Der Versuch, eine Scala-Bibliothek auf 2.11 und den kontravarianten Typ zu portieren, ist erforderlich, um eine Bootsladung von impliziten Defs zu erhalten, die vom Compiler aufgenommen werden (d. H. U-Invarianten scheinen keine Option zu sein).

Danke

+1

Könnten Sie erklären, mehr darüber, wie Sie den Typ Element zu verwenden und Kontra implizite Auflösung zu kontrollieren? Ich wäre daran interessiert, mehr darüber zu erfahren, und vielleicht gibt es einen Workaround, der tiefer in dem Problem liegt. – wingedsubmariner

+0

Können Sie 'Typ Contra>: U' verwenden? –

+0

@ n.m. Ich kann Contra>: U nicht als die Instanzen verwenden, die von U abhängen, und nicht von einem Supertyp von U (dh, bei diesem Ansatz kompiliert der Compiler, dass Methode X kein Mitglied von Contra ist) – virtualeyes

Antwort

4

Ich kann mir nicht vorstellen, dass es eine verfügbare Arbeit gibt. Der Grund, warum ich sagen, dass dies alles über die Unterstützung wegabhängige Typen:

def foo[T <: Foo[A,B]](that: T): that.Contra 

die den Contra Typ in der falschen Position platziert. Sie können einen kontravarianten Typ als Ergebnis einer Operation nicht zurückgeben. Vielleicht erfordert die Suche und Validierung dieser so viel Arbeit, dass die Autoren des Compilers entschieden haben, dass dieser kleine Eckfall eine zu große Belastung darstellt oder es ist ein Compilerfehler, den Sie aufgedeckt haben.

Übrigens ist dies nur wilde Spekulationen meinerseits. Ich müsste den Compiler-Code lesen, um herauszufinden, welcher Weg welcher ist.

+0

+1 für das Beispiel bestätigt die Änderung in 2.11.In meiner Antwort finden Sie den verlinkten Fehler-Thread für Details. – virtualeyes

4

Offenbar Post-2.7 und Pre-2.11 this was a bug im Typ Checker. Nun ist die Verhinderung des Ansatzes in OP ist ein Merkmal, das eine gute Sache ist, eine Art o_O

Die Abhilfe ist zu tun, wie ein Pre-2.11 taten, mit dem Unterschied, dass Sie jetzt wissen du bist auf eigene Faust, vs. vor, wo Sie dachten, der Compiler hätte Ihren Rücken.

Ignoranz ist Glückseligkeit, oder?

Die Abhilfe:

import annotation.unchecked._ 
trait Foo[-U,T]{ 
    type Contra = (U @uncheckedVariance) 
}