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? Похоже на довольно распространенную операцию.