另一個 Haskell 教程/前言
| Haskell | |
|---|---|
| |
| 另一個 Haskell 教程 | |
| 前言 | |
| 簡介 | |
| 入門 | |
| 語言基礎 (解決方案) | |
| 型別基礎 (解決方案) | |
| IO (解決方案) | |
| 模組 (解決方案) | |
| 高階語言 (解決方案) | |
| 高階型別 (解決方案) | |
| 單子 (解決方案) | |
| 高階 IO | |
| 遞迴 | |
| 複雜度 | |
另一個 Haskell 教程的目標是提供對 Haskell 程式語言的完整介紹。它假設你對 Haskell 語言沒有任何瞭解,也不熟悉函數語言程式設計。但是,對程式設計概念(例如演算法)的一般瞭解將有所幫助。這不是旨在介紹一般的程式設計;而是介紹 Haskell 中的程式設計。你還需要熟悉你的作業系統和文字編輯器(本報告只討論了 Windows 和 *Nix 系統上的安裝和配置;其他作業系統可能受支援——請參閱你選擇的編譯器的文件,以瞭解有關在其他平臺上安裝的更多資訊)。
Haskell 被稱為一種惰性、純函數語言程式設計語言。它被稱為惰性,因為不需要確定問題答案的表示式不會被求值。惰性的反義詞是嚴格,這是大多數常見程式語言(C、C++、Java,甚至 ML)的求值策略。嚴格語言是指所有表示式都被求值的語言,無論其計算結果是否重要。(這可能並不完全正確,因為針對嚴格語言的最佳化編譯器通常會進行所謂的“死程式碼消除”——這會從程式中刪除未使用的表示式。)Haskell 被稱為純,因為它不允許副作用(副作用是影響世界“狀態”的東西。例如,一個列印到螢幕上的函式被稱為有副作用,同樣,影響全域性變數值的一個函式也是有副作用的)——當然,沒有副作用的程式語言將毫無用處;Haskell 使用單子系統來將所有不純計算從程式的其餘部分隔離出來,並以安全的方式執行它們(參見本章 單子 以瞭解單子的討論,或者參見本章 IO 以瞭解如何在純語言中進行輸入/輸出)。
Haskell 被稱為函式式語言,因為程式的求值等同於從純粹的數學意義上求值一個函式。這也與標準語言(如 C 和 Java)不同,標準語言按順序執行一系列語句(這被稱為命令式語言)。
Haskell 的歷史最好用作者的話來描述。以下文字摘自已釋出的 Haskell 98 報告。
1987 年 9 月,在俄勒岡州波特蘭舉行的函數語言程式設計語言和計算機體系結構會議(FPCA '87)上舉行了一次會議,討論了函數語言程式設計社群中一個不幸的狀況:當時已經出現了十多種非嚴格的純函數語言程式設計語言,它們在表達能力和語義基礎方面都非常相似。會議上達成了一致意見,認為缺乏一種通用語言阻礙了這類函式式語言的廣泛使用。會議決定成立一個委員會來設計這種語言,以實現更快地傳播新想法、為真實應用程式開發提供穩定的基礎,並鼓勵更多人使用函式式語言。本文件描述了該委員會努力的結果:一種名為 Haskell 的純函數語言程式設計語言,以邏輯學家 Haskell B. Curry 的名字命名,他的工作為我們的大部分工作提供了邏輯基礎。
該委員會的主要目標是設計一種滿足以下約束條件的語言
- 它應該適用於教學、研究和應用,包括構建大型系統。
- 它應該透過釋出正式的語法和語義來完整地描述。
- 它應該可以免費獲得。任何人都被允許實現該語言並將其分發給任何人。
- 它應該基於得到廣泛共識的想法。
- 它應該減少函數語言程式設計語言中不必要的差異。
該委員會希望 Haskell 成為未來語言設計研究的基礎,並希望語言的擴充套件或變體能夠出現,幷包含實驗性功能。
自最初發布以來,Haskell 的確不斷發展。到 1997 年中,該語言設計已經迭代了四次(當時最新的版本是 Haskell 1.4)。在 1997 年阿姆斯特丹舉行的 Haskell 研討會上,人們決定需要一個穩定的 Haskell 變體;這個穩定的語言是本報告的主題,被稱為“Haskell 98”。
Haskell 98 被認為是對 Haskell 1.4 的相對較小的整理,進行了一些簡化,並消除了一些對新手而言的陷阱。它旨在成為一種“穩定”語言,從這個意義上說,實現者承諾在可預見的未來準確地支援 Haskell 98,如規範所述。
最初的 Haskell 報告只涵蓋了語言本身,以及一個名為 Prelude 的標準庫。到 Haskell 98 穩定為止,很明顯許多程式需要訪問更大的一組庫函式(特別是涉及輸入/輸出和與作業系統的簡單互動)。如果這些程式要可移植,那麼一組庫也必須標準化。因此,由一個不同的(但重疊的)委員會開始了一項單獨的努力來修復 Haskell 98 庫。
很明顯你對 Haskell 感興趣,因為你正在閱讀本教程。使用 Haskell 有很多動機。我個人使用 Haskell 的原因是我發現使用 Haskell 比使用任何其他語言,我能夠在更短的時間內編寫出更多無錯誤的程式碼。我還發現它非常易讀且可擴充套件。
然而,也許最重要的是,我一直髮現 Haskell 社群非常樂於助人。該語言一直在不斷發展(這並不意味著它不穩定;而是說已經添加了若干擴充套件到一些編譯器中,我發現這些擴充套件非常有用),並且使用者建議在實施新擴充套件時通常會被採納。
我最大的兩個抱怨,也是我認識的大多數 Haskell 程式設計師的抱怨,是:(1)生成的程式碼往往比用 C 等語言編寫的等效程式速度慢;(2)除錯起來往往很困難。
第二個問題往往不是一個大問題:我編寫的大多數程式碼都沒有錯誤,因為大多數其他語言中常見的錯誤來源在 Haskell 中根本不存在。第一個問題在我以往的經驗中確實出現過幾次;然而,CPU 時間幾乎總是比程式設計師時間便宜,如果我不得不花更多的時間等待結果,而之前已經節省了幾天的時間進行程式設計和除錯,那也是可以接受的。
當然,並非所有應用程式都如此。有些人可能會發現使用 Haskell 帶來的速度損失是不可接受的。但是,Haskell 擁有一個標準化的 _外部函式介面_,它允許你連結其他語言編寫的程式碼,當你需要從程式碼中獲得最大速度時。如果你覺得這還不夠,我建議你看看 OCaml 語言,這種語言的效能往往 _超過_ 甚至 C++,但也擁有 Haskell 的許多優點。
關於 Haskell 已經寫了很多書和教程;要檢視一個(幾乎)完整的列表,請訪問 Haskell 主頁的 Haskell 文件。對現有教程的簡要調查得出
- Haskell 入門 是 Haskell 的入門教程,假設讀者熟悉函數語言程式設計。
- Haskell 伴侶 是常見概念和定義的簡短參考。
- 線上 Haskell 課程 是一個簡短的課程(德語),用於開始學習 Haskell。
- 二十四個簡短的 Haskell 課 是一個優秀的教科書的草稿,強呼叫戶的參與。
- Haskell 教程 基於第三屆高階函數語言程式設計國際暑期學校的課程。
- 面向 Miranda 程式設計師的 Haskell 假設讀者瞭解 Miranda 語言。
雖然所有這些教程都非常優秀,但它們本身並不完整:“入門”對 Haskell 初學者來說過於高階,而其他教程往往結束得太早,或者沒有涵蓋所有內容。Haskell 對新手程式設計師和有經驗的非函式式程式設計師來說都充滿了陷阱,這可以從閱讀 Haskell 郵件列表的檔案中得到證明。
很明顯,迫切需要一種教程,它在入門意義上不假設讀者瞭解函數語言程式設計,但在高階意義上假設讀者具有一定的程式設計背景。此外,已知的教程都沒有早點介紹輸入/輸出和互動性(Paul Hudak 的書是個例外,它在第 35 頁介紹了 IO,儘管這本書和本教程的重點和目標非常不同)。本教程不適合初學者;假設讀者具有一定的程式設計和計算機知識(儘管附錄包含一些背景資訊)。
Haskell 語言經歷了一個標準化過程,結果被稱為 Haskell 98。本書的大部分內容將涵蓋 Haskell 98 標準。任何與標準的偏差都將予以說明(例如,許多編譯器提供了標準的某些擴充套件,這些擴充套件很有用;其中一些可能會在本文中討論)。
本教程的目標是
- 首先要 _實用_
- 提供一個全面、免費的 Haskell 語言入門
- 指出常見的陷阱及其解決方法
- 提供對 Haskell 如何在現實世界中使用的良好理解
- Haskell 簡介:http://haskell.org/aboutHaskell.html
- Haskell Wiki:http://haskell.org/
- Haskell 教程:ftp://ftp.geoinfo.tuwien.ac.at/navratil/HaskellTutorial.pdf
- Haskell Prelude 導覽:http://undergraduate.csse.uwa.edu.au/units/CITS3211/lectureNotes/tourofprelude.html
- Haskell 課程:http://haskell.org/classes/
如果不感謝 Haskell 的最初設計者,那就是不合適的。他們是:Arvind、Lennart Augustsson、Dave Barton、Brian Boutel、Warren Burton、Jon Fairbairn、Joseph Fasel、Andy Gordon、Maria Guzman、Kevin Hammond、Ralf Hinze、Paul Hudak、John Hughes、Thomas Johnsson、Mark Jones、Dick Kieburtz、John Launchbury、Erik Meijer、Rishiyur Nikhil、John Peterson、Simon Peyton Jones、Mike Reeve、Alastair Reid、Colin Runciman、Philip Wadler、David Wise、Jonathan Young。
最後,我要特別感謝 Simon Peyton Jones、Simon Marlow、John Hughes、Alastair Reid、Koen Classen、Manuel Chakravarty、Sigbjorn Finne 和 Sven Panne,他們一直支援我學習 Haskell,讓我的人生更加愉快。當然還有其他人也提供了幫助,但沒有列出來,不過這些是我想到的。
還要感謝許多人報告了第一版中的“錯誤”。
- Hal Daumé III
