reducee, applyé claro, são apenas equivalentes (em termos do resultado final retornado) às funções associativas que precisam ver todos os seus argumentos no caso de variável-aridade. Quando eles são equivalentes em termos de resultados, eu diria que applyé sempre perfeitamente idiomático, enquanto reduceé equivalente - e pode raspar uma fração de um piscar de olhos - em muitos casos comuns. O que se segue é minha justificativa para acreditar nisso.
+é implementado em termos de reducepara o caso de variável-arity (mais de 2 argumentos). De fato, esse parece ser um caminho "padrão" imensamente sensato para qualquer função associativa de aridade variável: reducetem o potencial de realizar algumas otimizações para acelerar as coisas - talvez através de algo como internal-reduceuma novidade 1.2 recentemente desativada no master, mas espera-se que seja reintroduzido no futuro - o que seria bobagem replicar em todas as funções que possam se beneficiar delas no caso vararg. Nesses casos comuns, applybasta adicionar um pouco de sobrecarga. (Observe que não é nada para se preocupar.)
Por outro lado, uma função complexa pode tirar proveito de algumas oportunidades de otimização que não são gerais o suficiente para serem incorporadas reduce; então applyvocê pode tirar vantagem disso enquanto reducepode realmente atrasá-lo. Um bom exemplo do último cenário que ocorre na prática é fornecido por str: ele usa um StringBuilderinternamente e se beneficiará significativamente do uso de applye não reduce.
Então, eu diria que use applyquando estiver em dúvida; e se você souber que isso não está comprando nada para você reduce(e que é improvável que isso mude muito em breve), fique à vontade reducepara cortar essa sobrecarga desnecessária e diminuta, se você quiser.
sumfunção interna como no haskell? Parece uma operação bastante comum.