【前端開發】FP 基礎:純函式 & 柯里化

閱讀時間約 4 分鐘
Functional Programming 中文譯作函式程式設計,或是功能性程式設計,常簡稱為:FP,是一種透過使用純函式(Pure Funciton)進行軟體開發,且避免副作用的程式設計典範,比起宣告式的流程控制,在 FP 採用主要以表達式的方式撰寫程式碼。
如果我們將 FP 這個設計典範的特點一一列點出來會有以下概念:
  • 透過純函數(Pure Function)將函式封裝成函式最小單位
  • 使用複合函數(Function Composition)提升函式的復用性
  • 避免副作用(Side Effect)
  • 使用表達式
接著就讓我們來看看什麼是純函式吧!

什麼是純函式?

純函式(Pure Funciton)在 FP 中是一個很核心的概念,在 FP 這個設計典範中,我們都會使用純函式的方式來撰寫我們的程式碼。
首先讓我們來看看純函式的定義:
  • 單輸入單輸出(One input, one output)
  • 不會造成任何副作用
那我們為什麼在 FP 中要使用純函式呢?我們希望可以讓程式碼的狀態不互相依賴,以免造成變數與變數間互相覆蓋的狀況。
更重要的是,我們同時也希望程式碼的覆用性可以更高,而不是在同個函式中,同時處理不同性質的任務,一旦這些任務重複性出現在不同的流程中,就會發現任務彼此之間過於耦合難以拆分,要擴充新的功能,就只能向樂高一樣繼續往上疊,或一改就要改到天荒地老的窘境。
除了開發過程可能變得沒有效率外,把程式碼當樂高疊的後果是,萬一未來有人不小心改到了某個地方,就很容易導致這個程式碼樂高塔輕易崩塌。
在 FP 中,我們傾向把任務拆分成最小最小的單位,並且透過函式來處理這些任務,而規則單純卻又嚴謹的純函式就成為 FP 最萬用的工具。
如果我們要寫一個簡單、但卻會重複出現的篩選邏輯,例如:將指定商品進行打折,沒有使用 FP 前我們可能會這樣寫:
或者是:
上述這些程式碼會有幾個狀況:重複程式碼函式內一次性做太多事,如果我只要取得指定商品的打折價,就必須再計算一次,或是取得其他商品的打折數,這樣就很容易產生副作用,甚至是預期外的結果。
現在我們使用純函式寫一個打折器:
這樣是不是乾淨許多呢?除了純函式外,在 FP 中我們還會使用另外一個工具:「柯里化」來管理我們的程式碼。

什麼是「柯里化」?

其實最初科里化(Currying)是一個數學理論,後續才由 Haskell Curry 發揚光大,故名「Currying」。
科里化的核心概念是將函式要帶入的多個參數,轉換為一次性帶入一個參數,舉例來說:
這麼做有什麼好處呢?讓我們來看看科里化與純函式相比有什麼好處:
  1. 可以把程式法切的更碎片,提高複用性,例如:可以固定第一個、第 n 個參數的值,根據需求將關注點放在需要放的地方。
  2. 因為一次只傳入一個參數,降低傳入參數數量的錯誤
