天天看點

scala中的部分應用函數和偏函數的差別

之前學習 Scala

程式設計語言時, 經常把部分應用函數(Partial Applied Function)和偏函數(Partial Function) 搞混。

這裡做個簡單的總結

以下的讨論基于 scala 2.8

部分應用函數(Partial Applied Function)是缺少部分參數的函數,是一個邏輯上概念

偏函數是(Partical Function)隻對函數定義域的一個子集進行定義的函數。 scala中用

scala.PartialFunction[-T, +S]

類來表示

比如定義了一個函數:

def sum(x: Int)(y: Int) = x + y

, 當調用sum的時候,如果不提供所有的參數或某些參數還未知時,比如

sum _

,

sum(3)(_: Int), sum(_: Int)(3)

, 這樣就生成了所謂的部分應用函數。部分應用函數隻是邏輯上的一個表達,scala編譯器會用

Function1

Function2

這些類來表示它.

下面這個變量signal引用了一個偏函數

val signal: PartialFunction[Int, Int] = {
    case x if x > 1 => 1
    case x if x < -1 => -1
}           

這個signal所引用的函數除了0值外,對所有整數都定義了相應的操作。 signal(0) 會抛出異常,是以使用前最好先

signal.isDefinedAt(0)

判斷一下。 偏函數主要用于這樣一種場景:對某些值現在還無法給出具體的操作(即需求還不明朗),也有可能存在幾種處理方式(視乎具體的需求);我們可以先對需求明确的部分進行定義,比如上述除了0外的所有整數域,然後根據具體情況補充對其他域的定義,比如 :

val composed_signal: PartialFunction[Int,Int] = signal.orElse{
case 0 => 0
}

composed_signal(0)  // 傳回 0            

或者對定義域進行一定的偏移(假如需求做了變更, 1 為無效的點)

val new_signal: Function1[Int, Int] = signal.compose{
  case x => x  - 1
}

new_signal(1)  // throw exception
new_signal(0)   // 傳回 -1 
new_signal(2)  // 傳回 1           

還可以用andThen将兩個相關的偏函數串接起來

val another_signal: PartialFunction[Int, Int] = {
   case 0 =>  0
   case x if x > 0 => x - 1 
   case x if x < 0 => x + 1
}

val then_signal =  another_signal andThen  signal           

這裡的then_signal 剔除了-1, 0, 1三個點的定義

繼續閱讀