Scala неожиданно не может определить тип расширенной функции
Почему в Скале дано:
a = List(1, 2, 3, 4)
def f(x : String) = { x }
делает
a.map(_.toString)
работать, но
a.map(f(_.toString))
дай ошибку
missing parameter type for expanded function ((x$1) => x$1.toString)
1 ответ
Что ж... f()
принимает строку в качестве параметра. Конструкция _.toString
имеет тип A <: Any => String
, Функция f()
ожидает тип String
, так что пример выше не проверяет тип. Кажется, что Scala дружелюбен в этом случае и дает пользователю еще один шанс. Сообщение об ошибке означает: "По моим алгоритмам вывода типов это не компилируется. Введите типы, и это может произойти, если я что-то не могу вывести".
В этом случае вам придется написать анонимную функцию, т.е. a.map(n => f(n.toString))
, Это не ограничение вывода типа, а подстановочный знак. В основном, когда вы пишете a.map(f(_.toString))
, _.toString
превращается в анонимную функцию в ближайших скобках, которые он может найти, в противном случае это приведет к огромной неопределенности. Представь что-то вроде f(g(_.toString))
, Это значит f(g(x => x.toString))
или же f(x => g(x.toString))
? Хуже неоднозначности могут возникнуть при множественных вызовах вложенных функций. Поэтому средство проверки типа Scala принимает наиболее логичное решение, как описано выше.
Nitpick: первая строка вашего кода должна быть val a = List(1,2,3,4)
:).