第I部分 函數(shù)式工具包
第1章 學(xué)習(xí)函數(shù)式編程 3
1.1 也許你選擇本書(shū)是因?yàn)?hellip;…4
1.2 你應(yīng)掌握的背景知識(shí) 5
1.3 函數(shù)是什么樣的 6
1.4 認(rèn)識(shí)函數(shù) 7
1.5 當(dāng)代碼說(shuō)謊時(shí)…… 8
1.6 命令式與聲明式 9
1.7 小憩片刻:命令式與聲明式 10
1.8 解釋:命令式與聲明式 11
1.9 學(xué)習(xí)函數(shù)式編程的益處 12
1.10 進(jìn)入Scala 13
1.11 練習(xí)用Scala編寫(xiě)函數(shù) 14
1.12 準(zhǔn)備工具 15
1.13 了解REPL 16
1.14 編寫(xiě)你的第一個(gè)函數(shù) 17
1.15 如何使用本書(shū) 18
小結(jié) 19
第2章 純函數(shù) 21
2.1 為什么需要純函數(shù) 22
2.2 命令式編碼 23
2.3 破譯代碼 24
2.4 傳遞數(shù)據(jù)的副本 25
2.5 再次破譯代碼…… 26
2.6 重新計(jì)算而不是存儲(chǔ) 27
2.7 通過(guò)傳遞狀態(tài)來(lái)集中于邏輯 28
2.8 狀態(tài)去哪兒了 29
2.9 純函數(shù)和非純函數(shù)之間的區(qū)別 30
2.10 小憩片刻:將命令式代碼重構(gòu)為純函數(shù) 31
2.11 解釋:將命令式代碼重構(gòu)為純函數(shù) 32
2.12 純函數(shù)是值得信任的 34
2.13 程序語(yǔ)言中的純函數(shù) 35
2.14 保持純函數(shù)的難度…… 36
2.15 純函數(shù)和清潔代碼 37
2.16 小憩片刻:純函數(shù)還是非純函數(shù) 38
2.17 解釋:純函數(shù)還是非純函數(shù) 39
2.18 使用Scala編寫(xiě)純函數(shù) 40
2.19 用Scala練習(xí)純函數(shù) 41
2.20 測(cè)試純函數(shù) 42
2.21 小憩片刻:測(cè)試純函數(shù) 43
2.22 解釋:測(cè)試純函數(shù) 44
小結(jié) 45
第3章 不可變值 47
3.1 引擎的燃料 48
3.2 不可變性的另一種情況 49
3.3 你會(huì)相信這個(gè)函數(shù)嗎 50
3.4 可變性是危險(xiǎn)的 51
3.5 回顧:說(shuō)謊的函數(shù)…… 52
3.6 使用副本對(duì)抗可變性 53
3.7 小憩片刻:可變性帶來(lái)的困擾 54
3.8 解釋:可變性帶來(lái)的困擾 55
3.9 引入共享可變狀態(tài) 58
3.10 狀態(tài)對(duì)編程能力的影響 59
3.11 處理移動(dòng)部分 60
3.12 使用FP處理移動(dòng)部分 61
3.13 Scala中的不可變值 62
3.14 建立對(duì)不可變性的直覺(jué) 63
3.15 小憩片刻:不可變的
String API 64
3.16 解釋:不可變的String API 65
3.17 等等,這不是更糟糕嗎 66
3.18 純函數(shù)解法解決共享可變狀態(tài)問(wèn)題 67
3.19 練習(xí)不可變的切分和追加 69
小結(jié) 70
第4章 函數(shù)作為值 71
4.1 將要求實(shí)現(xiàn)為函數(shù) 72
4.2 非純函數(shù)和可變值反擊 73
4.3 使用Java Streams對(duì)列表進(jìn)行排序 74
4.4 函數(shù)特征標(biāo)記應(yīng)說(shuō)明全部情況 75
4.5 更改要求 76
4.6 只是在傳遞代碼 77
4.7 使用Java的Function值 78
4.8 使用Function語(yǔ)法處理代碼重復(fù)問(wèn)題 79
4.9 將用戶定義的函數(shù)作為參數(shù)傳遞 80
4.10 小憩片刻:將函數(shù)作為參數(shù) 81
4.11 解釋:將函數(shù)作為參數(shù) 82
4.12 閱讀函數(shù)式Java的問(wèn)題 83
4.13 在Scala中傳遞函數(shù) 84
4.14 深入了解sortBy 85
4.15 在Scala中具有函數(shù)參數(shù)的特征標(biāo)記 86
4.16 在Scala中將函數(shù)作為參數(shù)傳遞 87
4.17 練習(xí)函數(shù)傳遞 88
4.18 采用聲明式編程 89
4.19 將函數(shù)傳遞給自定義函數(shù) 90
4.20 小函數(shù)及其職責(zé) 91
4.21 內(nèi)聯(lián)傳遞函數(shù) 92
4.22 小憩片刻:在Scala中傳遞函數(shù) 93
4.23 解釋:在Scala中傳遞函數(shù) 94
4.24 僅通過(guò)傳遞函數(shù)還能實(shí)現(xiàn)什么功能呢 95
4.25 將函數(shù)應(yīng)用于列表中的每個(gè)元素 96
4.26 使用map將函數(shù)應(yīng)用于列表的每個(gè)元素 97
4.27 了解map 98
4.28 練習(xí)使用map 99
4.29 學(xué)習(xí)一次,隨處適用 100
4.30 根據(jù)條件返回列表的部分內(nèi)容 101
4.31 使用filter返回列表的部分內(nèi)容 102
4.32 了解filter 103
4.33 練習(xí)filter 104
4.34 迄今為止的旅程…… 105
4.35 避免重復(fù)自己 106
4.36 API是否易于使用 107
4.37 添加一個(gè)新參數(shù)不足以解決問(wèn)題 108
4.38 函數(shù)可以返回函數(shù) 109
4.39 使用可以返回函數(shù)的函數(shù) 110
4.40 函數(shù)就是值 111
4.41 小憩片刻:返回函數(shù) 112
4.42 解釋:返回函數(shù) 113
4.43 設(shè)計(jì)函數(shù)式API 114
4.44 函數(shù)式API的迭代設(shè)計(jì) 115
4.45 從返回的函數(shù)中返回函數(shù) 116
4.46 如何從返回的函數(shù)中返回函數(shù) 117
4.47 使用返回函數(shù)構(gòu)建的靈活A(yù)PI 118
4.48 在函數(shù)中使用多個(gè)參數(shù)列表 119
4.49 使用柯里化 120
4.50 練習(xí)柯里化 121
4.51 通過(guò)傳遞函數(shù)值進(jìn)行編程 122
4.52 將許多值縮減為單個(gè)值 123
4.53 使用foldLeft將多個(gè)值縮減為一個(gè) 124
4.54 了解foldLeft 125
4.55 foldLeft用者須知 126
4.56 練習(xí)foldLeft 127
4.57 建模不可變數(shù)據(jù) 128
4.58 使用具有高階函數(shù)的求積類型 129
4.59 內(nèi)聯(lián)函數(shù)的更簡(jiǎn)潔語(yǔ)法 130
小結(jié) 131
第II部分 函數(shù)式程序
第5章 順序程序 135
5.1 編寫(xiě)基于流水線的算法 136
5.2 根據(jù)小模塊構(gòu)建大型程序 137
5.3 命令式解法 138
5.4 flatten和flatMap 139
5.5 使用多個(gè)flatMap的實(shí)際案例 140
5.6 flatMap和列表大小的更改 141
5.7 小憩片刻:處理由列表組成的列表 142
5.8 解釋:處理由列表組成的列表 143
5.9 連接的flatMap和map 144
5.10 嵌套的flatMap 145
5.11 依賴其他值的值 146
5.12 練習(xí)嵌套的flatMap 147
5.13 更好的嵌套 flatMap 語(yǔ)法 148
5.14 使用for推導(dǎo)式 149
5.15 小憩片刻:flatMap與for推導(dǎo)式 150
5.16 解釋:flatMap與for推導(dǎo)式 151
5.17 了解for推導(dǎo)式 152
5.18 這不是你想要的for 153
5.19 在for推導(dǎo)式內(nèi)部 154
5.20 更復(fù)雜的for推導(dǎo)式 155
5.21 使用for推導(dǎo)式檢查所有組合 156
5.22 過(guò)濾技術(shù) 157
5.23 小憩片刻:過(guò)濾技術(shù) 158
5.24 解釋:過(guò)濾技術(shù) 159
5.25 抽象化 160
5.26 比較map、foldLeft和flatMap 161
5.27 使用Set的for推導(dǎo)式 162
5.28 使用多種類型的for推導(dǎo)式 163
5.29 練習(xí)for推導(dǎo)式 164
5.30 再次定義for推導(dǎo)式 165
5.31 使用非集合類型的for推導(dǎo)式 166
5.32 避免null函數(shù):Option類型 167
5.33 解析為流水線 168
5.34 小憩片刻:使用Option進(jìn)行解析 169
5.35 解釋:使用Option進(jìn)行解析 170
小結(jié) 171
第6章 錯(cuò)誤處理 173
6.1 從容處理許多不同的錯(cuò)誤 174
6.2 是否可能處理所有問(wèn)題 175
6.3 按照播出時(shí)長(zhǎng)對(duì)電視節(jié)目列表進(jìn)行排序 176
6.4 實(shí)現(xiàn)排序要求 177
6.5 處理來(lái)自外部世界的數(shù)據(jù) 178
6.6 函數(shù)式設(shè)計(jì):利用小代碼塊構(gòu)建 179
6.7 將String解析為不可變對(duì)象 180
6.8 解析一個(gè)List只是解析一個(gè)元素 181
6.9 將String解析為T(mén)vShow 182
6.10 如何處理潛在錯(cuò)誤 183
6.11 返回null是不是一個(gè)好辦法 184
6.12 如何更從容地處理潛在錯(cuò)誤 185
6.13 實(shí)現(xiàn)返回Option的函數(shù) 186
6.14 Option強(qiáng)制處理可能的錯(cuò)誤 187
6.15 基于小代碼塊進(jìn)行構(gòu)建 188
6.16 函數(shù)式設(shè)計(jì)是基于小代碼塊進(jìn)行構(gòu)建 189
6.17 編寫(xiě)一個(gè)小而安全的函數(shù),使其返回一個(gè)Option 190
6.18 函數(shù)、值和表達(dá)式 192
6.19 練習(xí)返回Option的安全函數(shù) 193
6.20 錯(cuò)誤如何傳播 194
6.21 值代表錯(cuò)誤 195
6.22 Option、for推導(dǎo)式和已檢查的異常 196
6.23 已檢查異常怎么樣 197
6.24 條件恢復(fù) 198
6.25 使用命令式風(fēng)格進(jìn)行條件恢復(fù) 199
6.26 使用函數(shù)式的條件恢復(fù) 200
6.27 已檢查異常不可組合,但Option可以 201
6.28 orElse的工作原理 202
6.29 練習(xí)函數(shù)式錯(cuò)誤處理 203
6.30 即使存在錯(cuò)誤,仍組合函數(shù) 204
6.31 編譯器提醒需要覆蓋錯(cuò)誤 205
6.32 編譯錯(cuò)誤對(duì)我們有好處 206
6.33 將由Option組成的List轉(zhuǎn)換為扁平 List 207
6.34 讓編譯器成為我們的向?qū)?208
6.35 不要過(guò)于相信編譯器 209
6.36 小憩片刻:錯(cuò)誤處理策略 210
6.37 解釋:錯(cuò)誤處理策略 211
6.38 兩種不同的錯(cuò)誤處理策略 212
6.39 孤注一擲錯(cuò)誤處理策略 213
6.40 將Option組成的List折疊為一個(gè)List的Option 214
6.41 現(xiàn)已知道如何處理多個(gè)可能的錯(cuò)誤 215
6.42 如何知道哪里出錯(cuò)了 216
6.43 需要在返回值中傳達(dá)錯(cuò)誤的詳細(xì)信息 217
6.44 使用Either傳達(dá)錯(cuò)誤詳情 218
6.45 重構(gòu)以使用Either 219
6.46 返回Either而不是Option 220
6.47 練習(xí)返回Either的安全函數(shù) 223
6.48 學(xué)到的Option相關(guān)知識(shí)也適用于Either 224
6.49 小憩片刻:使用Either進(jìn)行錯(cuò)誤處理 225
6.50 解釋:用Either進(jìn)行錯(cuò)誤處理 226
6.51 使用Option/Either進(jìn)行工作 227
小結(jié) 228
第7章 作為類型的要求 229
7.1 建模數(shù)據(jù)以盡量減少程序員的錯(cuò)誤 230
7.2 精心建模的數(shù)據(jù)不會(huì)說(shuō)謊 231
7.3 使用已知內(nèi)容(即原始類型)進(jìn)行設(shè)計(jì) 232
7.4 使用建模為原始類型的數(shù)據(jù) 233
7.5 小憩片刻:原始類型之苦 234
7.6 解釋:原始類型之苦 235
7.7 使用原始類型建模的問(wèn)題 236
7.8 使用原始類型加大工作難度 237
7.9 newtype使參數(shù)不被錯(cuò)放 238
7.10 在數(shù)據(jù)模型中使用newtype 239
7.11 練習(xí)newtype 240
7.12 確保只存在有效數(shù)據(jù)組合 241
7.13 建模數(shù)據(jù)缺失的可能性 242
7.14 模型變化導(dǎo)致邏輯變化 243
7.15 在邏輯中使用建模為Option的數(shù)據(jù) 244
7.16 高階函數(shù)獲勝 245
7.17 可能存在符合要求的高階函數(shù) 246
7.18 小憩片刻:forall/exists/contains 247
7.19 解釋:forall/exists/contains 248
7.20 將概念耦合在單個(gè)求積類型內(nèi) 249
7.21 建模有限可能性 250
7.22 使用求和類型 251
7.23 使用求和類型改善模型 252
7.24 使用求和類型 求積類型的組合 253
7.25 求積類型 求和類型=代數(shù)數(shù)據(jù)類型 254
7.26 在行為(函數(shù))中使用基于ADT的模型 255
7.27 使用模式匹配解構(gòu)ADT 256
7.28 重復(fù)和DRY 257
7.29 練習(xí)模式匹配 258
7.30 實(shí)際應(yīng)用中的newtype、ADT和模式匹配 259
7.31 如何繼承呢 260
7.32 小憩片刻:函數(shù)式數(shù)據(jù)設(shè)計(jì) 261
7.33 解釋:函數(shù)式數(shù)據(jù)設(shè)計(jì) 262
7.34 建模行為 263
7.35 將行為建模為數(shù)據(jù) 264
7.36 使用基于ADT的參數(shù)實(shí)現(xiàn)函數(shù) 265
7.37 小憩片刻:設(shè)計(jì)與可維護(hù)性 266
7.38 解釋:設(shè)計(jì)與可維護(hù)性 267
小結(jié) 268
第8章 作為值的IO 269
8.1 與外界交流 270
8.2 與外部 API 集成 271
8.3 具有副作用的IO操作的屬性 272
8.4 帶有副作用的IO代碼的命令式解決方案 273
8.5 命令式IO方案存在許多問(wèn)題 274
8.6 能通過(guò)FP完善方案嗎 275
8.7 執(zhí)行IO與使用IO的結(jié)果 276
8.8 命令式處理IO 277
8.9 作為IO值的計(jì)算 278
8.10 IO 值 279
8.11 實(shí)際運(yùn)行中的IO值 280
8.12 將非純性排出 281
8.13 使用從兩個(gè)IO操作獲取的值 282
8.14 將兩個(gè)IO值組合成單個(gè)IO值 283
8.15 練習(xí)創(chuàng)建和組合IO值 284
8.16 僅使用值來(lái)解決問(wèn)題 285
8.17 IO類型是病毒性的 286
8.18 小憩片刻:使用值 287
8.19 解釋:使用值 288
8.20 向函數(shù)式IO前進(jìn) 289
8.21 如何處理IO故障 290
8.22 運(yùn)行由IO描述的程序可能會(huì)失敗 291
8.23 記得orElse嗎 292
8.24 惰性求值和及早求值 293
8.25 使用IO.orElse實(shí)現(xiàn)恢復(fù)策略 294
8.26 使用orElse和pure實(shí)現(xiàn)回退 295
8.27 練習(xí)IO值的故障恢復(fù) 296
8.28 應(yīng)該在哪里處理潛在的故障 297
8.29 具有故障處理的函數(shù)IO 298
8.30 純函數(shù)不會(huì)說(shuō)謊,即使在
不安全的世界中也是如此 299
8.31 函數(shù)式架構(gòu) 300
8.32 使用IO存儲(chǔ)數(shù)據(jù) 301
8.33 小憩片刻:使用IO存儲(chǔ)數(shù)據(jù) 304
8.34 解釋:使用IO存儲(chǔ)數(shù)據(jù) 305
8.35 將一切視為值 306
8.36 將重試作為值處理 307
8.37 將未知數(shù)量的API調(diào)用視為值 309
8.38 練習(xí):培養(yǎng)函數(shù)特征標(biāo)記的直覺(jué) 311
小結(jié) 312
第9章 作為值的流 313
9.1 無(wú)限超越 314
9.2 處理未知數(shù)量的值 315
9.3 處理外部非純的API調(diào)用(再次) 316
9.4 函數(shù)式設(shè)計(jì)方案 317
9.5 不可變映射 318
9.6 練習(xí)不可變映射 319
9.7 應(yīng)該進(jìn)行多少I(mǎi)O調(diào)用 320
9.8 自下而上的設(shè)計(jì) 321
9.9 高級(jí)列表操作 322
9.10 引入元組 323
9.11 zip和drop 324
9.12 元組模式匹配 325
9.13 小憩片刻:使用映射和元組 326
9.14 解釋:使用映射和元組 327
9.15 函數(shù)拼圖 328
9.16 跟蹤自下而上設(shè)計(jì)中的類型 329
9.17 原型制作和死胡同 330
9.18 遞歸函數(shù) 331
9.19 無(wú)限和惰性 332
9.20 遞歸函數(shù)結(jié)構(gòu) 333
9.21 處理未來(lái)的空值(使用遞歸函數(shù)) 334
9.22 無(wú)限遞歸調(diào)用的有用性 335
9.23 小憩片刻:遞歸和無(wú)限 336
9.24 解釋:遞歸和無(wú)限 337
9.25 使用遞歸創(chuàng)建不同的IO程序 338
9.26 使用遞歸進(jìn)行任意數(shù)量的調(diào)用 339
9.27 遞歸版本的問(wèn)題 340
9.28 引入數(shù)據(jù)流 341
9.29 命令式語(yǔ)言中的Stream 342
9.30 按需生成值 343
9.31 流處理、生產(chǎn)者和消費(fèi)者 344
9.32 流和IO 345
9.33 函數(shù)式Stream 346
9.34 FP中的流是值 347
9.35 流是遞歸值 348
9.36 原始操作和組合器 349
9.37 基于IO值的流 350
9.38 基于IO值的無(wú)限流 351
9.39 為副作用而執(zhí)行 352
9.40 練習(xí)流操作 353
9.41 利用流的功能 354
9.42 API調(diào)用的無(wú)限流 355
9.43 在流中處理IO故障 356
9.44 分離的關(guān)注點(diǎn) 357
9.45 滑動(dòng)窗口 358
9.46 等待IO調(diào)用 360
9.47 組合流 361
9.48 使用基于流的方案的好處 362
小結(jié) 363
第10章 并發(fā)程序 365
10.1 無(wú)處不在的線程 366
10.2 聲明式并發(fā) 367
10.3 順序與并發(fā) 368
10.4 小憩片刻:順序性思考 369
10.5 解釋:順序性思考 370
10.6 需要進(jìn)行批處理 371
10.7 批處理實(shí)現(xiàn) 372
10.8 并發(fā)世界 373
10.9 并發(fā)狀態(tài) 374
10.10 命令式并發(fā) 375
10.11 原子引用 377
10.12 引入Ref 378
10.13 更新Ref值 379
10.14 使用Ref值 380
10.15 讓一切并行運(yùn)行 381
10.16 parSequence的實(shí)際應(yīng)用 382
10.17 練習(xí)并發(fā)IO 384
10.18 建模并發(fā)性 385
10.19 使用Ref和Fiber進(jìn)行編碼 386
10.20 無(wú)限運(yùn)行的IO 388
10.21 小憩片刻:并發(fā)性思考 389
10.22 解釋:并發(fā)性思考 390
10.23 需要異步性 391
10.24 為異步訪問(wèn)做準(zhǔn)備 392
10.25 設(shè)計(jì)函數(shù)式異步程序 393
10.26 手動(dòng)管理Fiber 394
10.27 編寫(xiě)函數(shù)式異步程序 395
小結(jié) 396
第III部分 應(yīng)用函數(shù)式編程
第11章 設(shè)計(jì)函數(shù)式程序 399
11.1 有效、準(zhǔn)確、快速 400
11.2 使用不可變值建模 401
11.3 業(yè)務(wù)領(lǐng)域建模和FP 402
11.4 數(shù)據(jù)訪問(wèn)建模 403
11.5 函數(shù)包 404
11.6 作為純函數(shù)的業(yè)務(wù)邏輯 405
11.7 分離真正的數(shù)據(jù)訪問(wèn)問(wèn)題 406
11.8 使用命令式庫(kù)和IO與API集成 407
11.9 遵循設(shè)計(jì) 410
11.10 將輸入操作作為IO值實(shí)現(xiàn) 411
11.11 將庫(kù)IO與其他關(guān)注點(diǎn)分離 413
11.12 柯里化和控制反轉(zhuǎn) 414
11.13 作為值的函數(shù) 415
11.14 串聯(lián)知識(shí) 416
11.15 我們做到了 417
11.16 使業(yè)務(wù)邏輯正確 418
11.17 資源泄漏 419
11.18 處理資源 420
11.19 使用Resource值 421
11.20 我們做對(duì)了 422
11.21 小憩片刻:加快速度 423
11.22 解釋:加快速度 424
小結(jié) 425
第12章 測(cè)試函數(shù)式程序 427
12.1 你對(duì)其進(jìn)行測(cè)試嗎 428
12.2 測(cè)試只是函數(shù) 429
12.3 選擇要測(cè)試的函數(shù) 430
12.4 提供示例進(jìn)行測(cè)試 431
12.5 通過(guò)示例練習(xí)測(cè)試 432
12.6 生成好示例 433
12.7 生成屬性 434
12.8 基于屬性的測(cè)試 435
12.9 提供屬性進(jìn)行測(cè)試 436
12.10 通過(guò)傳遞函數(shù)來(lái)委派工作 437
12.11 了解基于屬性測(cè)試的失敗原因 438
12.12 測(cè)試錯(cuò)誤還是存在錯(cuò)誤 439
12.13 自定義生成器 440
12.14 使用自定義生成器 441
12.15 以可讀的方式測(cè)試更復(fù)雜的場(chǎng)景 442
12.16 查找并修復(fù)實(shí)現(xiàn)中的錯(cuò)誤 443
12.17 小憩片刻:基于屬性的測(cè)試 444
12.18 解釋:基于屬性的測(cè)試 445
12.19 屬性和示例 446
12.20 要求范圍 447
12.21 測(cè)試具有副作用的要求 448
12.22 確定工作所需的正確測(cè)試 449
12.23 數(shù)據(jù)使用測(cè)試 450
12.24 練習(xí)使用IO存根外部服務(wù) 452
12.25 測(cè)試和設(shè)計(jì) 453
12.26 服務(wù)集成測(cè)試 454
12.27 本地服務(wù)器作為集成測(cè)試中的資源 455
12.28 編寫(xiě)單獨(dú)集成測(cè)試 456
12.29 與服務(wù)集成是單一職責(zé) 457
12.30 小憩片刻:編寫(xiě)集成測(cè)試 458
12.31 解釋:編寫(xiě)集成測(cè)試 459
12.32 集成測(cè)試耗時(shí)更長(zhǎng) 460
12.33 基于屬性的集成測(cè)試 461
12.34 選擇正確的測(cè)試方案 462
12.35 測(cè)試驅(qū)動(dòng)開(kāi)發(fā) 463
12.36 為不存在的功能編寫(xiě)測(cè)試 464
12.37 紅綠重構(gòu) 465
12.38 讓測(cè)試通過(guò) 466
12.39 增加紅色測(cè)試 467
12.40 最后的TDD迭代 468
小結(jié) 469
結(jié)語(yǔ) 470
以下內(nèi)容可通過(guò)掃描封底二維碼下載
附錄A Scala 速查表 471
附錄B 函數(shù)式重點(diǎn) 477