Haskell 筆記(四)函數系統

函數系統


函數式編程當然少不了函數系統啦,在教程最初的時候就有一個最簡單的函數,函數系統貫穿在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 部分可見
本教程參考了《Haskell趣學指南》,是這篇指南的學習筆記,不過參入了我自己的一些想法和總結,首先,感謝《Haskell趣學指南》的作者bonus 和大陸翻譯者Fleurer和臺灣翻譯者MnO2,謝謝你們之前的工作。
發佈了54 篇原創文章 · 獲贊 16 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章