【发布时间】:2020-05-13 16:39:33
【问题描述】:
我正在尝试了解函数式编程的概念和基础知识。我不会硬核 Haskell、Clojure 或 Scala。相反,我使用的是 JavaScript。
所以,如果我理解正确的话,函数式编程背后的想法是使用纯函数编写软件应用程序——它负责处理应用程序中的单一职责/功能,而不会产生任何副作用。
组合以这样一种方式进行,即一个函数的输出作为输入传递给另一个函数(根据逻辑)。
我分别编写了 2 个函数用于加倍和递增,它们以整数作为参数。后跟一个实用函数,该函数组成作为参数传入的函数。
{
// doubles the input
const double = x => x * 2
// increments the input
const increment = x => x + 1
// composes the functions
const compose = (...fns) => x => fns.reduceRight((x, f) => f(x), x)
// input of interest
const arr = [2,3,4,5,6]
// composed function
const doubleAndIncrement = compose(increment, double)
// only doubled
console.log(arr.map(double))
// only incremented
console.log(arr.map(increment))
// double and increment
console.log(arr.map(doubleAndIncrement))
}
输出如下:
[4, 6, 8, 10, 12] // double
[3, 4, 5, 6, 7] // increment
[5, 7, 9, 11, 13] // double and increment
所以,我的问题是,在这种情况下,reduceRight 函数将遍历数组两次以应用这 2 个函数。
如果数组变大了,会不会效率低下?
使用循环,它可以在一次遍历中完成,两个操作在同一个循环中。
如何防止这种情况发生,或者我的理解是否有任何错误?
【问题讨论】:
-
请注意,您可以通过在
double和increment函数中添加日志来测试情况并非如此 -
天啊!是的,你是对的......就像我完全沉浸在 FP 思维和单一责任的事情中,完全错过/忽略了这些基本的东西
-
你也缺少操作融合的概念。许多功能平台将通过仅访问每个元素一次并应用所有
mapped 操作来融合操作。这需要一些积极的优化技术,但在 GHC Haskell 编译器中实现。
标签: javascript node.js function ecmascript-6 functional-programming