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
```javascript
const 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 function
const 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 3
5
-_-"
传参可选—而不是一定要一个一个传
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); // 6
curriedGreet('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 once
const result1 = curriedGreet('Hello', 'John', 'Doe');
// Or break it up
const result2 = curriedGreet('Hello')('John')('Doe');
// Get weird if you want
const result3 = curriedGreet('Hello')()()()('John', 'Doe');
// Store curried function as variable
const 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);