《Scala函数式编程》PDF下载

  • 购买积分:10 如何计算积分?
  • 作  者:(美)Paul Chiusano,(美)Runar Bjarnason著
  • 出 版 社:2016
  • 出版年份:22
  • ISBN:9787121283307
  • 页数:245 页
图书介绍:函数式编程(FP)是一种软件开发风格,它注重不依赖于编程状态的函数。函数式代码易于测试和复用,容易实现并发,且不容易受到bug的攻击。Scala是一种能很好支持函数式编程的新兴JVM语言。本书是针对希望学习FP并将它应用于日常编码中的程序员而写的,内容包括:函数式编程的概念;函数式编程相关的各种“为什么”和“怎么做”;如何编写多核程序;练习和检测。

第一部分 函数式编程介绍 1

1 什么是函数式编程 2

1.1 函数式编程的好处:一个简单的例子 3

1.1.1 一段带有副作用的程序 3

1.1.2 函数式的解法:去除副作用 5

1.2 (纯)函数究竟是什么 7

1.3 引用透明、纯粹度以及替代模型 8

1.4 小结 10

2 在Scala中使用函数式编程 11

2.1 Scala语言介绍:一个例子 11

2.2 运行程序 14

2.3 模块、对象和命名空间 15

2.4 高阶函数:把函数传给函数 15

2.4.1 迂回做法:使用循环方式 16

2.4.2 第一个高阶函数 17

2.5 多态函数:基于类型的抽象 18

2.5.1 一个多态函数的例子 19

2.5.2 对高阶函数传入匿名函数 20

2.6 通过类型来实现多态 21

2.7 小结 23

3 函数式数据结构 24

3.1 定义函数式数据结构 24

3.2 模式匹配 26

3.3 函数式数据结构中的数据共享 29

3.3.1 数据共享的效率 30

3.3.2 改进高阶函数的类型推导 31

3.4 基于list的递归并泛化为高阶函数 32

3.4.1 更多与列表相关的函数 35

3.4.2 用简单组件组合list函数时的效率损失 36

3.5 树 37

3.6 小结 39

4 不是用异常来处理错误 40

4.1 异常的优点与劣势 40

4.2 异常的其他选择 42

4.3 Option数据类型 43

4.3.1 Option的使用模式 44

4.3.2 Option的组合、提升及对面向异常的API的包装 47

4.4 Either数据类型 50

4.5 小结 52

5 严格求值和惰性求值 54

5.1 严格和非严格函数 55

5.2 一个扩展例子:惰性列表 57

5.2.1 对Stream保持记忆,避免重复运算 58

5.2.2 用于检测Stream的helper函数 59

5.3 把函数的描述与求值分离 59

5.4 无限流与共递归 62

5.5 小结 65

6 纯函数式状态 66

6.1 以副作用方式生成随机数 66

6.2 纯函数式随机数生成器 67

6.3 用纯函数式实现带状态的API 69

6.4 状态行为的更好的API 71

6.4.1 组合状态行为 71

6.4.2 嵌套状态行为 72

6.5 更通用的状态行为数据类型 74

6.6 纯函数式命令编程 74

6.7 小结 76

第二部分 功能设计和组合子库 77

7 纯函数式的并行计算 78

7.1 选择数据类型和函数 79

7.1.1 一种用于并行计算的数据类型 80

7.1.2 组合并行计算 82

7.1.3 显性分流 83

7.2 确定表现形式 85

7.3 完善API 86

7.4 API与代数 89

7.4.1 映射法则 90

7.4.2 分流法则 91

7.4.3 打破法则:一个微妙的bug 92

7.4.4 用Actor实现一个完全无阻塞的Par 94

7.5 完善组合子为更通用的形式 98

7.6 小结 100

8 基于性质的测试 101

8.1 基于性质测试概览 101

8.2 选择数据类型和函数 103

8.2.1 API的初始代码片段 103

8.2.2 性质的含义与API 104

8.2.3 生成器的意义和API 106

8.2.4 生成值决定生成器 107

8.2.5 精炼Prop的数据类型 108

8.3 最小化测试用例 109

8.4 使用库并改进其易用性 111

8.4.1 一些简单的例子 111

8.4.2 为并行计算编写测试套件 112

8.5 测试高阶函数及展望未来 116

