reduce
и apply
, конечно, эквивалентны (с точки зрения возвращаемого конечного результата) только для ассоциативных функций, которым необходимо видеть все свои аргументы в случае переменной арности. Когда они эквивалентны по результату, я бы сказал, что apply
это всегда совершенно идиоматично, в то время reduce
как эквивалентно - и может сбрить долю секунды на мгновение - во многих общих случаях. Ниже приводится мое обоснование верить в это.
+
сам реализован в терминах reduce
для случая переменной арности (более 2 аргументов). В самом деле, это кажется чрезвычайно разумным способом "по умолчанию" для любой ассоциативной функции переменной арности: reduce
имеет потенциал для выполнения некоторых оптимизаций для ускорения работы - возможно, с помощью чего-то вроде internal-reduce
новинки 1.2, недавно отключенной в master, но надеюсь, что в будущем они будут повторно введены - что было бы глупо повторять в каждой функции, которая могла бы получить от них пользу в случае vararg. В таких распространенных случаях apply
это просто добавит немного накладных расходов. (Обратите внимание, что это не повод для беспокойства.)
С другой стороны, сложная функция может использовать преимущества некоторых возможностей оптимизации, которые недостаточно общие, чтобы быть встроенными reduce
; тогда apply
вы сможете воспользоваться ими, а на reduce
самом деле замедлить работу. Хороший пример реализации последнего сценария на практике str
: он использует для StringBuilder
внутренних целей и значительно выиграет от использования apply
вместо reduce
.
Итак, я бы сказал, используйте, apply
если сомневаетесь; и если вы знаете, что это не дает вам ничего лишнего reduce
(и что это вряд ли изменится в ближайшее время), не стесняйтесь использовать, reduce
чтобы сбрить эти крошечные ненужные накладные расходы, если вам это нравится.
sum
функцию, как в haskell? Похоже на довольно распространенную операцию.