2016-12-07 92 views
0

我對函數式編程和庫如ramda.js比較陌生,但有一點我覺得非常有用的是咖喱函數的可能性。咖喱功能:如何優化它們

使用咖喱功能我寫的很經常的事情,如下

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時間總是一樣的。

有沒有一種方法可以優化這種行爲,並且只有在其參數改變時才調用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複雜

回答

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

我不認爲Ramda將幫助你在這裏任何事情;和JavaScript編譯器當然不會做這種優化。

1

@Bergi是正確的,拉姆達不會爲您提供任何幫助。如果你想要一個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箭頭功能。但它可能是值得的。

如果同時提供了兩個參數(如果這對您很重要),您也可以稍微修改它以不構建內部函數。

0

怎麼樣來自Ramda的useWithmemoize

const myFun = R.useWith(
    (a, b) => a * 5 + b, 
    [R.memoize(anotherFun), R.identity] 
);