Hmm...
Dla mnie to jest to wszystko pomieszane jakoś jeśli chodzi o Scalę, może dlatego że nie miałem wcześniej do czynienia z paradygmatem funkcyjnym (i przy okazji przemieszanym z obiektowym).
1.
val show_f: B => Unit = () => ()
Nie powinno być np :
val show_f: B => Unit = (b: B) => ()
Inaczej jednak mi się nie kompiluje ;)
Tak, masz rację. Walnąłem się :)
class A[+T]{def show(x: T) = {}}
Czyli metoda zachowuje się w takim przypadku jak funkcja (chodzi o wariancje) ?
Metoda, o ile nie podasz wprost, nie ma własnego parametru generycznego, a więc w ogólności zachowuje się inaczej niż funkcja. Jak chcesz konkretną odpowiedź to pokaż konkretny przypadek, tzn zarówno typ bazowy funkcji czy metody oraz metodę czy funkcję implementującą.
- Powiedzmy że mamy :
var show_f: B => B = _
show_f = (_: A) => new B // jeśli chodzi o typ to mogę dać _: A lub _: B (kontrawariancja)
show_f(new C) // jeśli chodzi o argument to mogę dać new C lub new B (dziedziczenie)
Dlaczego jako argument nie mogę dać instancji klasy A ?
Funkcja przyjmująca argument, a argument dla funkcji to dwie strony barykady. Funkcja przyjmująca A przyjmie też B, ale jeśli funkcja przyjmuje B to nie możemy wstawić do niej niekompatybilnego A.
Tak jak napisałem wcześniej, w Scali wariancja jest sprawdzana głównie przy przypisaniu instancji F[A]
do zmiennej typu F[B]
, a nie przy wywoływaniu metod na F[B]
.
Oznaczanie wariancji jest po to, by móc stworzyć poprawny i ogólny kod. Inwariancja pozwala pisać poprawny kod, ale mocno ogranicza możliwości kompozycji. Z drugiej strony niedostatki w sprawdzaniu wariancji powodują błędy niewykrywalne na etapie kompilacji. Sztandarowym przykładem są tablice w Javie:
String[] stringi = new String[] { "ala ma kota" };
Object[] obiekty = stringi;
obiekty[0] = 5; // błąd ArrayStoreException
Z racji tego że są mutowalne, a więc mają de facto settery powinny być inwariantne. Twórcy Javy zdecydowali, że będą kowariantne (niezgodnie z regułami wariancji). Wskutek tego da się wygenerować powyższy błąd rzutowania mimo iż kompilacja przebiegła bez błędów.
Poza tym polecam zapoznać się z tabelką wariancji parametrów i typów zwracanych metod: Covariance and contravariance (computer science)