何時使用 Currying

Currying 是一種翻譯函式求值的技術,該函式將多個引數計算為一系列函式,每個函式都有一個引數

例如,這通常很有用:

  1. 函式的不同引數在不同時間計算。 (例 1)
  2. 函式的不同引數由應用程式的不同層計算。 (例 2)

例 1

我們假設年收入總額是由收入和獎金組成的函式:

val totalYearlyIncome:(Int,Int) => Int =  (income, bonus) => income + bonus

以上 2-arity 函式的 curried 版本是:

val totalYearlyIncomeCurried: Int => Int => Int = totalYearlyIncome.curried

請注意,在上面的定義中,型別也可以被視為/寫為:

Int => (Int => Int)

我們假設年收入部分是事先知道的:

val partialTotalYearlyIncome: Int => Int = totalYearlyIncomeCurried(10000)

在某些方面,獎金是已知的:

partialTotalYearlyIncome(100)

例 2

讓我們假設汽車製造涉及車輪和車身的應用:

val carManufacturing:(String,String) => String = (wheels, body) => wheels + body

這些部件由不同的工廠應用:

class CarWheelsFactory {
  def applyCarWheels(carManufacturing:(String,String) => String): String => String =
          carManufacturing.curried("applied wheels..")
}
    
class CarBodyFactory {
  def applyCarBody(partialCarWithWheels: String => String): String = partialCarWithWheels("applied car body..")
}

請注意,上面的 CarWheelsFactory 會影響汽車的製造功能並僅適用於車輪。

然後汽車製造過程將採用以下形式:

val carWheelsFactory = new CarWheelsFactory()
val carBodyFactory   = new CarBodyFactory()

val carManufacturing:(String,String) => String = (wheels, body) => wheels + body
  
val partialCarWheelsApplied: String => String  = carWheelsFactory.applyCarWheels(carManufacturing)
val carCompleted = carBodyFactory.applyCarBody(partialCarWheelsApplied)