[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 #程式設計







你可能感興趣的文章

WeakMap

WeakMap

D18_第二週作業

D18_第二週作業

「margin : atuo」與「margin : 0 auto」 有什麼差別?

「margin : atuo」與「margin : 0 auto」 有什麼差別?






留言討論