Questo problema è sorto in un modulo che sto scrivendo, ma ho creato un caso minimale che mostra lo stesso comportamento.Perché non digitare l'inferenza funziona qui?
class Minimal[T](x : T) {
def doSomething = x
}
object Sugar {
type S[T] = { def doSomething : T }
def apply[T, X <: S[T]] (x: X) = x.doSomething
}
object Error {
val a = new Minimal(4)
Sugar(a) // error: inferred [Nothing, Minimal[Int]] does not fit the bounds of apply
Sugar[Int, Minimal[Int]](a) // works as expected
}
Il problema è che il compilatore riesce a capire il parametro interno per Minimal
(Int
), ma poi imposta l'altra occorrenza di T
a Nothing
, che ovviamente non corrisponde apply
. Questi sono sicuramente gli stessi T
, poiché la rimozione del primo parametro fa si che il secondo si riferisca al fatto che T non è definito.
C'è qualche ambiguità che significa che il compilatore non può dedurre il primo parametro, o si tratta di un bug? Posso aggirare questo con garbo?
Ulteriori informazioni: Questo codice è un semplice esempio di tentativo di zucchero sintattico. Il codice originale cerca di rendere |(a)|
il modulo di a
, dove a è un vettore. Chiaramente |(a)|
è meglio che scrivere |[Float,Vector3[Float]](a)|
, ma sfortunatamente non riesco a utilizzare unary_|
per semplificare la procedura.
L'errore effettivo:
inferred type arguments [Nothing,Minimal[Int]] do not conform to method apply's type parameter bounds [T,X <: Sugar.S[T]]
Sì, questa soluzione funziona nel mio caso. È anche più pulito della soluzione di Joshua (scusa Joshua!). Puoi spiegare perché la soluzione di Joshua funziona, allora? – Dylan
Risposta aggiornata per fornire una spiegazione del perché la soluzione di Joshua funziona anche. –