1. 程式人生 > >scala之柯里化函式

scala之柯里化函式

  • 定義

        柯里化(Currying)指的是將原來接受兩個引數的函式變成新的接受一個引數的函式的過程。新的函式返回一個以原有第二個引數為引數的函式。也就是說,有多個引數列表的函式就是柯里化函式,所謂的引數列表就是使用小括號括起來的函式引數列表。

        curry化最大的意義在於把多個引數的function等價轉化成多個單引數function的級聯,這樣所有的函式就都統一了,方便做lambda演算。 在scala裡,curry化對型別推演也有幫助,scala的型別推演是區域性的,在同一個引數列表中後面的引數不能借助前面的引數型別進行推演,curry化以後,放在兩個引數列表裡,後面一個引數列表裡的引數可以藉助前面一個引數列表裡的引數型別進行推演。

  • 函式
val add_f = (x: Int, y: Int) => x + y
  • 方法
def add(x:Int, y: Int) = x + y

def add_f = (x: Int, y: Int) => x + y  //轉為方法
  • 區別
    • 方法只能用def接收,函式可以用def接收,也可以用val接收。
    •  當函式用def來接收之後,不再顯示為function,轉換為方法。
    •  方法可以省略引數,函式不可以。函式可以作為方法的引數.
  • 柯里化例項
def add(x:Int,y:Int)=x+y

     現在我們把這個函式變一下形式:

def add(x:Int)(y:Int) = x + y
  •  程式碼
object CurryingInstance {
  def strAdd(st1: String)(st2: String): String = {
    st1 + st2
  }
}


object CurryingTest {
  def main(args: Array[String]): Unit = {
    val str1: String = "Hello, "
    val str2: String = "Scala!"
    val result = CurryingInstance.strAdd(str1)(str2)
    println(result)
  }
}
  • 柯里化函式和偏函式的區別

        下面程式碼定義一個普通方法multiply1和一個currying方法multiply2,並將其轉換相應的函式型別:

def multiply1(x: Int, y:Int, z:Int) = x * y * z
val partialAppliedMultiply = multiply1 _
//型別:(x: Int, y: Int, z: Int) => Int

def multiply2(x: Int)(y: Int)(z: Int) = x * y * z
val curryingMultiply = multiply2 _
//型別:Int => (Int => (Int => Int))

      在呼叫時,curryingMultiply可以依次傳入各個引數,而partialAppliedMultiply在傳入部分引數時,必須顯示指定剩餘引數的佔位符:

val curryingMultiply1 = curryingMultiply(1)
//型別:Int => (Int => Int)

val partialAppliedMultiply1 = partialAppliedMultiply(1, _:Int, _: Int)
//型別:(Int, Int) => Int

另外,curryingMultiply1的型別仍然是currying型別,而partialAppliedMultiply1的型別仍然是普通函式型別。