答案 0 :(得分:9)
来自更广泛的FP社区的许多答案可能会引导你一点点错误。在我看来,Ramda的讨论将ML风格的语言融入Javascript,但并不完全相同。
部分申请可能在Ramda中相当标准。 (免责声明:我是Ramda的一位作者。)它也更容易描述。 Ramda的">"
函数接受partial
参数的函数和n
参数列表(对于某些k
),并返回{{1}的新函数使用新参数和原始参数调用原始函数的参数:
0 < k < n
返回的函数只是其余参数的一个简单函数。如果你用太少的东西来调用它,它就好像你用太少的东西调用原始函数一样。
Currying是一个略有不同的故事。在many languages中,n - k
函数会将const f = (a, b, c, d, e) => a + b + c + d + e;
// f :: a -> b -> c -> d -> e -> a + b + c + d + e
const g = partial(f, [1, 2]);
g.length; //=> 3
g(3, 4, 5); //=> 15
g(3); //=> NaN ≍ 1 + 2 + 3 + undefined + undefined)
// g :: (c, d, e) -> 1 + 2 + c + d + e
参数的函数转换为嵌套的1参数函数序列,以便curry
转换为n
,这可以写成(a, b, c) => f(a, b, c)
而不会混淆。在Ramda中,我们更灵活一点,允许您在一次调用时提供尽可能多的参数,每次返回一个函数,直到您提供了足够的总参数来满足原始函数,此时我们调用它并返回该值。用例子解释可能更容易:
a => (b => (c => f(a, b, c))
由于a => b => c => f(a, b, c)
更加灵活,我自己很少使用const f = (a, b, c, d, e) => a + b + c + d + e;
// f :: a -> b -> c -> d -> e -> a + b + c + d + e
const h5 = curry(f);
h5.length; //=> 5
const h3 = h5(1, 2);
h3.length; //=> 3
h3(3, 4, 5); //=> 15
const h2a = h3(3);
h2a.length; //=> 2
h2a(4, 5); //=> 15
const h2b = h5(1, 2, 3);
h2b.length; //=> 2
h2b(4, 5); //=> 15
const h2c = h5(1)(2, 3);
h2c.length; //=> 2
h2c(4, 5); //=> 15
const h2d = h5(1)(2)(3);
h2d.length; //=> 2
h2d(4, 5); //=> 15
const h1a = h3(3, 4);
h1a.length; //=> 1
h1a(5); //=> 15
const h1b = h2a(4);
h1b.length; //=> 1
h1b(5); //=> 15
// h5 :: (a, b, c, d, e) -> a + b + c + d + e
// :: (a, b, c, d) -> e -> a + b + c + d + e
// :: (a, b, c) -> (d, e) -> a + b + c + d + e
// :: (a, b, c) -> d -> e -> a + b + c + d + e
// :: (a, b) -> (c, d, e) -> a + b + c + d + e
// :: (a, b) -> (c, d) -> e -> a + b + c + d + e
// :: (a, b) -> c -> (d, e) -> a + b + c + d + e
// :: (a, b) -> c -> d -> e -> a + b + c + d + e
// :: a -> (b, c, d, e) -> a + b + c + d + e
// :: a -> (b, c, d) -> e -> a + b + c + d + e
// :: a -> (b, c) -> (d, e) -> a + b + c + d + e
// :: a -> (b, c) -> d -> e -> a + b + c + d + e
// :: a -> b -> (c, d, e) -> a + b + c + d + e
// :: a -> b -> (c, d) -> e -> a + b + c + d + e
// :: a -> b -> c -> (d, e) -> a + b + c + d + e
// :: a -> b -> c -> d -> e -> a + b + c + d + e
。但有些人是,嗯,部分。
答案 1 :(得分:-2)
正如您简要提到的,curry
函数可以使用带有n个参数的函数,并使用一个参数返回n个函数。 Currying是将函数组合成高阶函数的重要工具。
功能的部分应用是一种currying。事实上,如果你研究一下Ramda source code,你会发现使用咖喱函数实现了partial
函数。
var _arity = require('./_arity');
var _curry2 = require('./_curry2');
module.exports = function _createPartialApplicator(concat) {
return _curry2(function(fn, args) {
return _arity(Math.max(0, fn.length - args.length), function() {
return fn.apply(this, concat(args, arguments));
});
});
};
另外,请查看this question从根本上解释不同的内容。