如何指定柯里化参数应用的顺序

How can I specify the order of curried parameter application

我正在尝试将以下内容转换为 pointfree 样式:一个在传入要迭代的集合之前将值部分应用到转换器函数 add 的函数。 (使用 Ramda.js)

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

问题是 R.addR.map 一样都是 2 元数。我希望申请顺序如下:

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>

有人知道指定此行为的方法吗?

普通的 composepipe 不会这样做,因为它们都将吸收提供给第一个函数的所有参数。 Ramda 包括两个额外的函数来帮助解决这个问题,converge and useWith。在这种情况下,useWith 会有所帮助:

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

虽然 identity 在这里不是绝对必需的,但它为生成的函数提供了正确的数量。

想通了。如果有人好奇,这里是要点。 (您可以在 RamdaJS.com 的控制台中尝试它。)

0) 对于基线,这里是指向的版本。

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

1) 这里是pointfree核心,但是它有上面问题的排序问题。

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])