2011-08-19 27 views
15

注意:跳轉到「問題」的,如果你只是想跳過上下文時要使用部分應用功能

在給予對Scala的會談中,我非常給「玩具問題」類似下面的部分應用功能的例子。

def multiply(x:Int, y:Int): Int = x * y 
val x5 = multiply(5, _:Int) 
x5(10) //produces 50 

這個例子並幫助,但它的強硬讓我解釋一下一般的「這是當你意識到時要使用一個部分應用的功能」。

問題:任何人都有自己的方式來成功地解釋部分應用函數,這對Java(或其他面嚮對象語言)的開發人員來說真的很有用嗎?

回答

25

假設您想應用銷售稅。

def withTax(cost: Float, state: String) = { /* Some complicated lookup table */ } 

現在假設你想在紐約進行一大堆採購。

val locallyTaxed = withTax(_: Float, "NY") 
val costOfApples = locallyTaxed(price("apples")) 

你通過不指定參數是(當地)總是相同的從原始方法最大的代碼重用,又極大的方便了重複性的任務。

人們經常嘗試用implicits解決這個代替:

def withTax(cost: Float)(implicit val state: String) = ... 

不要這麼做! (並非沒有仔細考慮。)很難跟蹤當時哪個隱含val發生。通過部分應用的功能,您可以節省相同的打字費用,而且您可以知道您正在使用哪一種功能,因爲每次使用時都鍵入名稱!

+0

ahhh我可以看到,真正減少了你需要定義的「重載」函數的數量。謝謝。 – ThaDon

+0

我剛剛讀完部分應用函數,並想知道在什麼情況下我會使用它,在這裏它是.. +1對於優秀的解釋 – Sikorski

8

在Java中,您經常會將部分應用函數的第一個(或多個)參數傳遞給類的構造函數。雷克斯的例子可能看起來像這樣:

class TaxProvider { 
    final String state; 

    TaxProvider(String state) { 
     this.state = state; 
    } 

    double getTaxedCost(double cost) { 
     return ... // look up tax for state and apply to cost 
    } 
} 


TaxProvider locallyTaxed = new TaxProvider("NY") 
double costOfApples = locallyTaxed.getTaxedCost(price("apples")) 
1

我猜Scala有函數組成,這是部分應用函數發光的東西。

另一點是高階函數等filter稱取的謂詞,和它們的用法等在:

filter (<42) list -- sorry, don't speak Scala 

謂詞是經常一些部分應用功能。 map,fold等等。