Ошибка с varargs для функциональных объектов в Scala? - PullRequest
21 голосов
/ 24 декабря 2011

Почему это не работает?

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

Ответы [ 2 ]

24 голосов
/ 24 декабря 2011

Я не специалист по чтению спецификаций, но похоже, что синтаксис varargs не поддерживается для анонимной функции.

Сравните синтаксис объявления функций с анонимными функциями в спецификации языка

Из 4.6 Объявления и определения функций

ParamType ::= Type
              | ‘=>’ Type
              | Type ‘*’

6.23 Анонимные функции

Binding ::= (id | ‘_’) [‘:’ Type]

Я понятия не имею, в чем причина этого. Кажется, есть причины, но нет таких, которые можно легко объяснить. Мартин Одерский прокомментировал запрос на добавление varargs для анонимных функций: «Поначалу это выглядит заманчиво, но это может повлечь за собой большую сложность (вам просто нужно в это поверить)»

2 голосов
/ 29 декабря 2012

Здесь также есть хорошее объяснение, данное Лексом Ложкой здесь

Здесь синтаксис немного вводит в заблуждение; возможно это слишком мило. Синтаксис Any * для varargs делает вид, что Any * сам по себе является типом. Действительно, * - это аннотация к параметру метода, а не к типу.

Когда вы записываете тип функции с использованием синтаксиса T1 => T2, оба T1 и T2 должны быть обычными добросовестными типами. Scala предоставляет множество типов типов, но типы vararg не входят в их число.

В практическом коде выходом является явное использование типа последовательности. Фактически, если вы посмотрите на предполагаемый тип для good2, вы увидите, что он включает в себя Seq [Any], а не Any *.

...