《C++函数式编程》- Functional Programming in C++ - Ivan Čukić

来源:/books/c++/Functional Programming in C++.pdf 页数:321页文本型PDF,10.52MB 作者:Ivan Čukić(KDE核心开发者,贝尔格莱德大学数学系讲师)

核心观点

本书是首部系统讲解C++函数式编程范式的专著,由Manning出版社于2019年出版。作者Ivan Čukić是KDE核心开发者,从20世纪90年代末就开始使用C++,具有丰富的实战经验。

传统C++开发以面向对象为主,但C++实际上支持多种编程范式——过程式、泛型式和函数式。本书的核心论点是:函数式编程风格能让代码更易测试、更易于复用、更易于并行化,且错误更少。

全书结构(13章)

第一部分:函数式编程惯用法

章节主题核心内容
第1章函数式编程导论FP与OOP的关系、纯函数、函数式思维、C++作为FP语言的演进
第2章函数式编程入门高阶函数概念、STL中的高阶函数示例、自定义高阶函数
第3章函数对象函数指针、函数对象、Lambda表达式与闭包、std::function包装
第4章从旧函数创建新函数部分函数应用、柯里化、函数组合、函数提升
第5章纯函数:避免可变状态可变状态的陷阱、引用透明性、纯函数编程、const的重要性
第6章惰性求值C++中的惰性、惰性优化技术、通用记忆化、表达式模板
第7章范围(Ranges)range-v3库的使用、只读视图、无限范围、单词频率计算
第8章函数式数据结构不可变链表、位映射向量trie、持久化数据结构

第二部分:高级函数式软件设计

章节主题核心内容
第9章代数数据类型与模式匹配和类型(sum types)、std::variant、领域建模、Mach7模式匹配库
第10章单子(Monads)函子与单子、可选值处理、错误处理、状态处理、并发单子
第11章模板元编程编译时类型操作、模板元编程技巧、DSL构建
第12章并发系统的函数式设计Actor模型、响应式流、单子驱动的并发设计
第13章测试与调试单元测试与纯函数、属性测试、比较测试、Fuzzing

关键概念

1. 纯函数(Pure Functions)

  • 无副作用:不修改任何外部状态
  • 引用透明性:相同输入永远产生相同输出
  • 好处:易于测试、易于并行化、可缓存结果

2. 高阶函数(Higher-Order Functions)

  • 接受函数作为参数或返回函数的函数
  • STL中的典型例子:std::accumulate、std::for_each、std::transform、std::filter

3. 函数组合(Function Composition)

  • 将多个函数组合成单一函数:h(x) = g(f(x))
  • 支持管道的左结合和右结合两种风格

4. 柯里化(Currying)

  • 将多参数函数转换为一系列单参数函数
  • C++中可用模板元编程实现

5. 惰性求值(Lazy Evaluation)

  • 只在需要时才计算表达式的值
  • 应用场景:排序优化、UI视图、动态规划、表达式模板

6. 单子(Monads)

  • 抽象概念:函子 + bind操作 + 单位元
  • C++中的单子实例:
    • std::optional<T> - 可选值单子
    • expected<T, E> - 错误处理单子
    • std::future<T> - 并发单子
    • 响应式流 - 异步数据流单子

7. 范围(Ranges)

  • range-v3库提供的现代迭代器抽象
  • 支持管道操作:source | filter(f) | transform(g) | sink(h)
  • 无限范围:使用哨兵值标记结束

8. 不可变数据结构

  • 持久化数据结构:每次修改都保留旧版本
  • 不可变链表:头插/尾插/中间操作
  • 位映射向量trie:高效的持久化向量实现

实践价值

并发优势

// 函数式风格的并发设计
auto pipeline = source 
    | transform(trim)
    | filter([](const std::string& msg) { 
        return msg.length() > 0 && msg[0] != '#'; 
    })
    | transform(parse_json)
    | sink(process);

这种设计将数据流逻辑与异步性解耦,可以无缝切换同步/异步执行。

测试优势

  • 纯函数天然适合单元测试
  • 属性测试(Property-based Testing)自动生成测试用例
  • Fuzzing测试随机输入

错误处理

  • 使用std::optional和expected<T, E>替代异常
  • 类型系统强制处理错误情况
  • 单子组合支持链式错误处理

与其他书籍的关联

行动点

  1. 学习高阶函数:掌握std::accumulate、std::for_each等STL高阶函数的使用
  2. 理解lambda表达式:深入理解捕获列表、泛型lambda、移动语义
  3. 实践惰性求值:尝试用表达式模板实现惰性字符串连接
  4. 探索单子概念:从std::optional开始,理解monadic bind操作
  5. 使用range-v3:在现代C++项目中使用ranges库简化数据处理

评价

这本书填补了C++函数式编程领域的空白。对于有一定C++经验的开发者来说,它能提供全新的编程视角,帮助写出更安全、更简洁、更易测试的代码。虽然C++不是函数式语言,但通过合理使用FP惯用法,可以显著提升代码质量。