2017-06-13 76 views
1

在下面的例子中,我不能让Ramda.js uncurry功能与ES6箭头功能工作时,默认的参数存在:Ramda咖喱/ 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应该与默认参数相同。但输出是不同的(巴贝尔节点6.24.1):

3 
6 

似乎默认的语法被视为与uncurrying的分配。

我在这里错过了什么吗?这是打算还是一个错误?


只是为了澄清:

没有咖喱/ uncurry,这两个函数(具有或不具有默认值),当行为参数被充分供给的相同的方式。 tt(1)(2)tt1(1)(2)都评估为3。为什么改变调用约定后行为会有所不同?

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

+0

这似乎相关,因为uncurryN需要手动curried功能https://github.com/ramda/ramda/issues/1837 – AnthonyJClink

+1

@AnthonyJClink:这些功能** **手动curried。 Ramda讨论的要点是,这对于像((x,y)=> x + y'或'R.curry((x,y)=> x + y)''不适用。 –

回答

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来完成未充分调试的功能似乎很奇怪。

但总的来说,我不知道这有助于。默认参数可能很难处理。有默认的参数不利于功能的length

length是一个函数对象的属性,并表示该功能多少个参数预期,即正式参数的数量。该数字不包括其余参数,并且仅包含具有默认值的第一个参数之前的参数。 - MDN

的默认值是不可用的装饰功能,所以像uncurryN将失去的默认值。而且,在使用默认值之后的任何参数后,它会变得很尴尬。

你仍然可以做到这一点,当然:

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

,并传递给uncurry(tt1)会工作,以及一个undefined。但通过一个明确的undefined感觉有点奇怪。

请随时致电raise an issue以获得Ramda的意见。

你可以玩这些想法在Ramda REPL

+0

'idx + Math.min(1,value.length)'也许?但是,这基本上是无法解决的。最好不要使用默认参数,而应该明确地说'tt1 = tt(5)' – Bergi

+0

@Bergi:同意。我起初发现默认参数无非是麻烦。但它们对于递归函数非常有用。 'function fact(n,acc = 1){return n <2? acc:fact(n-1,acc * n)}'是为TCO准备的arity-1函数,不需要辅助函数。但我对违约参数的看法仍然是混合不清的。 –

+0

特别是在那些情况下,我总是使用帮助函数 - 当意外地使用更多参数(例如数组'map')时,它不值得麻烦 – Bergi