在下面的示例中,当存在默认参数时,我无法使用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) );
除默认参数外,两个函数tt
和tt1
应该相同。但是输出是不同的(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样式。这里讨论的问题显然是一个障碍。
答案 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 上播放这些想法。