跳轉到內容

Haskell/解決方案/模式匹配

來自華夏公益教科書,開放的書籍,為開放的世界

← 返回模式匹配

匹配字面量值

[編輯 | 編輯原始碼]
練習
  1. 在 GHCi 中測試上面有缺陷的 h 函式,使用等於 1 和不同於 1 的引數。然後解釋錯誤發生的原因。
  2. 在本節關於用字面量值進行模式匹配中,我們沒有提到布林值 TrueFalse,但我們也可以用它們進行模式匹配,如 下一步 章中所示。你能猜出我們為什麼省略它們嗎?(提示:我們寫布林值的方式有什麼獨特之處嗎?)

1.

在用於模式匹配時,像 h 中的 k 這樣的簡單變數名

h k = True

k 繫結到 h 的引數,並且至關重要的是,匹配任何東西。由於我們在等式右側沒有使用繫結的 k 變數,因此在這個函式中,這個定義的效果與

h _ = True

相同,這就是 GHC/GHCi 會抱怨模式重疊,以及為什麼 h 的第二個等式被忽略。此外,在函式外部定義的 k = 1 定義不會影響發生的事情 - 用於模式匹配的 k 具有區域性作用域(h 等式的作用域),並且與其他 k 無關。

2.

Bool 不是字面量值;相反,它是一個代數資料型別,就像我們在上一章中首次遇到的那樣。本質上,它在 Prelude 中的定義等同於

data  Bool  =  False | True

FalseTrue 是無引數建構函式;這就是為什麼它們的名字以大寫字母開頭。

語法技巧

[編輯 | 編輯原始碼]
練習
實現 scanr,如 列表 III 中的練習所示,但這次使用 as 模式。


myScanr step zero [] = [zero]
myScanr step zero (x:xs) = (step x y):ys
    where ys@(y:_) = myScanr step zero xs

你可能在第一個版本的練習中使用了 head 而不是 as 模式;但是,在這裡,我們沒有在 ys 的模式中匹配空列表。在這種特定情況下,兩種解決方案都不是不安全的,因為 myScanr 的結果永遠不會是空列表。然而,模式匹配仍然比 head 更好,因為它更清楚地表明我們選擇不處理空列表情況。

華夏公益教科書