https://ramdajs.com/docs/#curry
接受一个函数
( → a) → ( → a)
Parameters
Added in v0.1.0
Returns a curried equivalent of the provided function. The curried function has two unusual capabilities. First, its arguments needn’t be provided one at a time. If f is a ternary function and g is R.curry(f), the following are equivalent:
- g(1)(2)(3)
- g(1)(2, 3)
- g(1, 2)(3)
- g(1, 2, 3)
Secondly, the special placeholder value R.__ may be used to specify “gaps”, allowing partial application of any combination of arguments, regardless of their positions. If g is as above and is [R._](https://ramdajs.com/docs/#), the following are equivalent:
- g(1, 2, 3)
- g(_, 2, 3)(1)
- g(, , 3)(1)(2)
- g(, , 3)(1, 2)
- g(_, 2)(1)(3)
- g(_, 2)(1, 3)
g(, 2)(, 3)(1)
See also curryN, partial. ```javascript const addFourNumbers = (a, b, c, d) => a + b + c + d;
const curriedAddFourNumbers = R.curry(addFourNumbers); const f = curriedAddFourNumbers(1, 2); const g = f(3); g(4); //=> 10
<a name="fwbK2"></a># 提高了代码重用性I hope the last section gave you a taste of currying, as we’re dipping a bit more into it here.<br />Its main benefit is code reuse. Curried functions have a better chance of being useful in different scenarios, thus making them [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)er.<br />Let’s say you have an add function```javascriptconst add = (x, y) => {console.log(`Adding ${x} and ${y}`);return x + y;};const result = add(2, 3);console.log({ result });
What happens if you don’t give add its required parameters? What if you give too little?
const add = (x, y) => {console.log(`Adding ${x} and ${y}`);return x + y;};const result = add(2);console.log({ result });Adding 2 and undefined{ result: NaN }
Not fun. You know this leads to weird bugs, especially in JavaScript where we do anything and everything. The problem sort of goes away when you curry add.
import { curry } from 'ramda';const add = (x, y) => {console.log(`Adding ${x} and ${y}`);return x + y;};const curriedAdd = curry(add);// returns a functionconst result = curriedAdd(2);console.log({ result });//{ result: [Function] }
Your eyes don’t deceive you, curriedAdd(2) returns a function. It will keep returning a function until you supply the last parameter, y.
import { curry } from 'ramda';const add = (x, y) => {console.log(`Adding ${x} and ${y}`);return x + y;};const curriedAdd = curry(add);const result = curriedAdd(2);console.log(result(),result(),result());console.log("I won't stop returning functions until you give me Y! \n")console.log("Okay dude, here's y = 3...\n");console.log(result(3));console.log('\n-_-"')
[Function] [Function] [Function]I won't stop returning functions until you give me Y!Okay dude, here's y = 3...Adding 2 and 35-_-"
传参可选—而不是一定要一个一个传
According to the FP books, currying means you return one new function per expected parameter.
So if you have an add3 or greet function
const add3 = (x, y, z) => x + y + z;const greet = (greeting, first, last) => `${greeting}, ${first} ${last}`;
“Properly” currying them looks like this
const curriedAdd3 = (x) => (y) => (z) => x + y + z;const curriedGreet = (greeting) => (first) => (last) => `${greeting}, ${first} ${last}`;
But let’s be honest, this sucks in JavaScript. I don’t want to call my functions like this
curriedAdd3(1)(2)(3); // 6curriedGreet('Hello')('John')('Doe'); // Hello, John Doe
Thankfully Ramda’s curry supports either style. You can use them like above or give all the arguments at once.
import { curry } from 'ramda';const greet = (greeting, first, last) => `${greeting}, ${first} ${last}`;const curriedGreet = curry(greet);// Supply all arguments at onceconst result1 = curriedGreet('Hello', 'John', 'Doe');// Or break it upconst result2 = curriedGreet('Hello')('John')('Doe');// Get weird if you wantconst result3 = curriedGreet('Hello')()()()('John', 'Doe');// Store curried function as variableconst greetJohn = curriedGreet('Hello', 'John')const result4 = greetJohn('Smith');console.log({result1,result2,result3,result4});/**{ result1: 'Hello, John Doe',result2: 'Hello, John Doe',result3: 'Hello, John Doe',result4: 'Hello, John Smith' }**/
总结
- Curried functions keep returning functions until all required parameters are given.
- This lets you partially apply a function and create more specialized versions.
- “Properly” curried functions return one function per argument. (a) => (b) => (c) instead of (a, b, c).
- But they’re a bit impractical so Ramda lets you supply them normally, or one at a time.
普通函数转为柯里化函数
Create a function called defaultTo. It takes two parameters:
- defaultVal: A default value
- val: The value to return
If val is null or undefined, return defaultVal.
Else, return val.
Curry it to allow preloading arguments.
import { curry } from 'ramda';const defaultTo =curry((defaultVal, val) => val == null ? defaultVal : val);
