位元詩人 Haskell 程式設計入門

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

當前定位

Haskell 起源於語言研究,每隔幾年,新的研究成果便會整合進編譯器,形成新的穩定版本。

這門語言擁有型別推論(type inference)、型別類別(typeclass)、模式匹配(pattern matching)以及惰性求值(lazy evaluation)等特性,使它特別適合抽象建模、數理建模與領域專用語言設計。同時,對於想要學習函數式程式設計(FP, Functional Programming)的開發者而言,Haskell 也是一個理想的起點。

除了學術研究之外,Haskell 也被應用在真實專案中。原因在於編譯器能嚴格檢查程式碼,顯著降低錯誤率,讓開發團隊能夠在高可靠性的基礎上開發專案。

Hello World

這是一個「空的」Haskell 程式,什麼事都沒做就結束:

main = return ()

也可以按照 Hello World 傳統,印出文字:

main = putStrLn "Hello World"

編譯後執行程式:

$ ghc program.hs
$ ./program
Hello World

原始碼命名規範

以下是 Haskell 專案常見的副檔名:

  • .hs:原始碼
  • .hi:介面檔
  • .o:目的檔
  • .exe:Windows 二進位執行檔
  • Unix 二進位執行檔通常沒有副檔名

主函式

在 Haskell 中,主函式的名稱固定為 main,它是整個程式的進入點。

主函式的型態必須是 IO (),代表它會執行輸出入操作並回傳空值。如果程式不需要輸出任何字串,可以在最後寫上 return (),以明確回傳空值並結束執行。

大小寫敏感

Haskell 是一種大小寫敏感的語言。按照慣例,識別字的命名方式多半仿照 Java 風格,讓程式碼在可讀性與一致性上更容易維護。

排版元素

在 Haskell 中,縮排會影響程式碼的語意,因此排版是不可或缺的。依照函數式程式設計的慣例,通常以兩格空白作為縮排。

當語意已經清楚時,括號可以省略;但在需要改變運算子優先順序或進行層疊函式呼叫時,括號則不可省略。

註解

Haskell 的註解以 -- 開頭,後方的文字會被編譯器忽略。這種方式可以用來記錄程式碼的設計想法、意圖或備註,方便日後維護與理解。

撰寫敘述

如同其他 FP,Haskell 是以表達式(expression)為主體的語言,無法撰寫敘述。不過可以用語法糖 do,程式碼看起來就會像敘述。

參考以下範例:

import Text.Printf

greet obj =
  printf "Hello %s" obj

main = do
  let o = "World"
  putStrLn (greet o)

如果把 do 還原,其實程式碼更難閱讀。把 do 當成語法就好。

回傳值

不是用 return,而是用 System.Exit 庫。

程式正確執行:

import System.Exit

main = exitSuccess

預設即為正確執行。若非必要,不需顯式回傳。

程式發生錯誤:

import System.Exit

main = exitWith(ExitFailure 1)

這時會回傳 1

系統資源處理

Haskell 程式通常不需要手動管理記憶體,因為垃圾回收會自動處理大部分情況。

但 Haskell 採用 lazy evaluation,雖然這特性很適合表達數學概念與無限資料結構,有時卻可能因累積過多暫存值(thunk)而造成 space leak,導致記憶體使用效率不佳。

關於作者

位元詩人 (ByteBard) 是資訊領域碩士,專注於從探索到產品的開發過程,並以工具驅動的方式改善專案。喜歡以開源專案作為成果,回饋社群。

主要方向包括:自用工具的打磨 (dogfooding)、編譯器技術在工具開發中的應用,以及將研究轉化為可維護的開源成果。

除了技術之外,也喜歡日本料理和黑咖啡,偶爾自助旅行,將生活中的靈感融入技術隨筆。