8.6 生成器法则 117

8.7 小结 118

9 语法分析器组合子 119

9.1 代数设计,走起 120

9.2 一种可能的代数 124

9.2.1 切片和非空重复 125

9.3 处理上下文的相关性 127

9.4 写一个JSON分析器 128

9.4.1 JSON格式 129

9.4.2 JSON分析器 130

9.5 错误提示 130

9.5.1 一种可行的设计 131

9.5.2 错误嵌套 132

9.5.3 控制分支和回溯轨迹 133

9.6 实现代数 134

9.6.1 一种可能的实现 135

9.6.2 串化分析器 136

9.6.3 标记分析器 137

9.6.4 故障转移和回溯 138

9.6.5 上下文相关的分析 138

9.7 小结 140

第三部分 函数设计的通用结构 141

10 Monoid 142

10.1 什么是monoid 142

10.2 使用monoid折叠列表 144

10.3 结合律和并行化 145

10.4 例子:并行解析 147

10.5 可折叠数据结构 148

10.6 组合monoid 149

10.6.1 组装更加复杂的monoid 150

10.6.2 使用组合的monoid融合多个遍历 151

10.7 小结 151

11 Monad 152

11.1 函子:对map函数的泛化 152

11.1.1 函子法则 153

11.2 Monad:对flatMap和unit函数的泛化 154

11.3 Monadic组合子 157

11.4 单子定律 158

11.4.1 结合法则 158

11.4.2 为指定的monad证明结合法则 159

11.4.3 单位元法则 160

11.5 什么是monad 161

11.5.1 identity monad 162

11.5.2 状态monad和partial type application 163

11.6 小结 166

12 可应用和可遍历函子 167

12.1 泛化单子 167

12.2 Applicative trait 168

12.3 单子与可应用函子的区别 170

12.3.1 对比Option applicative与Option monad 170

12.3.2 对比Parser applicative与Parser monad 171

12.4 可应用函子的优势 172

12.4.1 不是所有的可应用函子都是Monad 173

12.5 可应用法则 175

12.5.1 Left and rightidentity 175

12.5.2 结合律 176

12.5.3 Naturalityofproduct 176

12.6 可遍历函子 178

12.7 使用Traverse 179

12.7.1 从monoid到可应用函子 180

12.7.2 带状态的遍历 181

12.7.3 组合可遍历结构 182

12.7.4 遍历融合 183

12.7.5 嵌套遍历 184

12.7.6 Monad组合 184

12.8 小结 185

第四部分 作用与I/O 187

13 外部作用和I/O 188

13.1 分解作用 188

13.2 一个简单的IO类型 189

13.2.1 处理输入效果 190

13.2.2 简单IO类型的优缺点 194

13.3 避免栈溢出 194

13.3.1 将一个控制流转化为数据构造子 195

13.3.2 Trampolining:栈溢出的通用解决方法 197

13.4 一个更微妙的IO类型 198

13.4.1 合理的monad 199

13.4.2 一个支持控制台I/O的monad 200

13.4.3 纯解释器 202

13.5 非阻塞和异步I/O 204

13.6 一个通用的IO类型 206

13.6.1 最终的main程序 206

13.7 为什么IO类型不足以支撑流式I/O 207

13.8 小结 209

14 本地影响和可变状态 210

14.1 纯函数式的可变状态 210

14.2 一种限制副作用范围的数据类型 212

14.2.1 受限可变性的语言表达 212

14.2.2 一种可变引用的代数表达 214

14.2.3 执行修改状态的行为 215

14.2.4 可变数组 217

14.2.5 一个纯函数的in-place快排实现 218

14.3 纯粹是相对于上下文的 219

14.3.1 副作用是什么? 221

14.4 小结 222

15 流式处理与增量I/O 223

15.1 命令式I/O的问题示例 223

15.2 一个简单的流转换器 225

15.2.1 创建Process 227

15.2.2 组合和追加处理 229

15.2.3 处理文件 231

15.3 可扩展的处理类型 232

15.3.1 来源 234

15.3.2 保证资源安全 235

15.3.3 单一输入过程 237

15.3.4 多个输入流 239

15.3.5 去向 241

15.3.6 Effectful通道 242

15.3.7 动态资源分配 243

15.4 应用场景 244

15.5 小结 245