為什麼諸多編程語言都將模式匹配作為重要構成?
如題,這樣有什麼好處嗎
簡單來說, 模式匹配提供一個方便的解構(Destructuring)數據結構的方式, 而且構造跟解構的語法是類似(甚至相同)的可以加強語言的一致性.
以語法和傳統的C比較相近的Rust為例struct Point {
x: i32,
y: i32,
}
let origin = Point { x: 0, y: 0 };
//^^^^^^^^構造^^^^^^^^^
match origin {
Point { x: x, y: y } =&> println!("({},{})", x, y),
//^^^^^^^^解構^^^^^^^^^
}
via Patterns
但是解構數據結構都用模式匹配也有不方便的地方, 當數據結構比較"淺"的時候, 模式匹配還是比較好用, 就像上面的例子一樣, 但是當數據結構比較"深"的時候, *只有*模式匹配的語言做get/set操作就略麻煩data Person = P { name :: String
, addr :: Address
}
data Address = A { street :: String
, city :: String
, postcode :: String
}
setPostcode :: String -&> Person -&> Person
setPostcode pc p = p { addr = addr p { postcode = pc }}
via https://notepad.mmakowski.com/Tech/Haskell%20Exchange%202013
因為postcode這個成員藏得比較深, 想一次過set postcode, 做的解構次數會很多, 實際中肯定會存在這種情況, 想一下各種一層嵌一層的JSON. 其中一個解決方法就是用一個中間變數先把address拿出來, 再拿postcode. 這就失去了 @肖劍 在評論提到的可以減少中間變數的便利.如果能像OO用"."來訪問: person.address.postcode = newPostcode , 不是更加方便?
深入下去偏離題目討論的內容, 關於"."的話可以看Erik Merijer的 The essence of data access in cω: The power is in the dot.
Haskell對這個問題的解決辦法是lens: Lenses, Folds and Traversals這個庫, 這是個簡單的介紹 https://gist.github.com/patrickt/d43031e3b69f1a4ff8c9 , 記住, 千萬不要看實現, 千萬不要!
@RednaxelaFX 在評論里提到平行賦值Ruby類似模式匹配的功能看這裡:http://tony.pitluga.com/2011/08/08/destructuring-with-ruby.html
但是Ruby只對能用字面量表達的數據結構有比較好的解構支持補充一點, 模式匹配處理深匹配還可以玩成這樣:
egison/egison · GitHub
就很像 xpath, jquery, sql 等邏輯式編程了說這麼多,還不如在C裡面寫一遍紅黑樹,再用haskell寫一遍,比較下代碼長度就知道為啥要pattern match了
祖與占 解釋了原理。
應用上來說,就是,模式匹配很多時候真他媽好用!好用!好用!不好用的時候別用就是了。。。有句話說的好:
模式匹配是對於類型值不同形式的分析
其他答主也說了:好用。
舉個 Erlang 官方文檔里 bit string pattern matching 的例子:-define(IP_VERSION, 4).
-define(IP_MIN_HDR_LEN, 5).
DgramSize = byte_size(Dgram), 一個模式匹配解完一個完整的 IPv4 包頭。
case Dgram of
&<&&> when HLen&>=5, 4*HLen=&
OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN),
&<&
...
end.
我沒事翻了下erlang語法,第一次看到了模式匹配時,瞬間覺得這尼瑪屌爆了。
Algebraic data type
正如你為何需要正則表達式
1. 好寫易讀;2. 自動解構;3. 編譯期檢查.
不模式匹配,自舉起來多麻煩。。。。
畢竟boostraping推薦閱讀:
※Haskell中的foldl和foldr的聯繫?
※紅塵里的Haskell(之一)——Haskell工具鏈科普
※用哪些編程語言寫出的代碼,讀著能感受到美?
※函數式編程的早期歷史
TAG:函數式編程 |