Ramda:curry 如何将参数传递给占位符

Ramda: how curry pass the arguments to placeholders

我有如下代码片段可以使用 curry 和占位符

const calFourNumbers = (a, b, c, d) => a - b - c + d;

const curriedCalFourNumbers = R.curry(calFourNumbers );
const f = curriedCalFourNumbers(5, __);
const g = f(__,4);

console.log(g(1,2)) //=> result is 2

据我了解,5 -1 -2 + 4 = 6。

谁能帮我解释一下 returns 结果是 2.

我是 Ramda 新手

编辑* 正如 Scott Sauyet 解释的那样,末尾的占位符被省略了

const curriedCalFourNumbers = R.curry(calFourNumbers );
const f = curriedCalFourNumbers(5);
const g = f(__,4);

console.log(g(1,2)) // => 2
console.log (g (1,6)) //=> 6
console.log (g (1,10)) //=> 10

我知道这不是编写代码的方式,但只是尝试了解占位符在上述情况下的工作方式。任何解释表示赞赏。

f 定义末尾的占位符不执行任何操作。那里不是很明智。所以这实际上相当于 curriedCalFourNumbers (5).

但是,如果您在 gconst g = f (__, __, 4) 的开头使用了两次,那么您将得到相当于 (b, c) => calFourNumbers (5, b, c, 4):

const calFourNumbers = (a, b, c, d) => a - b - c + d;

const curriedCalFourNumbers = curry (calFourNumbers)
const f = curriedCalFourNumbers (5)
const g = f (__, __,4)

console .log (g (1, 2)) //=> result is 6
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>
<script> const {__, curry} = R </script>

更新:进一步说明

一个评论想知道更多关于为什么是这样的。首先,从技术上讲,这发生在 lines 32 - 34 of _curryN 中。 (注意:该代码中的变量left确实应该称为remaining。)我们减少了仅当当前值为而不是[=74时才需要接收的参数的数量=] 一个占位符。

从逻辑上讲,每个占位符都可以被认为是我们其中一个形式参数的非替代品。所以如果我们从这个开始:

const calFourNumbers = (a, b, c, d) => a - b - c + d)

我们可以编写一个函数 applyArgN,其工作方式如下:

const f = applyArgN (calFourNumbers, 0, 5)

这将使 f 大约 (b, c, d) => calFourNumbers (5, b, c, d) 然后

const g = applyArgN (f, 2, 4)

这将使 g 大约 (b, c) => f (b, c, 4),当然也大约 (b, c) => calFourNumbers (5, b, c, 4)

所以

g (1, 2) ~= calFourNumbers (5, 1, 2, 4)

但是我们没有让用户那样调用它,而是使用 Ramda 的扩展柯里化概念,这样当您调用

const curriedCalFourNumbers = curry (calFourNumbers)

您可以通过调用少于所需的值来简单地部分应用左侧的值。 Ramda 尝试工作,并鼓励您以一种更可能更改的参数出现在不太可能更改的参数之后的方式工作。因此,像 const f = curriedCalFourNumbers (5) 这样简单的部分应用将不太常见。但有时您确实想要部分应用不同的值。占位符所做的一切实际上就是:它在稍后将要填写的参数行中占据一席之地。因此 curriedCalFourNumbers (__, __, 2) 需要将 2 部分应用于形参 c。那当然留下了函数 (a, b, d) => curriedCalFourNumbers (a, b, 2, d).

这就是参数列表末尾的占位符毫无意义的原因。虽然 Ramda 不认为这是一个错误,但从逻辑上讲,您并没有为其他任何事情保留这个位置。我们需要上面的两个占位符,因为我们需要在将 2 应用于 c 时保留 ab 形式参数。在列表的末尾,我们不会将后续值应用于任何内容,因此它们什么都不做。

我希望这能解决问题。 (当我输入这个更新时,你说你现在明白了,但这可能会解释更多,或者对下一个提出相关问题的人有帮助。)