Ramda curry / uncurry问题与ES6默认参数语法

时间:2017-06-13 15:55:14

标签: javascript ecmascript-6 default-value ramda.js

在下面的示例中,当存在默认参数时,我无法使用Ramda.js uncurry函数处理ES6箭头函数:

const tt = (x) => y => x + y;
const tt1 = (x = 5) => y => x + y;
const uncurry = R.uncurryN(2);

console.log( uncurry(tt)(1,2)  );
console.log( uncurry(tt1)(1,2) );

除默认参数外,两个函数tttt1应该相同。但是输出是不同的(babel-node 6.24.1):

3
6

似乎默认语法被视为具有uncurrying的赋值。

我在这里遗漏了什么吗?这是故意还是错误?

只是为了澄清:

没有curry / uncurry,两个函数(有或没有默认值)在完全提供参数时的行为方式相同。 tt(1)(2)tt1(1)(2)都评估为3。更改调用约定后,为什么行为会有所不同?

顺便说一下,我正在关注一些react / redux示例(es6 how to use default parameters that go before non-default parameters?)并测试是否可以将一些react函数调用转换为Ramda样式。这里讨论的问题显然是一个障碍。

1 个答案:

答案 0 :(得分:1)

虽然这不是精确的预期,但很难看到真正有用的解决方案。

错误在实施中的this line中:

      endIdx = currentDepth === depth ? arguments.length : idx + value.length;

如果替换为

      endIdx = currentDepth === depth ? arguments.length : idx + 1;

你的两个功能会一样。那将破坏这种用法:

const tt2 = (x, y) => (z) => x + y + z;
uncurry(tt2)(1, 2, 3); //=> NaN

(使用当前实现,这将正确返回6。)

这可能不是那么重要。尝试将uncurryN用于未完全curry的函数似乎是一件奇怪的事。

但总的来说,我不知道这会有所帮助。默认参数可能难以使用。具有默认值的参数不会影响函数length

  

length是函数对象的属性,表示函数期望的参数数量,即形式参数的数量。此数字不包括rest参数,仅包含具有默认值的第一个参数之前的参数。 - MDN

默认值不可供装饰器函数使用,因此uncurryN之类的内容将丢失默认值。并且使用默认值后的任何参数都会很麻烦。

当然,你仍然可以这样做:

((x, y) => tt1(x)(y))(1, 2); //=> 3
((x, y) => tt1(x)(y))(undefined, 2); //=> 7

传递给undefined的{​​{1}}也会有用。但是通过一个明确的uncurry(tt1)感觉有点奇怪。

欢迎raise an issue让Ramda讨论这个问题。

您可以在 Ramda REPL 上播放这些想法。