另一個 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 最大的兩個抱怨,也是我認識的大多數 Haskeller 的抱怨,是:(1)生成的程式碼往往比用 C 等語言編寫的等效程式速度慢;(2)它往往難以除錯。
第二個問題通常不是一個大問題:我寫的大部分程式碼都沒有 bug,因為其他語言中常見的 bug 來源在 Haskell 中根本不存在。第一個問題在我的經驗中確實出現過幾次;但是,CPU 時間幾乎總是比程式設計師時間便宜,如果我必須在節省了幾天程式設計和除錯之後等待更長時間才能得到結果,那也沒關係。
當然,並非所有應用程式都是這樣。有些人可能會發現使用 Haskell 造成的效能下降難以忍受。但是,Haskell 具有標準化的 _外部函式介面_,它允許您連結用其他語言編寫的程式碼,以便在您需要從程式碼中獲得最高速度時使用。如果您覺得這還不夠,我建議您看看 OCaml 語言,它經常 _勝過_ 甚至 C++,同時還擁有 Haskell 的許多優點。
關於 Haskell 的書籍和教程已經有很多了;要獲得 (幾乎) 完整的列表,請訪問 Haskell 主頁上的 Haskell 文件。對現有教程的簡要調查得出
- Haskell Gentle Introduction 是 Haskell 的入門教程,假設讀者熟悉函數語言程式設計。
- Haskell Companion 是常見概念和定義的簡短參考。
- 線上 Haskell 課程 是一個簡短的課程(德語),用於 Haskell 入門。
- Haskell 的二十四個簡短課程 是一個優秀的教科書的草稿,強呼叫戶參與。
- Haskell 教程 基於第三屆高階函數語言程式設計國際暑期學校的課程。
- Haskell for Miranda Programmers 假設讀者瞭解 Miranda 語言。
儘管所有這些教程都很好,但它們本身並不完整:"Gentle Introduction" 對 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 的過程更加愉快。毫無疑問還有其他幫助過我的人,但這裡列出的是我想到的。
還要感謝許多報告第一版中“bug”的人。
- Hal Daumé III
