我有一個搜索名字的函數。這個擴展的`compose`函數有什麼好名字?
我一直在用JavaScript編寫一個new functional programming library,最近我添加了一個對我來說很有用的新函數。我將其命名爲useWith
,但我想知道它是否是功能程序員已知的一個以不同名稱命名的函數。
該功能與compose
相關,因爲它返回一個新功能,它組合了幾個現有功能,但方式與compose
略有不同。它收到的第一個參數被單獨列出;其餘部分統一處理。當調用返回的函數時,參數將分別傳遞給其餘的每個函數,並且結果以及任何不成對的參數都會發送到第一個函數,然後返回結果。因此,如果只用兩個函數調用它,並且如果傳遞的結果函數只有一個參數,這完全等同於compose。但它有多個參數的其他功能。
我想這個功能的原因是,我正在實施類似的project
功能 米哈爾Fogus在Functional Javascript介紹,Codd的project
的類似JavaScript對象的數組等價物,且類似於SQL的select
動詞。這是很容易這樣寫:
var project = curry(function(keys, table) {
return map(pick(keys), table);
});
// Used like this:
var kids = [{name: 'Bob', age: 3, eyes: 'blue', hair: 'brown'},
{name: 'Sue', age: 5, eyes: 'hazel', hair: 'blonde'}];
project(['name', 'eyes'], kids);
//=> [{name: 'Bob', eyes: 'blue'}, {name: 'Sue', eyes: 'hazel'}]
但我真的想實現它在一個無點的風格。但當然,這是行不通的:
var project = compose(map, pick); // NO!
...因爲沒有工具穿過第二個參數,table
內compose
。
這就是這個新功能進來:
var project = useWith(map, pick);
我把它比這種情況更通用,雖然。原始方法被稱爲using
,參數相反,因此它讀作一個命令:「使用選擇,映射」。但是這使得很難擴展到多個參數。我必須將第一個數組作爲一個數組,或者讓它成爲一個數組或單個函數,而我真的不想去那裏。這似乎是一個更好的解決方案。
我感覺好像我不能成爲第一個需要像這樣的功能的人。這是FP語言中的常見模式嗎?這個功能有一個共同的名字嗎?如果沒有,是否有比useWith
更好的名字?
如果你很好奇,這裏的useWith
實施,使用很明顯slice
,並且比較規範的curry
:
var useWith curry(function(fn /*, tranformers */) {
var tranformers = slice(arguments, 1);
return function() {
var args = [], idx = -1;
while (++idx < tranformers.length) {
args.push(tranformers[idx](arguments[idx]))
}
return fn.apply(this, args.concat(slice(arguments, tranformers.length)));
};
});
我會說當'compose'將結果函數的所有參數提供給'pick'時,'compose(map,pick)'只是一個* NO * - 它不一定應該。如果你採用嚴格的固定版本(比如Haskell''。),它實際上是有效的。 – Bergi
@Bergi:是的,我花了一段時間才意識到它不會在Javascript的動態函數中起作用。我撓了一下頭,不能看出這個優雅的小代碼有什麼問題! :-)我試圖決定是否要以能夠解決此問題的方式更改「撰寫」。現在,它把所有的論點弄糊塗了,把第一個調用和後面的調用區別開來,顯然只有一個參數。 –
我認爲既不對也不對。絕對值得研究函數組合(以及類似的函數方法)如何在可變參數函數(以及實現存在的可能性)上如何工作,併爲它們找到標準術語。 – Bergi