Confused о Scala методах вызова метода, в частности, о функции sum на Seq

Я играл с новой Scala IDE (Eclipse 3.6.2 + Scala IDE 2.0.0 [Scala 2.9.0]), и я попытался сделать что-то простое:

(1 to 10).sum

Это отлично работает, но я недавно делал много Groovy, и я автоматически писал:

(1 to 10).sum()

Эта вторая версия дает мне ошибку компилятора в среде IDE со следующим сообщением:

недостаточно аргументов для суммы метода: (неявное число: числовое [B]) B. Неопределенный параметр значения параметра

В API Scala я вижу, что существует две версии sum, одна из которых не принимает никаких параметров, а другая - неявно. Нужно ли мне приводить методы без аргументов без круглых скобок?

Ответы

Ответ 1

Ответ заключается в том, что , если вы указываете список параметров (т.е. используете parens), , а вы должны указать параметры в нем ( или, точнее, те, которые не имеют значений по умолчанию).

Если вы опускаете парсеры в непустом списке параметров, параметры которого implicit, то компилятор может их ввести для вас (предполагая, что он может найти соответствующие импликации в вашей области: как в первом примере)

1 to 10 sum

Если вы хотите передать параметр самостоятельно (в этом примере нет необходимости делать это), тогда вы можете воспользоваться Predef.implicitly, который в основном возвращает неявное внутри неявное значение (при условии, что оно есть), Их использование здесь будет:

(1 to 10).sum(implicitly[Numeric[Int]])
(1 to 10).sum[Int](implicitly)

Это особенно важно в методах, которые принимают более одного неявного параметра, из которых вы можете только его переопределить (вы можете использовать implicitly для остальных). Например, в scalaz

aFoldable.sum(implicitly, myMonoid) //uses implicit Foldable but bespoke monoid

Для вашего вопроса о сценарии использования scaladoc; это запись phantom, чтобы показать вам, как использовать (иначе потенциально запутывающий) метод с неявным списком параметров. Существование этой записи в виде скалядока можно отнести к этому печально известному вопросу.

Ответ 2

Существует только одна версия. Если вы внимательно изучите API, запись, в которой нет скобок, говорит "[use case]" в начале. Это синтетическая двойная запись в документах API, которая упрощает захват; записи в прецедентах в основном сводятся к полной записи для некоторых распространенных сценариев. Подробнее об этом в этом вопросе: Scaladoc [use case]

Причина неудачи второго вызова (... sum()) заключается в том, что хотя аргумент неявный, он не имеет значения по умолчанию. Вы можете только пропустить аргументы в круглых скобках, если указаны значения по умолчанию. Хотя это звучит нелогично, неявные аргументы обрабатываются по-разному: либо вы предоставляете их явно, то вам нужно использовать круглые скобки, или вы их опускаете (потому что имплицитный найден в области), но тогда вам также нужно отбросить круглые скобки. Это должно облегчить читаемость, например.

def test(fun: Int => Int)(implicit s: String)

теперь вы можете написать test { i => i }, а не test(i => i)(), что неудобно.