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

Scala неявно против неявных аргументов

Я новичок в Scala, и когда я смотрю на разные проекты, я вижу два стиля для работы с неявными аргументами

scala]]>def sum[A](xs:List[A])(implicit m:Monoid[A]): A = xs.foldLeft(m.mzero)(m.mappend)
sum:[A](xs:List[A])(implicit m:Monoid[A])A

и

scala]]>def sum[A:Monoid](xs:List[A]): A ={
     val m = implicitly[Monoid[A]]
     xs.foldLeft(m.mzero)(m.mappend)
   }
sum:[A](xs:List[A])(implicit evidence$1:Monoid[A])A

В зависимости от типа обеих функций они совпадают. Есть ли разница между этими двумя? Почему вы хотите неявно использовать неявные аргументы? В этом простом примере он выглядит более подробным.

Когда я запускаю вышеуказанное в REPL с чем-то, у которого нет неявного, я получаю следующие ошибки

с неявным параметром

<console>:11: error: could not find implicit value for parameter m: Monoid[String]

и

с неявным образом и a: Monoid

<console>:11: error: could not find implicit value for evidence parameter of type Monoid[String]
4b9b3361

Ответ 1

В некоторых случаях неявный формальный параметр напрямую не используется в теле метода, который принимает его как аргумент. Скорее, он просто становится неявным значением val, которое передается другому методу, который требует неявного параметра того же (или совместимого) типа. В этом случае, не имея открытого списка неявных параметров, удобно.

В других случаях привязка к контексту, которая является строго синтаксическим сахаром для открытого неявного параметра, считается эстетически желательной и даже несмотря на то, что фактический параметр необходим, и, следовательно, метод implicitly должен использоваться для его получения предпочтительнее.

Учитывая, что между ними нет семантической разницы, выбор основывается на довольно субъективных критериях.

Сделайте то, что вам нравится. Наконец, обратите внимание, что переход от одного к другому не приведет к нарушению какого-либо кода и не потребует перекомпиляции (хотя я не знаю, является ли SBT достаточно дискриминационным, чтобы отказаться от повторного компиляции кода, который может видеть измененное определение).