Cóż ... f()
przyjmuje ciąg jako parametr. Konstrukt _.toString
ma typ A <: Any => String
. Funkcja f()
oczekuje typu String
, więc powyższy przykład nie sprawdza typu. Wygląda na to, że Scala jest w tym przypadku przyjazna i daje użytkownikowi kolejną szansę. Komunikat o błędzie oznacza: "Według moich algorytmów wnioskowania typu nie kompiluje się. Umieszcza typy i może, jeśli jest to coś, czego nie mogę wywnioskować."
W tym przypadku należałoby napisać anonimową funkcję "longhand", tj. a.map(n => f(n.toString))
. Nie jest to ograniczenie wnioskowania typu, ale symbolu wieloznacznego. Zasadniczo, kiedy piszesz a.map(f(_.toString))
, _.toString
zostaje rozwinięty do anonimowej funkcji w najbliższym nawiasie, który może znaleźć, w przeciwnym razie doprowadziłoby to do ogromnej dwuznaczności. Wyobraź sobie coś w stylu f(g(_.toString))
. Czy to oznacza f(g(x => x.toString))
lub f(x => g(x.toString))
? W przypadku wielu zagnieżdżonych wywołań funkcji wystąpiłyby niejednoznaczności. Dlatego sprawdzarka typu Scala przyjmuje najbardziej logiczne rozwiązanie, jak opisano powyżej.
Nitpick: pierwsza linia kodu powinna być val a = List(1,2,3,4)
:).