Подтвердить что ты не робот

Ошибка с 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

4b9b3361

Ответ 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 *.