2013-02-03 22 views
6

Kompilator mówi mi, że nie może to być z ostrzeżeniem: "Kontrowersyjny typ A występuje w kowariantnej pozycji w typie>: A <: Dowolny typ B." Ostrzeżenie jest w parametrze typu metody komponowania. Logicznie definicja typu ma dla mnie sens. Jeśli kompilator nie ma skrupułów, a następnie, dlaczego problem z konwersją?Dlaczego kompilator Scala twierdzi, że przeciwwskazania typu A występują w kowariantnej pozycji w typie>: A <: Dowolny typ B?

trait Foo[-A]{ 
    def compose[B >: A](t: Foo[B]): Foo[A] = t andThen this 
    def andThen[B <: A](t: Foo[B]): Foo[B] 
} 

Wszystko czego potrzebuję to przykład, w którym się zepsuje. Wtedy jestem szczęśliwy.

Odpowiedz

4

Zgodnie z błędem Twoja adnotacja o wariancji A jest nieprawidłowa. Nie można użyć wartości A w typie zwracanym, który jest kowariantną pozycją. Wyobraź sobie, że miał inną metodę w Foo który wykorzystuje A w prawidłowej pozycji kontrawariantny (jako argument):

trait Foo[-A] { 
    ... 
    def foo(a: A): Unit 
} 

Teraz można zobaczyć jak to wywala:

  • Foo[-A] oznacza, że ​​Foo[X] <: Foo[Y] jeśli X >: Y
  • zwracana wartość może być podtypem zadeklarowanego typu zwrotu:
  • , dlatego też, jeśli -A było tutaj legalne, compose może zwrócić Foo[A1] dla niektórych A1 >: A
  • powiedzieć trait X i trait Y extends X { def bar() }
  • wyobrazić Foo[Y] gdzie foo rozmowy a.bar()
  • konsekwencji byłoby złamać jeśli compose pozwolono powrócić Foo[X]

Więc dla ciebie przykład do kompilacja, A musi być niezmienna.