拉姆达的咖喱和部分功能有什么不同?

时间:2016-12-12 06:38:15

标签: javascript functional-programming ramda.js

似乎currypartial函数完全相同。 (也许唯一的区别是参数的数量)

是否只是为了方便,或者有充分的理由让两个函数做类似的事情。

2 个答案:

答案 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从根本上解释不同的内容。