Scala學(xué)習(xí)筆記(六) Scala的偏函數(shù)和偏應(yīng)用函數(shù)

1. 偏函數(shù)

偏函數(shù)(Partial Function)形娇,是一個(gè)數(shù)學(xué)概念它不是"函數(shù)"的一種, 它跟函數(shù)是平行的概念瞭空。
Scala中的Partia Function是一個(gè)Trait讳推,其的類型為PartialFunction[A,B],其中接收一個(gè)類型為A的參數(shù)昔字,返回一個(gè)類型為B的結(jié)果。

舉個(gè)例子


scala> val pf:PartialFunction[Int,String] = {
     |   case 1=>"One"
     |   case 2=>"Two"
     |   case 3=>"Three"
     |   case _=>"Other"
     | }
pf: PartialFunction[Int,String] = <function1>

scala> pf(1)
res0: String = One

scala> pf(2)
res1: String = Two

scala> pf(3)
res2: String = Three

scala> pf(4)
res3: String = Other

偏函數(shù)內(nèi)部有一些方法首繁,比如isDefinedAt李滴、OrElse、 andThen蛮瞄、applyOrElse等等所坯。

1.1 isDefinedAt

isDefinedAt : 這個(gè)函數(shù)的作用是判斷傳入來(lái)的參數(shù)是否在這個(gè)偏函數(shù)所處理的范圍內(nèi)。
剛才定義的pf來(lái)嘗試使用isDefinedAt()挂捅,只要是數(shù)字都是正確的芹助,因?yàn)橛衏ase _=>"Other"這一句。如果換成其他類型就會(huì)報(bào)錯(cuò)闲先。

scala> pf.isDefinedAt(1)
res4: Boolean = true

scala> pf.isDefinedAt(2)
res5: Boolean = true

scala> pf.isDefinedAt("1")
<console>:13: error: type mismatch;
 found   : String("1")
 required: Int
       pf.isDefinedAt("1")
                      ^

scala> pf.isDefinedAt(100)
res7: Boolean = true

那我們?cè)俣x一個(gè)PartialFunction

scala> val anotherPF:PartialFunction[Int,String] = {
     |    case 1=>"One"
     |    case 2=>"Two"
     |    case 3=>"Three"
     | }
anotherPF: PartialFunction[Int,String] = <function1>

scala> anotherPF.isDefinedAt(1)
res8: Boolean = true

scala> anotherPF.isDefinedAt(2)
res9: Boolean = true

scala> anotherPF.isDefinedAt(3)
res10: Boolean = true

scala> anotherPF.isDefinedAt(4)
res11: Boolean = false

去掉了原先的最后一句状土,再執(zhí)行anotherPF.isDefinedAt(4)會(huì)返回false。

1.2 orElse

orElse : 將多個(gè)偏函數(shù)組合起來(lái)使用伺糠,效果類似case語(yǔ)句蒙谓。


scala> val onePF:PartialFunction[Int,String] = {
     |   case 1=>"One"
     | }
onePF: PartialFunction[Int,String] = <function1>

scala> val twoPF:PartialFunction[Int,String] = {
     |   case 2=>"Two"
     | }
twoPF: PartialFunction[Int,String] = <function1>

scala> val threePF:PartialFunction[Int,String] = {
     |   case 3=>"Three"
     | }
threePF: PartialFunction[Int,String] = <function1>

scala> val otherPF:PartialFunction[Int,String] = {
     |   case _=>"Other"
     | }
otherPF: PartialFunction[Int,String] = <function1>

scala> val newPF = onePF orElse twoPF orElse threePF orElse otherPF
newPF: PartialFunction[Int,String] = <function1>

scala> newPF(1)
res0: String = One

scala> newPF(2)
res1: String = Two

scala> newPF(3)
res2: String = Three

scala> newPF(4)
res3: String = Other

這樣,newPF跟原先的pf效果是一樣的训桶。

1.3 andThen

andThen: 相當(dāng)于方法的連續(xù)調(diào)用累驮,比如g(f(x))酣倾。

scala> val pf1:PartialFunction[Int,String] = {
     |   case i if i == 1 => "One"
     | }
pf1: PartialFunction[Int,String] = <function1>

scala> val pf2:PartialFunction[String,String] = {
     |   case str if str eq "One" => "The num is 1"
     | }
pf2: PartialFunction[String,String] = <function1>

scala> val num = pf1 andThen pf2
num: PartialFunction[Int,String] = <function1>

scala> num(1)
res4: String = The num is 1

pf1的結(jié)果返回類型必須和pf2的參數(shù)傳入類型必須一致,否則會(huì)報(bào)錯(cuò)谤专。

1.4 applyOrElse

