Supponiamo di avere due classi, Input
e Output
, progettate per essere connesse tra loro. Output
produce valori di qualche tipo e Input
li consuma.Perché Scala non può inferire il parametro type in questo esempio?
class Input[T] {
var output: Option[Output[_ <: T]] = None
}
class Output[T] {
var input: Option[Input[_ >: T]] = None
}
Va bene se una coppia Input
e Output
non operano sullo stesso tipo di valore fino a quando il parametro di tipo Input
è un supertipo del parametro Output
tipo. Si noti che il parametro type in entrambe le classi è invariante; nelle versioni reali è usato in entrambe le posizioni co- e controvarianti.
Ho un metodo connect
altrove, che stabilisce un collegamento tra un Input
/Output
coppia:
def connect[T](output: Output[T], input: Input[_ >: T]) = {
output.input = Some(input)
input.output = Some(output)
}
Se chiamo questo metodo come di seguito, ottengo un errore di tipo:
val out = new Output[String]
val in = new Input[AnyRef]
connect(out, in)
L'errore è:
test.scala:17: error: type mismatch;
found : Output[String]
required: Output[AnyRef]
connect(out, in)
^
Posso risolvilo scrivendo il parametro type (in questo caso, scriverei connect[String]
, ma penso che il compilatore dovrebbe essere in grado di capirlo. Come posso modificare il metodo connect
in modo che il parametro type venga inferito automaticamente?
Edit: Per ora, ho fatto connect
un metodo di Output
così diventa il parametro di tipo automatico. Questo ha anche il vantaggio che posso usare la notazione infisso out connect in
, ma il design sembra un po 'imbarazzante.
Sono ancora interessato al motivo per cui il compilatore mostra questo comportamento. Mi sento come dovrebbe essere in grado di inferire il parametro di tipo. Funziona effettivamente come specificato?
intendevi "non operare * su * lo stesso tipo di valore" –
hai provato a porre la domanda alla mailing list di Scala? – GClaramunt