淺談函數式編程

什么是函數式編程

函數式編程(Functional Programming, FP),FP 是編程范式之一,我們常聽說的編程范式還有面向過程
編程、面向對象編程。

  • 面向對象編程的思維方式:把現實世界中的事物抽象成程序世界中的類和對象,通過封裝、繼承和
    多態來演示事物事件的聯系
  • 函數式編程的思維方式:把現實世界的事物和事物之間的聯系抽象到程序世界(對運算過程進行抽
    象)
    • 程序的本質:根據輸入通過某種運算獲得相應的輸出,程序開發過程中會涉及很多有輸入和
      輸出的函數
    • x -> f(聯系、映射) -> y,y=f(x)
    • 函數式編程中的函數指的不是程序中的函數(方法),而是數學中的函數即映射關系,例如:y = sin(x),x和y的關系
    • 相同的輸入始終要得到相同的輸出(純函數)
    • 函數式編程用來描述數據(函數)之間的映射

特點

函數式編程具有五個鮮明的特點。

1. 函數是"第一等公民"

所謂"第一等公民"(first class),指的是函數與其他數據類型一樣,處于平等地位,可以賦值給其他變量,也可以作為參數,傳入另一個函數,或者作為別的函數的返回值。

舉例來說,下面代碼中的print變量就是一個函數,可以作為另一個函數的參數。

var print = function(i){ console.log(i);};

[1,2,3].forEach(print);

2. 只用"表達式",不用"語句"

"表達式"(expression)是一個單純的運算過程,總是有返回值;"語句"(statement)是執行某種操作,沒有返回值。函數式編程要求,只使用表達式,不使用語句。也就是說,每一步都是單純的運算,而且都有返回值。

原因是函數式編程的開發動機,一開始就是為了處理運算(computation),不考慮系統的讀寫(I/O)。"語句"屬于對系統的讀寫操作,所以就被排斥在外。

當然,實際應用中,不做I/O是不可能的。因此,編程過程中,函數式編程只要求把I/O限制到最小,不要有不必要的讀寫行為,保持計算過程的單純性。

3. 沒有"副作用"

所謂"副作用"(side effect),指的是函數內部與外部互動(最典型的情況,就是修改全局變量的值),產生運算以外的其他結果。

函數式編程強調沒有"副作用",意味著函數要保持獨立,所有功能就是返回一個新的值,沒有其他行為,尤其是不得修改外部變量的值。

4. 不修改狀態

上一點已經提到,函數式編程只是返回新的值,不修改系統變量。因此,不修改變量,也是它的一個重要特點。

在其他類型的語言中,變量往往用來保存"狀態"(state)。不修改變量,意味著狀態不能保存在變量中。函數式編程使用參數保存狀態,最好的例子就是遞歸。下面的代碼是一個將字符串逆序排列的函數,它演示了不同的參數如何決定了運算所處的"狀態"。

 function reverse(string) {
    if(string.length == 0) {
       return string;
     } else {
       return reverse(string.substring(1, string.length)) + string.substring(0, 1);
     }
 }

由于使用了遞歸,函數式語言的運行速度比較慢,這是它長期不能在業界推廣的主要原因。

5. 引用透明

引用透明(Referential transparency),指的是函數的運行不依賴于外部變量或"狀態",只依賴于輸入的參數,任何時候只要參數相同,引用函數所得到的返回值總是相同的。

有了前面的第三點和第四點,這點是很顯然的。其他類型的語言,函數的返回值往往與系統狀態有關,不同的狀態之下,返回值是不一樣的。這就叫"引用不透明",很不利于觀察和理解程序的行為。

高階函數

高階函數 (Higher-order function)

  • 可以把函數作為參數傳遞給另一個函數
  • 可以把函數作為另一個函數的返回結果
  • 函數作為參數

常用高階函數

  • forEach
  • map
  • filter
  • every
  • some
  • find/findIndex
  • reduce
  • sort

純函數

  • 純函數:相同的輸入永遠會得到相同的輸出,而且沒有任何可觀察的副作用
  • 函數式編程不會保留計算中間的結果,所以變量是不可變的(無狀態的)
  • 我們可以把一個函數的執行結果交給另一個函數去處理

純函數的好處

  • 可測試
  • 并行處理:純函數不需要訪問共享的內存數據,所以在并行環境下可以任意運行純函數 (Web Worker)

柯里化

柯里化 (Currying):
當一個函數有多個參數的時候先傳遞一部分參數調用它(這部分參數以后永遠不變)
然后返回一個新的函數接收剩余的參數,返回結果

函子

  • 容器:包含值和值的變形關系(這個變形關系就是函數)
  • 函子:是一個特殊的容器,通過一個普通的對象來實現,該對象具有 map 方法,map 方法可以運
    行一個函數對值進行處理(變形關系)

函子的意義

  • 函數式編程的運算不直接操作值,而是由函子完成
  • 函子就是一個實現了 map 契約的對象
  • 我們可以把函子想象成一個盒子,這個盒子里封裝了一個值
  • 想要處理盒子中的值,我們需要給盒子的 map 方法傳遞一個處理值的函數(純函數),由這
    個函數來對值進行處理
  • 最終 map 方法返回一個包含新值的盒子(函子)

常見函子

  • Maybe
  • Either
  • IO
  • Point
  • Monad
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,362評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,013評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,346評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,421評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,146評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,534評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,585評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,767評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,318評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,074評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,258評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,828評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,486評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,916評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,156評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,993評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,234評論 2 375

推薦閱讀更多精彩內容