我对函数式编程和ramda.js这样的库比较陌生,但我觉得非常有用的一件事就是可以理解函数。
使用curried函数我经常写下以下内容
const myFun = R.curry(
(arg1, arg2) => {
let calculated = anotherFun(arg1)
//do something with calculated and arg2
return calculated * 5 + arg2
}
)
const anotherFun = (arg) => {
console.log("calling anotherFun");
return arg + 1
}
var partial = myFun(1)
console.log(partial(2))
console.log(partial(3))
<script src="//cdn.jsdelivr.net/ramda/0.22.1/ramda.min.js"></script>
但显然在这种情况下anotherFun
每次拨打partial
时都会被呼叫,即使在arg1
中也是如此,因此calculated
始终是相同的。
有没有办法优化此行为并仅在其args更改时调用anotherFun
?
我想到的唯一方法就是这个
const myFun = R.curry(
(calculated, arg2) => {
return calculated * 5 + arg2
}
)
const anotherFun = (arg) => {
console.log("calling anotherFun");
return arg + 1
}
var calculated = anotherFun(1)
var partial = myFun(calculated)
console.log(partial(2))
console.log(partial(3))
<script src="//cdn.jsdelivr.net/ramda/0.22.1/ramda.min.js"></script>
但是这样我必须更改传递给myFun的参数,这会使外部API复杂化
答案 0 :(得分:3)
如果您像这样手动进行晃动
const myFun = arg1 => arg2 => {
let calculated = anotherFun(arg1)
// do something with calculated and arg2
return calculated * 5 + arg2
};
您也可以进行此优化:
const myFun = arg1 => {
let calculated = anotherFun(arg1);
return arg2 => {
// do something with calculated and arg2
return calculated * 5 + arg2
};
};
我不认为拉姆达会在这里帮助你;并且JavaScript编译器当然不会进行这种优化。
答案 1 :(得分:1)
@Bergi是对的,Ramda不会为你提供任何帮助。如果你想要一个Ramda风格的结果,你可以用一个参数来调用函数来获取函数,或者两者都可以得到结果,你可以这样做:
const myFun = function(arg1, arg2) {
let calculated = anotherFun(arg1);
const newFunc = arg2 => {
return calculated * 5 + arg2
};
return (arguments.length < 2) ? newFunc : newFunc(arg2);
};
const with3 = myFun(3);
//: calling anotherFun
with3(1); //=> 21
with3(2); //=> 22
with3(4); //=> 23
myFun(2, 7);
//: calling anotherFun
//=> 22
myFun(2, 8);
//: calling anotherFun
//=> 23
这是以无法使用ES2015箭头功能为代价的。但它对你来说可能是值得的。
如果提供了两个参数,如果这对您很重要,您也可以稍微重做这一点,以便不构建内部函数。
答案 2 :(得分:0)
Ramda的useWith
和memoize
怎么样?
const myFun = R.useWith(
(a, b) => a * 5 + b,
[R.memoize(anotherFun), R.identity]
);