函數系統
函數式編程當然少不了函數系統啦,在教程最初的時候就有一個最簡單的函數,函數系統貫穿在Haskell全部,Haskell的函數有幾個重要的性質。
- 首先聲明一下函數的參數和返回值類型
- 然後有一個很重要寫法就是匹配,用匹配來匹配參數,所以Haskell的函數寫法和其他語言不一樣,同樣一個函數可能有幾種表達形式
模式匹配
函數匹配的一個例子,比如有這麼一個函數,當用戶輸入7時顯示輸入了七,否則顯示沒輸入7.
lucky :: (Integral a) => a -> String
lucky 7 = "LUCKY NUMBER SEVEN!"
lucky x = "Sorry, you're out of luck, pal!"
- 第一行表示參數是個數字,輸出是個字符串
- 模式匹配自上向下檢查匹配結果
- 當匹配上以後就運行匹配項的函數並且後面的不會進行匹配
Guards
Guard
,直譯過來就是守衛,簡單的說就是if
語句,這是一個比模式匹配更精確的定位方式,可以更加精確的確定參數範圍。
bmiTell :: (RealFloat a) => a -> String
bmiTell bmi
| bmi <= 18.5 = "You're underweight, you emo, you!"
| bmi <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!"
| bmi <= 30.0 = "You're fat! Lose some weight, fatty!"
| otherwise = "You're a whale, congratulations!"
- 使用
|
表示守衛 - 一個 guard 就是一個布爾表達式,如果爲真,就使用其對應的函數體。如果爲假,就送去見下一個 guard
- 使用
otherwise
表示任意其他情況
Where
Where
用來在函數中綁定變量的數值,一般寫在函數的最後面,比如上一個例子中的bmi,如果使用身高和體重計算出來的話,可以寫成Where形式。
bmiTell :: (RealFloat a) => a -> a -> String
bmiTell weight height
| bmi <= 18.5 = "You're underweight, you emo, you!"
| bmi <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!"
| bmi <= 30.0 = "You're fat! Lose some weight, fatty!"
| otherwise = "You're a whale, congratulations!"
where bmi = weight / height ^ 2
Where
關鍵字中的變量只在函數中有效,不會污染命名空間- 綁定不會在多個模式中共享。如果你在一個函數的多個模式中重複用到同一名字,就應該把它置於全局定義之中
Let
let 綁定與 where 綁定很相似。where 綁定是在函數底部定義名字,對包括所有 guard 在內的整個函數可見。let 綁定則是個表達式,允許你在任何位置定義局部變量,而對不同的 guard 不可見
看一個依據半徑和高度求圓柱體表面積的函數
cylinder :: (RealFloat a) => a -> a -> a
cylinder r h =
let sideArea = 2 * pi * r * h
topArea = pi * r ^2
in sideArea + 2 * topArea
- let 的格式爲 let [bindings] in [expressions]
- let 綁定本身是個表達式,而 where 綁定則是個語法結構
- 在 let 中綁定的名字僅對 in 部分可見