学习地图:第一版三部分十五章
以Manning第一版权威目录组织3部分15章,建立value、composition、effect与operation四层学习证据。
学习目标
- 能说出第一版3部分15章的准确顺序,并解释每部分解决的程序设计问题
- 能分析value、composition、effect与operation四层依赖,判断自己缺少哪一层证据
- 能设计一条适合当前项目的阅读与实践路线,把每章实验映射到真实workflow
为什么先锁定这张地图对应哪一本书
本体系严格对应Enrico Buonanno的 Functional Programming in C#: How to write better C# code 第一版,Manning于2017年8月出版,ISBN 9781617293955。权威目录是3部分、15章,不是旧站点里按主题抽样出的“十章”。地图保留原书一级主题顺序,同时把每章转成可运行、可观察、可复查的C#工程门禁。
先预测:函数式C#只需要LINQ吗;pure function足以解决并发写入吗;Map/Bind名字相同就能任意互换context吗;Task和Either可压成同一个字符串错误吗;agent一次处理一条message就天然可靠。答案都是否。
↡以出版社第一版目录为边界,15个章节单元及其一级主题都必须在内容与导航中一一出现。三部分十五章总览
Part 1 “Core concepts”覆盖第1–5章:从函数式编程的目标出发,经purity、function signatures/types、常用patterns,到function composition。退出条件不是记住术语,而是能把一个有I/O的use case拆成pure decision core和effectful shell,并用types暴露absence、failure与dependency。
Part 2 “Becoming functional”覆盖第6–10章:typed error handling、application wiring、multi-argument composition、functional data与event sourcing。它把局部函数技巧推进到application architecture,要求读者处理client error contract、immutable state version、expected-version write与projection rebuild。
Part 3 “Advanced techniques”覆盖第11–15章:lazy/continuation、state computation、async、Reactive Extensions与message passing。重点转向evaluation time、resource lifetime、cancellation、stream terminal、mailbox capacity与recovery。函数组合仍是工具,但验收对象已是完整effect lifecycle。
↡从pure values与signatures起步,经Map/Bind/fold组合,再进入async、stream和concurrency lifecycle的学习递进。切换三部分与章节出口
Part 1 Core concepts Chapters 1-5
Part 2 Becoming functional Chapters 6-10
Part 3 Advanced techniques Chapters 11-15第一层:Functions and values
第1–3章建立基础:function作为value、purity/referential transparency、type-driven signatures。先学会列出一个function的显式input/output,再寻找clock、random、database、mutable field等隐藏输入。Option/Either/Validation不是装饰语法,而是让absence与expected failure进入type,使caller不能假装它们不存在。
这一层的验收是替换能力:同一个pure core可注入不同policy/function;同样输入重复运行得到同样输出;boundary adapter能把exception/null/DTO翻译为canonical domain type。测试必须包含boundary值、invalid input和effect count,不能只跑happy path。
↡把domain decision保持deterministic,并在输入输出边界显式传入clock、storage等effect capability的结构。Either<Error, Decision> Decide(State state, Command command) =>
Validate(command)
.Bind(valid => ApplyPolicy(state, valid));
Task Persist(Decision decision, CancellationToken token) =>
interpreter.Execute(decision.Effects, token);第二层:Patterns and composition
第4–8章把小函数组装成program:Map只改变context内value,Bind表达dependent next step,Apply组合independent elevated values,fold把ordered inputs归约为state,partial application固定dependencies。理解pattern的关键是写出每一步type和observable law,不是把所有helper命名为Monad。
Application structure由composition root构造:先验证configuration与long-lived dependencies,再为request建立scoped functions。Error handling区分absence、validation、business rejection与unexpected fault;delivery boundary把typed outcome映射为stable client contract。多参数函数则要求判断currying/partial、method resolution以及Applicative/Monad dependency差异。
↡在Map、Bind、Apply、fold和partial application之间按dependency与error semantics选择,而不隐藏effect的组合边界。切换value、compose、effect与operate
第三层:Data, state, and persistence
第9–12章连续追问“状态在哪里”。Immutable value仍需atomic publication;persistent data structure保留旧version但不等于disk persistence;event sourcing以facts为source of truth,却带来schema evolution、projection lag和rebuild责任。State computation适合pure in-memory threading,不替代database transaction或concurrent store protocol。
实践时为每个state写identity、version、owner、transition和publish规则。Random generator把seed显式化后成为pure state transition;event fold按ordered history重建state;snapshot只是可丢弃优化。任何“可重放”都要用golden stream、old schema reader、checkpoint与fault injection证明。
load(version) -> pure decide -> effects/new state
| |
+--- conflict/reload <--- compare-and-swap
event log -> fold -> state -> projection -> query view第四层:Effect lifecycles and concurrency
第11、13–15章要求把时间纳入contract。Lazy与memoization区分evaluation timing/count;Try只捕获明确throwing boundary;Task区分invocation、hot handle、fault/cancel;IObservable包含Next/terminal/dispose与scheduler;message passing包含enqueue、handle、reply、timeout、dedup和supervision。
共同验收方法是画timeline:何时创建resource、何时启动effect、谁拥有cancel/dispose、terminal是什么、retry是否重复effect。再加capacity:Task traverse的in-flight、Observable queue、agent mailbox、projection replay都必须有上限或明确durability。没有这些,函数式syntax只是把风险移动到更难看见的位置。
↡对lazy、Task、Observable与mailbox统一追踪启动、资源所有权、terminal、retry和capacity的工程视角。三条阅读路线
首次系统学习按1–15顺序,每章先做“先预测”,再运行三组图解,最后完成练习和一个真实代码迁移。已有domain modeling经验者可重点走1–10,再按当前effect选11/13/14/15;异步并发专项可走2、4、6、8、11、13–15,但不能跳过purity与typed error prerequisites。
复查路线从地图开始,随机抽两章解释signature/failure/lifecycle,再做总复习的release gate。若只能背概念而不能给出fault evidence,就回到对应章节。书的完成标准是15章内容、导航、题库和MDX/type gates全部通过,不是“看过目录”。
切换new、domain、async与review路线
每章统一验收法
每章至少交付:三条可验收目标、原书一级主题覆盖、三组章节专属图解、三段可复现代码、两个陷阱、三个练习、五个术语。质量分只是结构底线;真正复查还要确认示例名称、failure和tradeoff属于本章,而非复制模板。
工程验收分四类:correctness(example/property/law)、compatibility(consumer/schema matrix)、capacity(load/bounds)、recovery(fault/replay/runbook)。按章节风险选择,不要求每章平均使用,但高级effect章节不能缺terminal和failure injection。
本章回顾:从目录到可执行学习系统
- 第一版有3部分15章,导航和内容必须与publisher outline一一对应。
- Part 1建立pure values与types,Part 2扩展为application/data architecture,Part 3处理effect lifecycle。
- Map/Bind/Apply等抽象必须保留dependency、error和law evidence。
- State与concurrency的正确性依赖ownership、version、capacity和recovery,而非immutable口号。
- 学习完成以代码、fault test和解释证据判断,不以阅读进度判断。
练习
问题 1:第一版三部分分别解决什么问题?
问题 2:怎样判断一个项目应该从哪章开始?
问题 3:为何地图还要包含production gates?
术语表
名词解释
本章出现的专业名词,用大白话再讲一遍。
- first-edition outline contract
- composition dependency chain
- functional core boundary
- typed composition boundary
- effect lifecycle evidence