[Day02] Pattern Matching


今天要講的是 pattern matching ,觀念上跟 Day01 講的 immutable 有一點點關係,但其實還是可以當作獨立的概念。

如果有寫過 ES6+ 的讀者,應該對於解構賦值(destructuring assignment)不陌生,語法寫起來大約是這樣:

// a = 'foo', b = { b: 'bar', c: 'baz' }
const { a, ...b } = { a: 'foo', b: 'bar', c: 'baz' }
// first = 1, second = 2, rest = [3, 4, 5]
const [first, second, ...rest] = [1, 2, 3, 4, 5]

解構賦值(destructuring assignment) 其實就隱含 pattern matching 的概念,就是如果等式的左邊跟右邊能找到一種方式能符合,則綁定 symbol & value。

但 pattern matching 的強大之處還不只如此,我們以 haskell 為例:

fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

簡單說明一下語法:
fib :: Int -> Int 表示宣告一個 function 叫做 fib ,fib 會吃一個 Int 型態的參數而回傳 Int 型態的回傳值。
下面就是有趣的部分了。我們定義 fib 0 = 0fib 1 = 1 ,意思就是說當參數是 0 時直接回傳 0,參數是 1 的時候直接回傳 1。附帶一提,在 haskell 裡括號是不必要的。
值得注意的部分有兩個:

  1. fib 0 = 0 這段用賦值來解釋的話完全說不通,要怎麼賦值給一個函數呢?所以這段程式碼的解讀應為 將 fib(0) 綁定到 0,如果在 Day01 還沒抓到'='其實是綁定這種感覺的讀者們可以感受一下這個概念。
  2. fib 0 = 0 的意義在於,如果我今天使用了 fib n 而 n 恰巧 = 0,則 (fib n) == (fib 0) == 0,換言之 pattern matching 不只可以針對 symbol 做配對,甚至可以對值做配對!只要左右測的值符合綁定的條件(以此例來說, n == 0),是可以直接用值來配對的,這是大多數具備類似解構賦值的特色的語言也做不到的。  

pattern matching 搭配 guard,甚至可以在參數階段就做一些簡單的過濾,像是下列這段 Haskell 程式碼:

absolute x
  | x < 0 = -x
  | otherwise = x

意思是在 x < 0 時,函式的值 = -x,反之則為 x。不用用 if/else 就可以寫出簡單的判斷,這就是 pattern matching 的威力!

有興趣的讀者也可以參考這一篇等號究竟是什麼意思? Elixir 裡的 pattern matching,可以更深入了解 pattern matching 的機制。

#Functional Programming #程式設計







你可能感興趣的文章

Day 2 - MongoDB 的 CRUD 教學

Day 2 - MongoDB 的 CRUD 教學

循序漸進理解 HTTP Cache 機制

循序漸進理解 HTTP Cache 機制

在Gatsby GraphQL中組合出完美資料

在Gatsby GraphQL中組合出完美資料






留言討論




caasi Feb 27, 2020

印象中 data constructor 和 pattern matching 常成對出現,大大有沒有打算介紹一下 algebraic data types ?

林子暘 Feb 27, 2020

那感覺有一點偏語法層面,因為只有七天不太想在語法層面上著墨太多~
後面有稍微提到一點點就是了
不過還是比較想講一些比較概念層面的東西