Domanda

La seguente classe Scala:

class Foo[+T <: Bar] extends FooBase ...

definisce efficacemente una gerarchia di tipi che ha Foo [Bar] come radice, ovvero qualsiasi Foo [X] valido sarà assegnabile a un valore o una variabile Foo [Bar]:

val v1: Foo[Bar] = new Foo[SubBar1]();
val v2: Foo[Bar] = new Foo[SubBar2]();

FooBase è più in alto e potrebbe anche implicare oggetti che non sono Foo: quanto segue mostra il problema:

class Trouble extends FooBase ...
val iOnlyWantFooHere: FooBase = new Trouble();

... e anche FooBase non è a conoscenza del tipo T, quindi i suoi membri non possono specificarlo e dovrei sovrascrivere queste definizioni in Foo per specializzarli:

class FooBase {
  def ohNoIDontKnowTheType: Bar;
}

class Foo[+T <: Bar] extends FooBase {
  override def ohNoIDontKnowTheType: T = ...;
}

Esistono altri modi per aggirare il problema, ma il punto dovrebbe essere chiaro.

Infine, la mia vera domanda è qual è la radice della seguente gerarchia:

class Foo[+T <: Foo[T]] extends FooBase ...

Ancora una volta, non dirmi FooBase, perché non è così. Sì, potrei inserire un'altra classe in mezzo specificamente per lo scopo, ma questa non è ancora una risposta vera come indicato sopra.

A Scala non piace solo Foo (senza il parametro type), e non è nemmeno Foo[_] poiché quindi l'accesso ai metodi che restituiscono il valore del tipo di parametro type sarà effettivamente Any, non Foo. Ovviamente, non possiamo nemmeno fare Foo[Foo] poiché manca anche il parametro type per il secondo e Foo[Foo[_]] o Foo[Foo[Foo[Foo[_]]] ci danno solo così tanti livelli.

C'è una risposta o Scala non ha il supporto per questo?

Grazie in anticipo!

È stato utile?

Soluzione

Che ne dici di Foo[_ <: Foo[_]]?Che, a proposito, ho menzionato nella mia risposta all'altra tua domanda.Oppure potresti scriverlo in questo modo:

type Base = Foo[t] forSome { type t <: Foo[t] }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top