另一个 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