Ten problem powstał w module, który piszę, ale zrobiłem minimalny przypadek, który wykazuje takie samo zachowanie.Dlaczego tutaj nie jest pisana inferencja typów?
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
}
Problemem jest to, że kompilator udaje się zorientować się parametr wewnętrzny do Minimal
(Int
), a następnie ustawia inne zdarzenia T
do Nothing
, co oczywiście nie jest zgodna apply
. Są to z pewnością te same wartości, co T
, ponieważ usunięcie pierwszego parametru powoduje, że drugi narzeka, że T nie jest zdefiniowany.
Czy istnieje pewna niejednoznaczność, która oznacza, że kompilator nie może wywnioskować pierwszego parametru, czy jest to błąd? Czy mogę obejść to z wdziękiem?
Dalsze informacje: Ten kod jest prostym przykładem próby syntaktycznego cukru. Oryginalny kod próbuje uczynić |(a)|
znaczeniem modułu a
, gdzie a jest wektorem. Najwyraźniej |(a)|
jest lepsze niż pisanie |[Float,Vector3[Float]](a)|
, ale niestety nie mogę użyć unary_|
, aby było to łatwiejsze.
Rzeczywisty błąd:
inferred type arguments [Nothing,Minimal[Int]] do not conform to method apply's type parameter bounds [T,X <: Sugar.S[T]]
Tak, to rozwiązanie działa dobrze w moim przypadku. Jest także czystszy niż rozwiązanie Joshua (przepraszam Joshua!). Czy możesz więc wyjaśnić, dlaczego rozwiązanie Joshua działa? – Dylan
Należy zaktualizować odpowiedź, aby wyjaśnić, dlaczego rozwiązanie Joshua działa. –