Ошибка с varargs для функций-объектов в Scala?
Почему это не работает?
val f = (args: Int*) => args.sum
error: ')' expected but identifier found.
val f = (args: Int*) => args.sum
^
Это, однако, прекрасно работает
def sum(args: Int*) = args.sum
val f = sum _
так делает это
val f: (Int*) => Int = args => args.sum
кстати. Я использую scala 2.9.1
Ответы
Ответ 1
Я не эксперт в чтении спецификаций, но похоже, что синтаксис varargs не поддерживается для анонимной функции.
Сравните синтаксис для объявления функции с анонимными функциями в Language Spec
Из 4.6 Декларации функций и определения
ParamType ::= Type
| ‘=>’ Type
| Type ‘*’
6.23 Анонимные функции
Binding ::= (id | ‘_’) [‘:’ Type]
Я понятия не имею, какие причины для этого. Там, по-видимому, есть причины, но никто не может быть легко объяснен. Мартин Одерски прокомментировал запрос на добавление varargs для анонимных функций: "Сначала это кажется соблазнительным, но оно сильно затянулось бы (вам просто нужно поверить мне на этом)".
Ответ 2
Здесь также есть хорошее объяснение, данное Lex Spoon здесь здесь
Синтаксис здесь немного вводит в заблуждение; возможно, это слишком мило. Синтаксис Any * для varargs делает его похожим на Any *, сам по себе является типом. Действительно, * является аннотацией к параметру метода, а не типу.
Когда вы записываете тип функции с использованием синтаксиса T1 = > T2, T1 и T2 должны быть обычными старыми добросовестными типами. Scala предоставляет куча видов, но типы vararg не являются одним из них.
В практическом коде выход состоит в том, чтобы явно использовать тип последовательности. На самом деле, если вы посмотрите на предполагаемый тип для good2, вы увидите, что он включает Seq [Any], а не Any *.