admin管理员组文章数量:1026989
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
2 Answers
Reset to default 10A 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.
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
2 Answers
Reset to default 10A 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.
本文标签: javascriptWhat is the different between curry and partial function in RamdaStack Overflow
版权声明:本文标题:javascript - What is the different between curry and partial function in Ramda? - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745526715a2154558.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论