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

Почему я получаю "отсутствующий параметр для расширенной функции" в одном случае, а не в другом?

Дело в этом:

Seq(fromDir, toDir) find (!_.isDirectory) foreach (println(_))

Если это не так:

Seq(fromDir, toDir) find (!_.isDirectory) foreach (throw new Exception(_.toString))

Компиляция заканчивается этой ошибкой:

error: missing parameter type for expanded function ((x$4) => x$4.toString)

Теперь, если я напишу его таким образом, он снова скомпилируется:

Seq(fromDir, toDir) find (!_.isDirectory) foreach (s => throw new Exception(s.toString))

Я уверен, что есть разумное объяснение;)

4b9b3361

Ответ 1

Это уже рассмотрено в связанном вопросе. Подчеркивания расширяются к ближайшему закрытию Expr: выражения верхнего уровня или выражения в круглых скобках.

(_.toString) - выражение в круглых скобках. Таким образом, аргумент, который вы передаете Exception в случае ошибки, после расширения - это полная анонимная функция (x$1) => x$1.toString типа A <: Any => String, а Exception ожидает String.

В случае println _ сам по себе не имеет синтаксической категории Expr, но (println (_)) есть, поэтому вы получаете ожидаемый (x$0) => println(x$0).

Ответ 2

Разница заключается в том, означает ли _ весь параметр или является частью выражения. В зависимости от того, он попадает в одну из двух следующих категорий:

Частично примененная функция

Seq(fromDir, toDir) find (!_.isDirectory) foreach (println(_))

означает

Seq(fromDir, toDir) find (!_.isDirectory) foreach ((x$1) => println(x$1))

Анонимный функциональный параметр

Seq(fromDir, toDir) find (!_.isDirectory) foreach (throw new Exception(_.toString))

означает

Seq(fromDir, toDir) find (!_.isDirectory) foreach (throw new Exception((x$1) => x$1.toString))