背景:
组合将两个函数放在一起形成第三个函数,其中一个函数的输出是另一个函数的输入。
无论我看多少,我都在努力阅读它。特别是为什么compose()
返回=> (a) =>
会捕获本地范围内的121.2121212
。此外,我还在努力研究最终fn f(g(a))
如何看待所有使用变量的值/ fn。
问题:有没有人有快速阅读此类示例的技术或图表;如何进行心理调试并遵循功能流程?
const compose = (f, g) => (a) => f(g(a)) // Definition
const floorAndToString = compose((val) => val.toString(), Math.floor) // Usage
floorAndToString(121.212121) // '121'
答案 0 :(得分:3)
正如T.J.克劳德,它经常帮助重写箭头功能作为常规功能。所以功能:
const compose = (f, g) => (a) => f(g(a))
可以改写为:
function compose (f, g) {
return function (a) {
return f(g(a));
}
}
现在可能更明显的是发生了什么。所以现在让我们改写其他部分:
const floorAndToString = compose((val) => val.toString(), Math.floor)
可以改写为:
function convertToString (val) { return val.toString() };
const floorAndToString = compose(convertToString, Math.floor);
现在可能更明显的是compose
函数将返回函数:
// remember that we pass `convertToString` as `f`
// and `Math.floor` as `g`:
function (a) {
return convertToString(Math.floor(a));
}
很明显,函数floorAndToString
只返回convertToString(Math.floor(a))
的结果。 compose
捕获121.2121212
没有什么特别之处,因为它没有。相反,它创建了一个函数,其中121.2121212
可以作为参数传递给convertToString(Math.floor(a))
。
答案 1 :(得分:2)
查看function composition的维基百科文章可能会有所帮助。但我认为你的问题与功能组成并没有关系,而是与箭头符号有关。
首先看一个更简单的例子可能会有所帮助:
const addOne = (x) => x + 1
const addN = (n) => (x) => x + n
const addSeven = addN(7)
最后一行产生一个新函数,它为输入(x) => x + 7
增加了7。您可以将箭头之间的参数元组视为在提供值时从左向右填充(并且右侧的变量与这些值绑定)。只要您不提供所有参数,您将获得新功能。
您还可以提供以下所有参数:
addN(5)(3) // yields 8
请注意,addN可以看作是两个参数,但是在单独的括号对中。定义类型中括号之间的箭头允许您省略右侧的参数并获得具有较少参数的函数,其中左侧的参数已经修复。
让我们看一下compose的替代定义:
const weirdCompose = (f, g, a) => f(g(a))
应该清楚它是如何工作的,但问题是你不能使用它来组合两个函数而不用立即用值a
来评估合成的结果。通过将参数分成两组,您可以partially apply使用该功能,并且只在第一步中提供f
和g
。
为了更好地理解这一点,我建议你也看一下currying
的概念