iT邦幫忙

2023 iThome 鐵人賽

DAY 7
0
Software Development

Haskell 從入門到放棄系列 第 7

[Haskell 從入門到放棄] Day 07 - Pattern Matching

  • 分享至 

  • xImage
  •  

pattern matching 這個許多語言都有的概念,它的常見形式會很像一個switch cass,然後根據不一樣的 case/pattern 決定執行不一樣的程式碼片段,而在 Haskell 中我們是在 function 定義時寫入特定的模式來達成這件事情。

基本使用

舉個例子我想寫一個 function ,如果讀到特定字元就輸出特定字串的話我可以這樣寫:

word 'a' = "Apple"
word 'b' = "Banana"
word 'c' = "Candy"

word 'a' -- "Apple"
word 'b' -- "Banana"
word 'c' -- "Candy"

但如果我們超出我們所規定的 pattern 的話

word 'd'
"*** Exception: <interactive>:116:1-18: Non-exhaustive patterns in function word

所以通常我還是需要定義一個通用的 pattern 這樣才能避免 runtime 的錯誤

稍微進階一點點

那我們也可以用 Pattern matching 來達成之前遞迴加總 List 的元素

sumList :: [Int] -> Int
sumList [] = 0
sumList (x:xs) = x + sumList xs

print (sumList [1..5]) -- 15 

我們先定義了sumList [] = 0 意思是 sumList 的參數為 [] 時會回傳 0 ,而當參數不是 [] 時就是會到下一行 sumList (x:xs) = x + sumList xs 我知道也許有人初見這種 expression 會感到疑惑。

首先只要先記得 [1,2,3] 就是 1:[2,3] (精確來說是 1:2:3:[] ) 的語法糖,那這邊我們就能用 (x:xs) 的形式去拿出 List 中的第一個元素及剩餘的List 。 然後我就把第一項與放入 sumList 的剩餘 List 相加即可。

as-pattern

在 Haskell 中還有兩個蠻常見搭配 pattern matching 的語法 @_

concatFirstElement :: [String] -> String
concatFirstElement [] = "Empty list, whoops!" 
concatFirstElement all@(x:_) = "The first element of the list " ++ show all ++ " is " ++ x

print (concatFirstElement []) -- "Empty list, whoops!"
print (concatFirstElement ["foo","bar","baz"]) -- "The first element of the list [\"foo\",\"bar\",\"baz\"] is foo"

我們先從_ 開始看,第二行的 pattern 是會去匹配 (x:_) 的格式,那_ 的意思是我們不在意或者說不會用到這個數值。那意義就是我們只需要x 而他後面: 所串接的 List,我們並不需要。

all@(x:_) 就是記住這個 pattern 的 reference ,也就是說 all 就是 (x:_) 這個 List ,所以我們可以在接下來的 expression 如果需要用到整個List 我們不必一直 x:xs 來作為整個 List 。

今天介紹了 pattern matching 的基本運用,明天將會介紹更多 pattern matching 相關的語法~


今天的程式碼:

https://github.com/toddLiao469469/30days-for-haskell


上一篇
[Haskell 從入門到放棄] Day 06 - type 入門課
下一篇
[Haskell 從入門到放棄] Day 08 - Pattern Matching (2)
系列文
Haskell 從入門到放棄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
shootingstar
iT邦新手 4 級 ‧ 2023-09-19 21:33:17

typo
1:[2:3] -> 1:[2,3]

感謝~

我要留言

立即登入留言