2016-08-01 27 views
0

Unabhängig von der Varianz des Parameters auf der linken Seite, die platzierten Beschränkungen für Ta und Tb in der folgenden Erklärung versagt die typecheck:Warum können klassenübergreifende Obergrenzeneinschränkungen nicht kovariant sein und Untergrenzeneinschränkungen in Hack kontravariant sein?

class A<+TCov, -TCon, [±]Ta as TCov, [±]Tb super TCon> { 
    public function __construct(private Ta $ta, private Tb $tb) {} 
    // [various methods making use of Ta and Tb] 
} 

Es ist erwähnenswert, dass die leere Klassendeklaration Fehler nicht erhöhen, sondern sobald die Parameter beschränkt verwendet (eigene Varianzen in ansonsten gültigen Positionen angegeben) sind, hebt der typechecker einen der folgenden Schritte:

Illegal Verwendung von kovarianten Typparameter (Typing [4120]), ... as Constraints kontra

Illegal Verwendung kontraTypParameter (Typing [4121]) sind ... super Constraints sind kovarianten

mit Bezug auf den Parameter auf der rechten Seite der Einschränkungs.

Ich kann mehr verstehen, warum generische Methoden Probleme darstellen. Die Verletzung Positionen sind ziemlich offensichtlich, und unter Verwendung der Argumente in Positionen, die Varianz ihrer Zwänge anpassen, sind unmöglich:

class A<+TCov, -TCon> { 
    public function cov_violate<T as TCov>(T $v): void { 
    // T can be cast to TCov and violate type if the original type is a subtype of T 
    } 
    public function con_violate<T super TCon>(): T { 
    // vice versa for the contravariant parameter 
    } 

    public function cov_impossible<T as TCov>(): T { 
    // how will we produce a T-typed value? 
    } 
    public function con_impossible<T super TCov>(T $v): void { 
    // what will we do with a T-typed value? 
    } 
} 

Aber was ist das Problem mit klassenweite Parameter? Für alle sechs fehlerhaften Beziehungen ({+|-| }T as +TCov und {+|-| }T super -TCon) kann ich mir kein Szenario ausdenken, in dem diese nicht typsicher wären. Meiner Meinung nach scheinen ihre Varianzen entweder ihre Casting-Richtung oder ihre Positionen ausreichend einzuschränken, um diese Beziehungen als sicher zu deklarieren.

Antwort

0

Ich habe 3.13.1 zum Zeitpunkt dieser Frage ausgeführt, aber zum Glück wurde die Einschränkung gelockert, um diese Untertypisierung der Klassen-Typ-Parameter ab HHVM 3.14.4 durch this commit zu ermöglichen! Das Commit verweist auch auf this Microsoft paper für einen Nachweis der Solidität.