Non riesco a scrivere il seguente polimorfismo F-bounded in Scala. Perché?Polimorfismo Scala F-bound sull'oggetto
trait X[T <: X[T]]
object Y extends X[Y]
Come posso esprimere questo e renderlo compilato?
Non riesco a scrivere il seguente polimorfismo F-bounded in Scala. Perché?Polimorfismo Scala F-bound sull'oggetto
trait X[T <: X[T]]
object Y extends X[Y]
Come posso esprimere questo e renderlo compilato?
Sembra davvero come si dovrebbe essere in grado di scrivere,
trait X[T <: X[T]]
object Y extends X[Y.type]
tuttavia, se si tenta che il compilatore vi darà un inutile (e penso spuria) errore,
scala> object Y extends X[Y.type]
<console>:16: error: illegal cyclic reference involving object Y
object Y extends X[Y.type]
Dico "spurio" perché possiamo costruire un oggetto equivalente con un po 'di infrastruttura aggiuntiva,
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
Se si desidera sperimentare questo nel codice reale, l'utilizzo di un oggetto del pacchetto al posto di object Fix
renderebbe questo linguaggio un po 'più utilizzabile.
modificarla in:
trait Y extends X[Y]
object
non è un tipo a Scala, ma il cosiddetto oggetto associato. Definendo object Y
, non è possibile esprimere che dovrebbe estendere trait T[Y]
, poiché il secondo Y
si riferisce a un tipo Y
che non è stato definito. È possibile comunque effettuare le seguenti operazioni:
trait Y extends X[Y] //If you try this on the REPL, do :paste before
object Y extends X[Y]
In questo caso l'oggetto si estende Y
X[Y]
dove il secondo Y è il tratto che avete appena definito, assicurarsi di tenere questo in mente.
Vorrei che Y fosse instanciato una sola volta e acceda alla sua istanza unica, ecco perché ho bisogno di un oggetto. –
Quindi è possibile rendere privato il costruttore con 'class Y private() estende X [Y]' e rendere tale istanza disponibile pubblicamente. – Chirlo
Pensi che questo sia un errore del compilatore o è una svista nelle specifiche? O forse c'è qualche sottigliezza che non vediamo, che rende necessario l'errore? –
Una conversazione con @retronym su scala/scala (https://gitter.im/scala/scala?at=55dc7303fcfd5a7865af45d4) suggerisce che si tratta di un bug. E funziona [come previsto su Dotty] (https://gitter.im/lampepfl/dotty?at=55dc95a3a6bcd8894068e278). –
https://github.com/scala/bug/issues/9844 –