難道上述兩個優點純函式做不到嗎?是的純函式還真的做不到,讓我們直接來看範例比較:
我們會發現若是透過純函式固定第一個參數,其實沒什麼意義,因為我們還是會不斷重複帶入同樣的參數,光是上方的程式碼,就足以想見未來若是要重複使用函式,未經科里化的純函式程式碼會越來越多。
以上就是 FP 設計典範中最基礎也是最廣為人知的概念,不過 FP 的概念不僅僅於此,如果你有興趣的話,可以參考我在 2022 第十四屆 iThome 鐵人賽《致 JavaScript 開發者的 Functional Programming 新手指南》
在這系列文章中,除了介紹 Functional Programming 這門設計典範外,也包含了要習得 FP 技術前所必備的 JavaScript 基礎知識,及一些 FP 在前端的演進史。
希望透過這篇文章的分享,可以讓大家簡單了解那些前端開發者常說的 Pure Function 及 Curry 是什麼,關於 Functional Programming 你有什麼想要跟我分享的嗎?歡迎下方留言與我分享!
希望今天的文章有幫助到正在閱讀的你,如果你喜歡我的文章的話,可以留下你的愛心或是收藏我的文章,也或者可以點選「贊助」,你的一杯咖啡絕對是我持續寫下去的動力!或是透過拍拍手,用你小小的行動支持我的創作!
我是Vivian,我們下次見。
關於我:
一名從英文系畢業的前端工程師,喜歡閱讀、寫東西及自我成長。
|聯絡我:vivian.enlife@gmail.com
此篇文章會顯示動態置底廣告
為什麼會看到廣告
為了追求可以窩在座位上、可以心無旁騖思考問題、座位可以亂七八糟沒關係、不需要到處哈腰點頭跑客戶,不用腳踩十公分、連妝都可以不用化的職場人生,文組少女毅然決然踏上RD的養成日常。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Hoisting 可以說是 ES6 問世之後,去面試還是會爾偶被問到的面試考題,雖然 Hoisting 離 Modern JavaScript 的技術有點距離,實作上幾乎不太會用到,但透過了解 Hoisting 的概念,可以對這門語言有更深的了解與掌握度。
對於剛接觸前端開發不久的人來說,可能會對var、let 與 const 的差異略懂略懂,但又說不太出三者實際哪裡不一樣。
在一開始學習前端開發的時候,一直遇到講師在課程內容中提到 ES5、ES6 等關鍵字,當初的我,單純認為 ES5、ES6 是講述 JavaScript 的版本,所以在使用上就沒有想太多,反正就是 JavaScript 1.0 、2.0 的感覺吧?
在初學程式的時候,我曾經看室友開發專案到一半時,突然坐在那發呆,於是我好奇一問,室友說:「我在等程式編譯完成啊。」 還記得當初還是程式小菜雞的我,懞懂無知的說:「編譯?哈哈哈,我們 JavaScript 都不需要編譯耶,可以直接跑在瀏覽器上。」 室友一臉莫名其妙地回我:「噢,是嗎⋯⋯」
前陣子有讀者來信詢問我:「嗨!Vivian,我想要請問妳都是在哪裡學程式的呢?是實體課程嗎?」
Hoisting 可以說是 ES6 問世之後,去面試還是會爾偶被問到的面試考題,雖然 Hoisting 離 Modern JavaScript 的技術有點距離,實作上幾乎不太會用到,但透過了解 Hoisting 的概念,可以對這門語言有更深的了解與掌握度。
對於剛接觸前端開發不久的人來說,可能會對var、let 與 const 的差異略懂略懂,但又說不太出三者實際哪裡不一樣。
在一開始學習前端開發的時候,一直遇到講師在課程內容中提到 ES5、ES6 等關鍵字,當初的我,單純認為 ES5、ES6 是講述 JavaScript 的版本,所以在使用上就沒有想太多,反正就是 JavaScript 1.0 、2.0 的感覺吧?
在初學程式的時候,我曾經看室友開發專案到一半時,突然坐在那發呆,於是我好奇一問,室友說:「我在等程式編譯完成啊。」 還記得當初還是程式小菜雞的我,懞懂無知的說:「編譯?哈哈哈,我們 JavaScript 都不需要編譯耶,可以直接跑在瀏覽器上。」 室友一臉莫名其妙地回我:「噢,是嗎⋯⋯」
前陣子有讀者來信詢問我:「嗨!Vivian,我想要請問妳都是在哪裡學程式的呢?是實體課程嗎?」
你可能也想看
Google News 追蹤
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
這篇內容,將會講解什麼是腳本函式,以及與腳本函式相關的知識。包括腳本的簡介、使用函式(或全域變數)的注意事項、定義全域變數、定義函式、什麼是宣告、局部變數的應用。
主要來講宣告函式跟箭頭函式 : 宣告函式(Function Declaration) 語法: function functionName(parameters) { return result; } 特點: 使用 function 關鍵字 函式名稱是必需的 存在函式
Thumbnail
這章節的目的是介紹 Kotlin 語言中函數的基本用法和概念,包括函數的聲明、使用、參數和返回值等。通過學習這章節,讀者可以熟練掌握如何在 Kotlin 中定義和使用函數,來解決各種問題。
pure function 是甚麼呢? 最主要兩大特點 : 淺顯易懂的說法就是 : 對於有相同的輸入,就會有相同的輸出。 無副作用 : 不會去修改或依賴外部的狀態。 舉一個例子 : function add(a, b) { return a + b; } function裡面他帶入的
※ 單例模式介紹 ※ 定義:單例模式是一種設計模式,確保一個class(類)只有一個實例,並提供一個存取它的全域存取點。無論如何取值,皆只對這個實例取值。 ※ 目的:保證一個類別只會產生一個物件,而且提供存取該物件的統一方法。 ※ 講解:單例模式確保一個類無論怎麼 new 或 get,都只能拿
對於程序式編程來說,程式是由一系列的指令組成,例如計算數值、印出訊息、修改變數、呼叫子程序、配置變數的記憶體空間等。定義函式是為了讓一些程序可以重複利用,因此稱為子程序,其中參數為子程序中特別的變數,讓我們能夠透過它們控制子程序的行為。函式的回傳值只是一種方便將結果帶回來的方法,但一般只能回傳一個值
這個系列的文章主要專注於物件導向到函數式編程的差異與分析,並針對概念與機制上的不同進行比較。很多人說物件導向和函數式編程沒有哪個比較好的問題,只有哪個比較適合的問題,然而我並不這麼認為,我透過這一系列的文章從各個角度討論它們之間的優缺點就是為了闡述我的觀點。物件導向錯在沒有理論基礎,但它贏在熟悉性,
Thumbnail
本文將介紹自定函式及應用,利用程式範例解釋為什麼要用到自定函式 自定函式好處當然就是,讓你的程式碼看起來比較簡潔,在重複使用到的程式碼區塊,可以包裝成函式,讓你重複使用它。
前幾篇文章討論了類型系統的合理性,而這會影響我們對於變數與函式是什麼的理解。其中泛型是當中很重要的一個元素,很多討論都是基於泛型的使用。泛型會大大地增加類型系統的複雜度,因此有些語言選擇不提供泛型(go),但缺少泛型又會使簡單的容器都無法用類型精確描述。泛型的強大必須結合有紀律的類型系統才能顯現,但
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
這篇內容,將會講解什麼是腳本函式,以及與腳本函式相關的知識。包括腳本的簡介、使用函式(或全域變數)的注意事項、定義全域變數、定義函式、什麼是宣告、局部變數的應用。
主要來講宣告函式跟箭頭函式 : 宣告函式(Function Declaration) 語法: function functionName(parameters) { return result; } 特點: 使用 function 關鍵字 函式名稱是必需的 存在函式
Thumbnail
這章節的目的是介紹 Kotlin 語言中函數的基本用法和概念,包括函數的聲明、使用、參數和返回值等。通過學習這章節,讀者可以熟練掌握如何在 Kotlin 中定義和使用函數,來解決各種問題。
pure function 是甚麼呢? 最主要兩大特點 : 淺顯易懂的說法就是 : 對於有相同的輸入,就會有相同的輸出。 無副作用 : 不會去修改或依賴外部的狀態。 舉一個例子 : function add(a, b) { return a + b; } function裡面他帶入的
※ 單例模式介紹 ※ 定義:單例模式是一種設計模式,確保一個class(類)只有一個實例,並提供一個存取它的全域存取點。無論如何取值,皆只對這個實例取值。 ※ 目的:保證一個類別只會產生一個物件,而且提供存取該物件的統一方法。 ※ 講解:單例模式確保一個類無論怎麼 new 或 get,都只能拿
對於程序式編程來說,程式是由一系列的指令組成,例如計算數值、印出訊息、修改變數、呼叫子程序、配置變數的記憶體空間等。定義函式是為了讓一些程序可以重複利用,因此稱為子程序,其中參數為子程序中特別的變數,讓我們能夠透過它們控制子程序的行為。函式的回傳值只是一種方便將結果帶回來的方法,但一般只能回傳一個值
這個系列的文章主要專注於物件導向到函數式編程的差異與分析,並針對概念與機制上的不同進行比較。很多人說物件導向和函數式編程沒有哪個比較好的問題,只有哪個比較適合的問題,然而我並不這麼認為,我透過這一系列的文章從各個角度討論它們之間的優缺點就是為了闡述我的觀點。物件導向錯在沒有理論基礎,但它贏在熟悉性,
Thumbnail
本文將介紹自定函式及應用,利用程式範例解釋為什麼要用到自定函式 自定函式好處當然就是,讓你的程式碼看起來比較簡潔,在重複使用到的程式碼區塊,可以包裝成函式,讓你重複使用它。
前幾篇文章討論了類型系統的合理性,而這會影響我們對於變數與函式是什麼的理解。其中泛型是當中很重要的一個元素,很多討論都是基於泛型的使用。泛型會大大地增加類型系統的複雜度,因此有些語言選擇不提供泛型(go),但缺少泛型又會使簡單的容器都無法用類型精確描述。泛型的強大必須結合有紀律的類型系統才能顯現,但