applyOrElse:它接收2個(gè)參數(shù)躁锡,第一個(gè)是調(diào)用的參數(shù),第二個(gè)是個(gè)回調(diào)函數(shù)置侍。如果第一個(gè)調(diào)用的參數(shù)匹配映之,返回匹配的值,否則調(diào)用回調(diào)函數(shù)蜡坊。

scala> onePF.applyOrElse(1,{num:Int=>"two"})
res5: String = One

scala> onePF.applyOrElse(2,{num:Int=>"two"})
res6: String = two

在這個(gè)例子中杠输,第一次onePF匹配了1成功則返回的是"One"字符串。第二次onePF匹配2失敗則觸發(fā)回調(diào)函數(shù)秕衙,返回的是"Two"字符串蠢甲。

2. 偏應(yīng)用函數(shù)

偏應(yīng)用函數(shù)(Partial Applied Function)也叫部分應(yīng)用函數(shù),跟偏函數(shù)(Partial Function)從英文名來(lái)看只有一字之差灾梦,但他們二者之間卻有天壤之別峡钓。

部分應(yīng)用函數(shù), 是指一個(gè)函數(shù)有n個(gè)參數(shù), 而我們?yōu)槠涮峁┥儆趎個(gè)參數(shù), 那就得到了一個(gè)部分應(yīng)用函數(shù)妓笙。
個(gè)人理解的偏應(yīng)用函數(shù)類似于柯里化若河,可以參考我以前寫(xiě)的文章借助Java 8實(shí)現(xiàn)柯里化

舉個(gè)例子,定義好一個(gè)函數(shù)有3個(gè)參數(shù)寞宫,再提供幾個(gè)有1-2個(gè)已知參數(shù)的偏應(yīng)用函數(shù)

scala> def add(x:Int,y:Int,z:Int) = x+y+z
add: (x: Int, y: Int, z: Int)Int

scala> def addX = add(1,_:Int,_:Int) // x 已知
addX: (Int, Int) => Int

scala> addX(2,3)
res1: Int = 6

scala> addX(3,4)
res2: Int = 8

scala> def addXAndY = add(10,100,_:Int) // x 和 y 已知
addXAndY: Int => Int

scala> addXAndY(1)
res3: Int = 111

scala> def addZ = add(_:Int,_:Int,10) // z 已知
addZ: (Int, Int) => Int

scala> addZ(1,2)
res4: Int = 13

總結(jié)

本篇筆記是為了下一篇 Scala 模式匹配所做的鋪墊萧福。模式匹配會(huì)用到偏函數(shù),所以先整理出來(lái)辈赋。還詳細(xì)介紹了偏函數(shù)和偏應(yīng)用函數(shù)的區(qū)別鲫忍。

先前的文章:
Scala學(xué)習(xí)筆記(五) 抽象類以及類中的一些語(yǔ)法糖
Scala學(xué)習(xí)筆記(四) 類的初步
Scala學(xué)習(xí)筆記(三)
Scala學(xué)習(xí)筆記(二)
Scala學(xué)習(xí)筆記(一)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市钥屈,隨后出現(xiàn)的幾起案子悟民,更是在濱河造成了極大的恐慌,老刑警劉巖篷就,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件射亏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡竭业,警方通過(guò)查閱死者的電腦和手機(jī)智润,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)未辆,“玉大人窟绷,你說(shuō)我怎么就攤上這事「拦瘢” “怎么了兼蜈?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵攘残,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我饭尝,道長(zhǎng)肯腕,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任钥平,我火速辦了婚禮实撒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘涉瘾。我一直安慰自己知态,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布立叛。 她就那樣靜靜地躺著负敏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪秘蛇。 梳的紋絲不亂的頭發(fā)上其做,一...
    開(kāi)封第一講書(shū)人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音赁还,去河邊找鬼妖泄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛艘策,可吹牛的內(nèi)容都是我干的蹈胡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼朋蔫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼罚渐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起驯妄,我...
    開(kāi)封第一講書(shū)人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤荷并,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后青扔,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體源织,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年赎懦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了雀鹃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡励两,死狀恐怖黎茎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情当悔,我是刑警寧澤傅瞻,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布踢代,位于F島的核電站,受9級(jí)特大地震影響嗅骄,放射性物質(zhì)發(fā)生泄漏胳挎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一溺森、第九天 我趴在偏房一處隱蔽的房頂上張望慕爬。 院中可真熱鬧,春花似錦屏积、人聲如沸医窿。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)姥卢。三九已至,卻和暖如春渣聚,著一層夾襖步出監(jiān)牢的瞬間独榴,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工奕枝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棺榔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓倍权,卻偏偏與公主長(zhǎng)得像掷豺,于是被迫代替她去往敵國(guó)和親捞烟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子薄声,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容