如何指定curried参数应用程序的顺序

时间:2016-05-21 02:49:10

标签: functional-programming composition currying ramda.js

我试图将以下内容转换为无点样式:在传递要迭代的集合之前,将一个值部分地应用于变换器函数add的函数。 (使用Ramda.js)

R.compose(
  R.map,
  R.add
)(1, [1,2,3])

问题是R.add是arity 2,R.map也是如此。我希望应用程序顺序如下:

add(1)
map(add(1))
map(add(1), [1,2,3])
[add(1,1), add(1,2), add(1,3)]

但是会发生什么呢:

add(1, [1,2,3])
map(add(1, [1,2,3]))
<partially applied map, waiting for collection>

有人知道指明这种行为的方法吗?

2 个答案:

答案 0 :(得分:2)

普通composepipe不会这样做,因为它们会吸收提供给第一个函数的所有参数。 Ramda包含两个有助于此功能的附加功能,convergeuseWith。在这种情况下,useWith是有帮助的:

useWith(map, [add, identity])(1, [1, 2, 3]); //=> [2, 3, 4]

虽然此处并非绝对需要identity,但它会为生成的函数提供正确的arity。

答案 1 :(得分:2)

想出来。如果有人好奇,这就是要点。 (您可以在RamdaJS.com的控制台中试用它。)

0)对于基线,这里是尖头版本。

func0 = x => R.map(R.add(x))
addOne = func0(1)
addOne([1,2,3]) // [2,3,4]

1)这里是无点核心,但它有上述问题的排序问题。

func1 = R.compose(R.map, R.add)
addOne = func1(1)
addOne([1,2,3]) // [2,3,4])
func1(1, [1,2,3]) // function

2)如果构图是unary(arity 1),则需要2次调用。

func2 = R.unary(R.compose(R.map, R.add))
addOne = func2(1)
addOne([1,2,3]) // [2,3,4])

3)我们希望一次调用同时应用两个参数,所以我们uncurry 2。

func3 = R.uncurryN(2, func2)
func3(1, [1,2,3]) // [2,3,4])

4)为了证明func2是可组合的,让结果加倍。

func4 = R.compose(
  R.map(R.multiply(2)), 
  R.uncurryN(2, func2)
)
func4(1, [1,2,3]) // [4,6,8])

5)替换为我们提供了完全无点的功能。

func5 = R.compose(
  R.map(R.multiply(2)),
  R.uncurryN(2, R.unary(R.compose(
    R.map,
    R.add
  )))
)
func5(1, [1,2,3]) // [4,6,8])