新書推薦:
《
郊庙之外:隋唐国家祭祀与宗教 增订版 (三联·哈佛燕京学术丛书)
》
售價:NT$
480.0
《
小麦文明:“黄金石油”争夺战
》
售價:NT$
445.0
《
悬壶杂记全集:老中医多年临证经验总结(套装3册) 中医医案诊疗思路和处方药应用
》
售價:NT$
614.0
《
无法忍受谎言的人:一个调查记者的三十年
》
售價:NT$
290.0
《
战争社会学专论
》
售價:NT$
540.0
《
剑桥意大利戏剧史(剑桥世界戏剧史译丛)
》
售價:NT$
740.0
《
教育何用:重估教育的价值
》
售價:NT$
299.0
《
理想城市:环境与诗性
》
售價:NT$
390.0
|
編輯推薦: |
《Haskell函数式编程基础:原书第3版》可作为计算机科学和其他相关学科的高年级本科生、研究生的教材,也可供对函数式程序设计感兴趣的程序员、软件工程师等参考学习。
|
內容簡介: |
《Haskell函数式编程基础:原书第3版》是一本非常优秀的Haskell函数式程序设计的入门书,依次介绍函数式程序设计的基本概念、编译器和解释器、函数的各种定义方式、简单程序的构造、多态和高阶函数、数组和列表的结构化数据、列表上的原始递归和推理、输入输出IO的控制处理、类型检测方法、代数数据类型、抽象数据类型、惰性计算等内容。《Haskell函数式编程基础:原书第3版》包含大量的实例和习题,注重程序测试、程序证明和问题求解,易读易学。《Haskell函数式编程基础:原书第3版》循序渐进,从基本的函数式程序设计直至高级专题,让读者对Haskell的学习不断深入。
|
目錄:
|
前言
第1章函数式程序设计简介
1.1计算机与建模
1.2什么是函数
1.3图形与函数
1.4类型
1.5函数式程序设计语言Haskell
1.6表达式与计算
1.7定义
1.8函数定义
1.9类型与函数式程序设计
1.10计算与求值
1.11函数式程序设计的精髓
1.12领域专用语言
1.13图形的两种模型.
1.14测试、性质和证明
第2章认识Haskell与GHCi
2.1第一个Haskell程序
2.2在工作中使用Haskell
2.3使用GHCi
2.4标准库Prelude和Haskell函数库
2.5模块
2.6例子:Pictures
2.7错误与错误信息
第3章基本类型与定义
3.1布尔类型Bool
3.2整数类型:Integer和Int
3.3重载
3.4守卫
3.5字符和串
3.6浮点数Float
3.7语法53第4章设计与书写程序
4.1如何开始一个Haskell程序的设计
4.2逐步求解问题:局部定义
4.3自定义类型:枚举类型
4.4递归
4.5实践中的原始递归
4.6扩展练习:图形.
4.7递归的一般形式
4.8程序测试.83第5章数据类型、多元组与列表
5.1多元组和列表简介
5.2元组类型
5.3代数类型简介
5.4本书对列表的介绍方法
5.5Haskell的列表
5.6列表概括
5.7图书馆数据库
第6章列表程序设计.
6.1通用函数:多态
6.2Haskell引导库Prelude中的列表函数
6.3认识Haskell函数库
6.4Picture例子的实现
6.5扩展练习:图形的另一种实现
6.6扩展练习:有位置的图形
6.7扩展练习:超市账单
6.8扩展练习:纸牌和纸牌游戏
第7章定义列表上的函数
7.1再谈模式匹配
7.2列表与列表模式
7.3列表上的原始递归
7.4寻找原始递归定义
7.5列表上的一般递归
7.6例子:文本处理
第8章游戏:Haskell的IO
8.1石头-剪刀-布的策略
8.2为什么IO是一个问题
8.3输入输出
8.4do语法
8.5迭代与递归
8.6石头-剪刀-布:玩游戏
第9章程序推理
9.1理解定义
9.2测试与证明
9.3定义性、终止性和有限性
9.4一些逻辑知识
9.5归纳法
9.6归纳证明的进一步例子
9.7推广证明目标186第10章推广:计算模型
10.1列表上的计算模式
10.2高阶函数:函数作为参数
10.3折叠与原始递归
10.4推广:拆分列表
10.5再谈实例.202第11章高阶函数
11.1运算:函数的复合和应用
11.2函数的表达式:λ抽象
11.3部分应用
11.4卡瑞式函数
11.5定义高阶函数
11.6验证与通用函数
第12章高级程序开发
12.1再谈Picture
12.2函数作为数据:策略组合子
12.3函数作为数据:正则表达式匹配
12.4函数作为数据的实例
12.5例子:建立索引
12.6实践中的程序开发
12.7理解程序
第13章重载,类族和类型检测
13.1为什么使用重载?
13.2引进类族
13.3签名和实例
13.4Haskell的预定义类族
13.5类型检测和类型推导概述
13.6单态类型检测
13.7多态类型检测
13.8类型检测与类族284第14章代数类型
14.1代数类型回顾
14.2递归代数类型
14.3多态代数类型
14.4程序错误的表示
14.5使用代数类型设计系统
14.6代数类型与类族
14.7代数类型的推理
第15章实例研究:Hu.man编码
15.1Haskell的模块
15.2模块设计
15.3编码与译码
15.4实现一
15.5构造Hu.man树
15.6设计
15.7实现二
第16章抽象数据类型
16.1类型表示
16.2Haskell抽象数据类型机制
16.3队列
16.4设计
16.5仿真
16.6实现仿真
16.7查找树
16.8集合
16.9关系和图
16.10评注
第17章惰性计算
17.1惰性计算
17.2计算规则与惰性计算
17.3再谈列表概括
17.4数据导向编程
17.5实例:分析表达式
17.6无穷列表
17.7为什么使用无穷列表
17.8实例:仿真
17.9再谈证明
第18章单子程序设计
18.1输入输出程序
18.2深入IO
18.3计算器
18.4再谈do记法
18.5单子:为函数式程序设计定制的语言
18.6例子:树上的单子式计算
第19章领域专用语言
19.1程序语言无处不在
19.2为什么在Haskell中嵌入DSL?
19.3浅嵌入和深嵌入
19.4处理正则表达式的DSL
19.5单子式DSL
19.6表示计算的DSL:QuickCheck中的数据生成
19.7深入DSL
第20章时间与空间行为
20.1函数的复杂度
20.2计算的复杂度
20.3集合的实现.
20.4空间行为
20.5再谈折叠
20.6避免重复计算:记忆
第21章结论
21.1函数式程序设计的威力
21.2深入Haskell
21.3网络上的Haskell
21.4其他函数式程序设计语言
附录A函数式,命令式和OO程序设计
A.1值与状态
A.2函数与变量
A.3程序验证
A.4记录和元组
A.5列表和指针
A.6高阶函数
A.7多态
A.8定义类型与类族
A.9列表概括
A.10惰性计算
A.11状态,无穷列表和单子
A.12结论
附录B术语解释501附录CHaskell运算符
附录DHaskell实践
D.1实现
D.2下载Craft3e代码
D.3使用GHCi
D.4Haskell编辑器511附录EGHCi错误
E.1语法错误
E.2类型错误
E.3程序错误
E.4模块错误
E.5系统信息
附录F项目建设
F.1游戏与智力测验
F.2Web图形
F.3逻辑
F.4投票系统
F.5有穷自动机
F.6领域专用语言
参考文献
索引
|
內容試閱:
|
第1章函数式程序设计简介
本章首先概括介绍什么是函数式程序设计(或者函数程序设计),以及函数式程序设计与其他方式程序设计的不同,同时介绍函数式程序设计语言Haskell。本章的目的有三个:
介绍函数式程序设计的主要思想,并解释函数和类型的概念。然后介绍如何求表达式的值以及如何书写求值的过程。一旦读者理解如何使用函数后,再介绍如何自定义一个函数。为了理解函数的功能,本章将介绍如何测试函数,以及如何使用数学证明来说明一个函数具有某种特定的性质。
以图形为例来解释以上的概念。这样做不仅是因为它可以展示Haskell在实践中的应用特点,而且也因为它是领域专用语言(DSL)的一个例子,而Haskell便是特别适用于领域专用语言的程序设计语言。
最后,对照其他程序设计方式,如面向对象的程序设计,本章将介绍函数式程序设计中更具表现力且与众不同的思想。读者由此可以看出,为什么在财经、Web2.0和多核高效程序设计等领域的许多程序开发人员选择了函数式程序语言。我们还将解释,为什么无论你在什么领域工作,函数式程序语言的思想都能让你成为一个更好的程序员。
本章将指明有关内容在后续哪些章节中有详细解释和例子说明。尽管本书是为Haskell函数式程序设计编写的教材,但是如第21章所讨论的一样,本书讨论的许多内容具有普遍意义,同样适用于其他函数程序语言。
1.1计算机与建模
过去的60年来,计算机已经由庞大、昂贵、稀少、低速及不可靠的机器过渡为小型、廉价、普及、快速和相对可靠的机器。第一代计算机是“孤立”(stand-alone)的机器,而现代计算机都连接到全球互联网络上。现代计算机不仅已经嵌入汽车和洗衣机等家用电器里,而且还成为诸如智能手机和其他个人设备的核心。如果你对计算机的重要性有所怀疑,那么设想一下如果所有的计算机都停止工作将产生的影响:那便是一夜之间整个世界将陷入一片混乱。
尽管如此,现在这个时期计算的基本目的即处理符号信息并没有多大的变化。这些信息可以是简单的情况,如超市的购物清单,或者更复杂的情况,如关于欧洲的气象系统。给定这些信息,信息处理的任务可能是计算超市购物的总支出,或者是对英格兰南部做出24小时的气象预报。
这些任务如何得以完成呢?我们需要描述信息是如何处理的。对这个过程的描述称为一个程序(program),它是用一种程序设计语言(programminglanguage)编写的。这种程序设计语言是一种计算机指令的人工形式化语言。换言之,这种语言用于编写控制计算机硬件(hardware)运行的软件(software)。
一方面,虽然计算机的体积已经由大如房屋变为小如手掌,但是其由集成电路构成的处理单元和内存组成结构以及基本工作原理基本没有变化。另一方面,计算机的编程方式却已经发生了巨大的变化。最初的程序是用直接控制计算机硬件的指令编写的,而现代程序设计语言致力于程序员思考和解决问题的“高”层次,而不是机器解决问题的“低”层次(机器层)。
程序设计语言由一个实现(implementation)来完成它在计算机上的工作,这个实现本身也是一个程序,其任务是运行由高阶语言编写的程序。本书的目的是讲授如何编写函数式程序,而非实现的细节,有关实现参见(PeytonJones1987;PeytonJones和Lester1992)。
本书讨论的主题是函数式程序设计。函数式程序设计是众多不同的程序设计方式或模式(paradigm)的一种,其他的程序设计方法包括面向对象(OO)、结构程序设计和逻辑程序设计等。为什么有不同的程序设计方法,它们之间有何不同呢?一种研究程序设计语言的有效方法是分析它在计算机中如何为实际问题或者想象的问题建模(modelling)。每类程序设计语言提供了不同的建模工具,这些不同的工具允许我们——或者迫使我们——用不同的方式思考问题。例如,函数式程序员考虑的是值之间的关系,而面向对象(OO)程序员考虑的是对象。在介绍函数式程序设计之前,我们首先需要弄清函数的概念。
1.2什么是函数
一个函数(function)可以视为如下图所示的一个方盒,它有一些输入和一个输出。函数给出一个依赖于输入值(input)的输出(output)。我们常用结果(result)这个术语来代替输出,用自变量(argument)或者参数(parameter)代替输入。数值的加法运算+便是一个简单的函数例子。给定两个输入12和34,对应的输出将是46。
1.3图形与函数
为函数提供特定输入的过程称为函数的应用(functionalapplication),(12+34)表示将函数+应用于12和34。
加法是一个数学函数,但是在许多其他场合下也会用到各种函数,例如:.输出两个城市(输入)间公路距离(输出)的函数;
.超市的结账程序,给定一系列扫描过的条形码(输入),计算出相应的账单(输出);
.化工厂的阀门控制器,其输入的是传感器的信息,输出的是传到阀门控制器的信号。
不同种类的程序设计语言因为其提供了不同的建模工具而各具特色。在函数式程序设计语言中,我们关注的是值(如条形码和账单)以及作用在这些值上的函数(如输出账单的总支出)。读者将会在下面的贯穿于本书的图形例子中看到这一点。
1.3图形与函数
让我们考虑如何给图形建模。首先,我们想说明图形间的很多关系是由函数来表述的。在本节,我们将讨论一系列这样的例子。
在垂直镜子中的反射可以将两个图形相关联,这种关系可以由一个函数flipV来描述:
在这里我们演示了将“马”的图形翻转后的结果。类似地,我们可以用一个函数flipH表示在水平镜子中的翻转。另一个函数表示了将(单色)图形反色的结果:
某些函数具有多个参数,如将图形放大的函数:
将一个图形放在另一个图形之上的函数:
以及将两个图形并列的函数:
以上这些函数都具有这样的特点:对于若干输入(或者自变量、参数),函数给出依赖于这些输入的输出(或者结果)。更重要的是,这些结果只依赖于给定的输入,同样的输入总是产生同样的输出。
1.4类型
在详细解释Haskell函数式程序设计之前,先来介绍另一个概念——类型(type)。
函数式程序中的函数涉及各种不同种类的值:加法函数把两个数相结合,然后给出另一个数;flipV将一个图形转换为另一个图形;scale取一个图形和一个数值,然后给出另一个图形,诸如此类。
一个类型(type)是同类值的一个集合,如数构成的集合和图形构成的集合。同类的值尽管各不相同,如.2不同于567,但是可以应用到这些值的函数是相同的。例如,求两个数中的较大者是有意义的,但是,求两个图形中较大的图形,或者求一个图形与一个数中较大者是无意义的。
以上介绍的函数都接受某些特定类型的输入,给出相应特定类型的输出。例如,加法函数+,只有两个数相加才有意义,两个图像相加是无意义的。这个例子说明,函数本身也有一个类型,并且可以用下图表示:
上图表示+由两个整数(Integer)作为输入,并返回一个整数(Integer)作为结果。类似地,函数scale可以用下图表示:
它的第一个参数是一个Picture,第二个参数是一个Integer,其结果是一个Picture。下图是一个正确地将函数above作用到两个Picture的例子:
但是,将函数above作用到一个Picture和一个Integer时会出现类型错误(typeerror),表示有错误发生:
至此函数式程序设计的中心思想已经介绍了其中的两个:一个类型是一些值的集合,如整数的集合;一个函数是带有一个或者多个参数,并能返回一个结果的运算。这两个概念是相互关联的:函数作用于特定的类型上,如拉伸图形的函数带有两个参数,一个类型是
Picture,另一个的类型是Integer,并返回一个Picture。
在为一个问题场景(通常称为问题领域(domain))建模时,类型表示领域中的事物①,函数表示可以作用到这些事物或者处理这些事物的操作中。例如,在“图形”例子中,类型Picture表示图形本身,函数表示可以对这些对象进行的处理,如将一个图形搁置在另一个图形之上,或者将一个图形放大。
一个大致的规则是类型对应名词,而对值进行转换或者处理的函数对应动词。本书将在1.9节继续对类型进行讨论。
1.5函数式程序设计语言Haskell
Haskell(Marlow2010)是本书使用的函数式程序设计语言。Haskell的定义始于1990年,并且经历了多个版本的修改,本书写作时的版本是Haskell2010。
Haskell是以发明λ演算的先驱之一HaskellB.Curry命名的。λ演算是关于函数的数学理论,它为多种函数语言的设计者提供了灵感。
了解Haskell的最佳地点是其官方网站,包括语言定义本身、语言的实现、库函数、资源、邮件列表、新闻和工作机会等。
Haskell有多种实现。本书将使用GHCi(2010)。GHCi是GlasgowHaskellCompilerinteractive的简写。SimonPeytonJones和SimonMarlow在格拉斯哥大学工作时开始了该编译器的设计,他们目前均受聘于微软在剑桥的研究院。GHCi为初学者提供了最好的环境,包括免费的PC版本、Linux版本和MacOSX系统版本,并且具有高效、紧凑和用户接口灵活等特点。
GHCi是一个解释器。这意味着它像在纸上作计算一样一步步地计算表达式的值。不过,GHCi也可以装载编译成机器语言的代码,所以GHCi综合了解释器的灵活性和编译器的高效性,使得程序的运行速度与传统语言C和C++语言程序运行的速度相近。有关Haskell不同实现的细节请参见附录E以及Haskell主页。
GHCi是Haskell平台(Haskell平台2010)的组成部分,该平台包括一个标准编译器和常用库。其他库可以从数据库HackageDB(Hackage2010)在线获得。用户通过平台的一个打包和发布工具Cabal(Cabal2010)很容易下载和安装这些库。关于GHC的交互版本使用在下一章介绍,Hackage和Cabal的使用将在第6章介绍。
本书中的所有程序和例子均可使用Cabal下载为Craft3e包,该网站也收集了其他的阅读材料和本书的背景材料。网站将跟踪在Haskell平台的后继版本中是如何使用本书的。
……
|
|