使用 Ramda 进行函数式编程:你能柯里化一个接受无限数量参数的函数吗
Functional Programming with Ramda: Can you curry a function that takes unlimited number of arguments
假设我有 3 个数组
var first = [0, 1, 2, 3];
var second = [0, 1, 2, 3];
var third = [0, 1, 2, 3];
我想制作一个咖喱函数,我在其中设置第一个参数,指示我想在作为参数传递的数组中添加哪个单元格...理想情况下,我希望该函数能够接受无限数量的数组....
例如:
mycurriedfunction(1)
意味着我想访问我传入的数组的单元格 1 中的值并将它们相加。
因此做:
mycurriedfunction(1)(first)
会 return 1
mycurriedfunction(1)(first)(second)
会 return 2
mycurriedfunction(2)(first)(second)(third)
会 return 6
这可能吗?
如果不是,那么有哪些替代方案可以实现类似甚至相同的结果?
不,一个值不可能既是数字又是函数。
您应该让您的函数采用列表代替,或者被表述为缩减器。
正如其他人所提到的,您描述的函数无法知道 return 下一个要调用的函数还是最终值。
如果你真的想实现类似的东西,接受无限数量的数组,你可以稍微调整一下,将累加值存储为 属性 的 returned 函数。
function sumIdx(idx) {
function f(value) {
function g(arr) {
return f(value + arr[idx]);
}
g.value = value;
return g;
}
return f(0);
}
这可以像您的示例一样使用,不同之处在于您需要在完成后从 value
属性 中提取结果。
const first = [0, 1, 2];
const second = [3, 4, 5];
const third = [6, 7, 8];
sumIdx(2)(first)(second)(third).value // 15
虽然可能,但我可能不建议使用这种方法。也许使用单独的数据类型会更好地表示这种行为(或者按照 Scott Sauyet 向 myFn(2, [first, second, third])
建议的那样更改 API)。
class SumIdx {
constructor(idx, value) {
this.idx = idx;
this.value = value;
}
next(arr) {
return new SumIdx(this.idx, this.value + arr[this.idx]);
}
}
const sumIdx = idx => new SumIdx(idx, 0);
这里的区别是需要调用next
方法而不是直接调用结果
sumIdx(2).next(first).next(second).next(third).value // 15
假设我有 3 个数组
var first = [0, 1, 2, 3];
var second = [0, 1, 2, 3];
var third = [0, 1, 2, 3];
我想制作一个咖喱函数,我在其中设置第一个参数,指示我想在作为参数传递的数组中添加哪个单元格...理想情况下,我希望该函数能够接受无限数量的数组....
例如:
mycurriedfunction(1)
意味着我想访问我传入的数组的单元格 1 中的值并将它们相加。
因此做:
mycurriedfunction(1)(first)
会 return 1
mycurriedfunction(1)(first)(second)
会 return 2
mycurriedfunction(2)(first)(second)(third)
会 return 6
这可能吗?
如果不是,那么有哪些替代方案可以实现类似甚至相同的结果?
不,一个值不可能既是数字又是函数。
您应该让您的函数采用列表代替,或者被表述为缩减器。
正如其他人所提到的,您描述的函数无法知道 return 下一个要调用的函数还是最终值。
如果你真的想实现类似的东西,接受无限数量的数组,你可以稍微调整一下,将累加值存储为 属性 的 returned 函数。
function sumIdx(idx) {
function f(value) {
function g(arr) {
return f(value + arr[idx]);
}
g.value = value;
return g;
}
return f(0);
}
这可以像您的示例一样使用,不同之处在于您需要在完成后从 value
属性 中提取结果。
const first = [0, 1, 2];
const second = [3, 4, 5];
const third = [6, 7, 8];
sumIdx(2)(first)(second)(third).value // 15
虽然可能,但我可能不建议使用这种方法。也许使用单独的数据类型会更好地表示这种行为(或者按照 Scott Sauyet 向 myFn(2, [first, second, third])
建议的那样更改 API)。
class SumIdx {
constructor(idx, value) {
this.idx = idx;
this.value = value;
}
next(arr) {
return new SumIdx(this.idx, this.value + arr[this.idx]);
}
}
const sumIdx = idx => new SumIdx(idx, 0);
这里的区别是需要调用next
方法而不是直接调用结果
sumIdx(2).next(first).next(second).next(third).value // 15