来自更广泛的 FP 社区的许多答案可能会让您有些误会。在我看来,Ramda 的柯里化将 ML 风格语言的柯里化精神带到了 Javascript 中,但并不完全相同。
部分应用程序在 Ramda 中可能是相当标准的。 (免责声明:我是 Ramda 的作者之一。)它也更容易描述。 Ramda 的partial 函数接受n 参数的函数和k 参数列表(对于某些0 < k < n),并返回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
返回的函数只是剩余参数的简单函数。如果你用太少调用它,它会像你用太少调用原始函数一样。
柯里化是一个稍微不同的故事。在many languages 中,curry 函数会将n 参数的函数转换为1 参数函数的嵌套序列,因此(a, b, c) => f(a, b, c) 转换为a => (b => (c => f(a, b, c)),可以毫无混淆地写为a => b => c => f(a, b, c) .在 Ramda 中,我们更灵活一点,允许您在一次调用中提供尽可能多的参数,每次都返回一个函数,直到您提供了足够的总参数来满足原始函数,此时我们调用它并返回该值。用例子可能更容易解释:
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
因为curry 灵活得多,所以我自己很少使用partial。但是有些人,咳咳,偏向。