javascript - What is the different between curry and partial function in Ramda? - Stack Overflow

It seems the curry and partial functions do the exact same thing. (Maybe the only difference is the num

It seems the curry and partial functions do the exact same thing. (Maybe the only difference is the number of arguments)

Is it just matter of convinience or there is a good reason on having two functions that do kind of similar thing.

It seems the curry and partial functions do the exact same thing. (Maybe the only difference is the number of arguments)

Is it just matter of convinience or there is a good reason on having two functions that do kind of similar thing.

Share Improve this question asked Dec 12, 2016 at 6:38 user7283346user7283346 2
  • This is almost the same question as What is the difference between currying and partial application only without ramda reference. – lonelyelk Commented Dec 12, 2016 at 10:19
  • @lonelyelk: ... but because Ramda's curry is somewhat non-standard, this might need its own answer. I'll try my own below. – Scott Sauyet Commented Dec 12, 2016 at 16:34
Add a ment  | 

2 Answers 2

Reset to default 10

A lot of answers from the wider FP munity might steer you a little wrong. Ramda's currying seems to me to carry the spirit of currying from ML-style languages into Javascript, but is not strictly the same.

Partial application is probably fairly standard in Ramda. (Disclaimer: I'm one of the Ramda authors.) It's also much easier to describe. Ramda's partial function accepts a function of n arguments and a list of k arguments (for some 0 < k < n), and returns a new function of n - k arguments that will call the original function with your new arguments and the original ones:

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

The function returned is just a simple function of the remaining parameters. If you call it with too few, it will act as though you called the original function with too few as well.

Currying is a slightly different story. In many languages, a curry function would convert a function of n parameters into a nested sequence of 1-parameter function, so that (a, b, c) => f(a, b, c) transforms into a => (b => (c => f(a, b, c)), which can be written without confusion as a => b => c => f(a, b, c). In Ramda, we are a little more flexible, allowing you to supply as many of the arguments as you choose at a single call, each time returning a function until you have supplied enough total parameters to satisfy the original function, at which point we call it and return that value. It's probably easier to explain with examples:

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

Because curry is so much more flexible, I rarely use partial myself. But there are people who are, ahem, partial to it.

As you briefly mentioned, curry function can take a function with n arguments and return n functions with one argument. Currying is an essential tool to pose functions into higher order functions.

Partial applications of functions is a type of currying. In fact, if you look into Ramda source code you'll see that the partial function was implemented using curry function.

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));
    });
  });
};

Also, take a look to this question that explain the different fundamentally.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745526717a4631503.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信