2014-05-04 16 views
7

W kodzieDlaczego adnotacja o wariancji powoduje, że ta relacja podrzędna nie jest wywnioskowana przez Scala?

sealed trait Node[+T] 
    case class I[C]() extends Node[C => C] 

    def test[A, B](n: Node[A => B]) = n match { 
    case i: I[c] => 
     val cId: c => c = identity _ 
     val ab: A => B = cId 
    } 

Scala daje błąd, że nie jest A => Bc => c. Usunięcie adnotacji o wariancji w Node[+T] rozwiązuje problem.

Jestem zdziwiony, ponieważ uważam, że w obecności adnotacji o wariancji, mecz i: I[c] powinien stworzyć regułę (c => c) <:< (A => B), która jest wszystkim, czego potrzeba do kompilacji tej linii. czego mi brakuje?

+1

Parametry funkcji są KONTRAVARANT na ich argumentach. To nie jest odpowiedź, ale domysły. –

+0

@MikeG. Hm Zastanawiałem się, czy to może być w to zaangażowane, ale nie widzę jak - wariancja '=>' nie wydaje się tu być w grze. Oczywiście, jeśli mam rację, powinienem móc odtworzyć ten przykład bez typów funkcji i powinien on nadal zawieść. Może spróbuję tego. – Owen

+0

Po dalszych eksperymentach wydaje się, że nie jest to związane z wariancją '=>' ...lub nawet do '=>' konkretnie, ale wydaje się, że ma coś wspólnego z powtarzającą się zmienną typu w 'c => c'. Wciąż nie jestem pewien, dlaczego to ma znaczenie. – Owen

Odpowiedz

0

Zrzeczenie odpowiedzialności: c w środowisku wykonawczym zostanie wymazane, a Twój mecz nie będzie działał poprawnie. Ci są dopasowane na I[_]

W przypadku, gdy Node jest niezmienna Node[A] jest podklasą Node[B] tylko IFF A=B. Zmusza

n przekazane test[A, B](n: Node[A => B]) być naprawdę Node[A => B]

Jeśli rozumować w dół, jeśli n odpowiada schematowi I[Something] niezależnie Something, A i B musi typu Something

W przypadku węzła jest kowariant, z definicji Function1[-A,+B] można zadzwonić pod numer

test[A,B](n) gdzie n jest Node[A1 =>B1] gdzie A1>:A i B1<:B(równanie 1)

więc jeśli n dopasowuje I[C] to znaczy, że A1 = C i B1 = C

Jeśli zastąpić C w równania 1, dostaniesz C >: A i C<:B(równanie 2)

Dlatego następujące przypisanie jest nieprawidłowe Już

f: A => B = C => C 

Na lewym skrzydle być przypisane z prawej strony, musimy C => C być Function1[-A,+B]

Oznacza to, że A >: C i B <: C ale z równania 2 wiemy, że to nie trzyma (z wyjątkiem przypadku C = A i C = B, i nie ma dowodów, aby tak się stało, chyba że węzeł jest niezmienny)

Powiązane problemy