Ich kann den folgenden F-beschränkten Polymorphismus in Scala nicht schreiben. Warum?Scala F-beschränkter Polymorphismus auf Objekt
trait X[T <: X[T]]
object Y extends X[Y]
Wie kann ich dies ausdrücken und es kompilieren lassen?
Ich kann den folgenden F-beschränkten Polymorphismus in Scala nicht schreiben. Warum?Scala F-beschränkter Polymorphismus auf Objekt
trait X[T <: X[T]]
object Y extends X[Y]
Wie kann ich dies ausdrücken und es kompilieren lassen?
Es scheint wirklich, wie sollten Sie in der Lage sein, zu schreiben
trait X[T <: X[T]]
object Y extends X[Y.type]
jedoch, wenn Sie versuchen, dass der Compiler Sie nicht hilfreich geben (und ich denke, unechte) Fehler,
scala> object Y extends X[Y.type]
<console>:16: error: illegal cyclic reference involving object Y
object Y extends X[Y.type]
ich sage „unecht“ weil wir ein äquivalentes Objekt mit einem wenig zusätzlichen Infrastruktur bauen können,
trait X[T <: X[T]]
trait Fix { type Ytype >: Y.type <: Y.type; object Y extends X[Ytype] }
object Fix extends Fix { type Ytype = Y.type }
import Fix.Y
Wenn Sie mit echtem Code experimentieren wollten, würde die Verwendung eines Paketobjekts anstelle von object Fix
dieses Idiom ein wenig nützlicher machen.
ändern Sie es an:
trait Y extends X[Y]
object
ist kein Typ in Scala, aber das so genannte Begleitobjekt. Durch die Definition object Y
können Sie nicht ausdrücken, dass es trait T[Y]
erweitern sollte, da sich die zweite Y
auf einen Typ Y
bezieht, der nicht definiert wurde. Sie können die folgenden jedoch tun:
trait Y extends X[Y] //If you try this on the REPL, do :paste before
object Y extends X[Y]
In diesem Fall wird das Objekt Y
X[Y]
erstreckt, wo die zweite Y das Merkmal ist, dass Sie nur definieren, stellen Sie sicher, dass Sie dies im Auge behalten.
Ich möchte, dass Y nur einmal instanziert wird und auf seine eindeutige Instanz zugreift, deshalb brauche ich ein Objekt. –
Dann können Sie den Konstruktor mit 'Klasse Y private() extends X [Y]' privat machen und diese Instanz öffentlich verfügbar machen. – Chirlo
Glaubst du, das ist ein Compiler Bug oder ist es ein Versehen in der Spezifikation? Oder vielleicht gibt es etwas Subtilität, die wir nicht sehen, die den Fehler notwendig macht? –
Ein Gespräch mit @retronym auf [scala/scala] (https://gitter.im/scala/scala?at=55dc7303fcfd5a7865af45d4) deutet darauf hin, dass es sich um einen Fehler handelt. Und es funktioniert [wie erwartet auf Dotty] (https://gitter.im/lampepfl/dotty?at=55dc95a3a6bcd8894068e278). –
https://github.com/scala/bug/issues/9844 –