[读书笔记] 函数式编程 - 第三章 纯函数与副作用
第三章 纯函数与副作用
纯函数
纯函数:
输出确定(相同输入->相同输出)
没有副作用
c#实现: immutability, readonly, const, static, [Pure]
示例
public static List<string> GetTitlesOfGenre(List<Book> books, string genre){ return books .Where(b => b.Genre == genre) .Select(b => b.Title) .ToList();}
纯函数的优点
容易测试(不需要模拟环境,只要给输入就行)
可复用性高
容易调试(有问题只有可能是逻辑问题)
示例
private static Dictionary<TowerType, double> _damageModifiers = new(){ {TowerType.Cannon, 0.8}, // Takes 20% less d ...
[读书笔记] 函数式编程 - 第五章 错误处理
第五章 错误处理
传统派: 相信后人的智慧
函数式: 承认每一步都会失败
传统异常处理是“出问题 -> 跳出去 -> 另想办法”
函数式错误处理是“每步都承认有可能失败,提前规划好”
传统派 - try catch
具体移步-> c#错误处理
Result 类型
// 传统派public Product GetProduct(int id){ var product = _productRepository.Get(id); if (product is null) { throw new ProductNotFoundException($"找不到ID为 {id} 的产品。"); } return product;}// Resultpublic Result<Product, string> GetProduct(int id){ var product = _productRepositor ...
[读书笔记] 函数式编程 - 第二章 Expressions && Statements
第二章 Expressions && Statements
Expressions: 表达式
Statements: 语句
表达式和语句的区别
表达式: 有返回值
语句: 执行操作
// Expression20pagesPerChapterpagesPerChapter * 10Math.Max(a, b)//Statementvar pagesPerChapter = 20;var totalBookPages = pagesPerChapter * 10;Console.WriteLine("Hello");if (x > 0) { ... }for (int i = 0; i < 10; i++) { ... }//每个表达式都可以成为语句(加上分号)x + 2; // 语句形式,但它什么都不做
将语句转换为表达式的技巧
用 LINQ 替代集合操作语句
用三元运算符(?:)代替 if-else
用递归代替循环(for、while、foreach)
Yagur Alex - ...
[读书笔记] 函数式编程 - 第九章 柯里化
第九章 柯里化
什么是柯里化
DDDD
柯里化实践
识别函数:
有多个参数
似乎常只使用部分参数
参数上天然可以分阶段传入
定义函数:
将转化为一系列嵌套的单参数函数。每个函数返回另一个函数,直到所有参数都被传入
柯里化会导致一些繁琐,但在一些情况下,这会非常实用
如配置
public static Func<NotificationType, Func<int, Action<string>>>CurryNotificationConfig(){ return notificationType => maxNotificationsPerMinute => recipientEmail => { Console.WriteLine($"配置 {notificationType} 通知:收件人 {recipientEmail},每分钟最多 {maxNotificationsPerMinute ...
[读书笔记] 函数式编程 - 第八章 递归与尾递归
第八章 递归与尾递归
递归分类
普通递归: 递归调用·不是· 函数的最后一步
尾递归: 递归调用 ·是· 函数的最后一步
尾递归可以被编译器优化,以提高性能,防止栈溢出.
递归应该尽量尾递归
缓解堆栈溢出风险的策略
尾递归
别递了
增加堆栈大小:通过设置 System.Threading.Thread.MaxStackSize 属性
限制递归深度:递归实现时追踪递归深度,太深了直接抛异常
C#递归代码优雅手段
局部函数
void ProcessAndCountVideosInCategory(Category category){ int videoCount = 0; // 局部函数:递归统计视频数量 void CountVideos(Category cat) { foreach (var subcategory in cat.Subcategories) { CountVideos(subcategory); // 递归调用 ...
[读书笔记] 函数式编程 - 第六章 高阶函数与委托
第六章 高阶函数与委托
高阶函数
定义:
接受函数作为参数
或 返回函数作为结果
背景知识
Linq
筛选: Where
map: Select
聚合: Aggregation
代码建议
确保传递的函数是无状态的
努力维护不可变性
[读书笔记] 函数式编程 - 第十章 管道和组合
第十章 管道和组合
public static T Pipe<T>(this T source, params Func<T, T>[] funcs){ return funcs.Aggregate(source, (current, func) => func(current));}
[读书笔记] 函数式编程 - 第四章 诚实函数、null 与 Option
第四章 诚实函数、null 与 Option
诚实函数
诚实函数,我更愿意称其为: 可靠函数
诚实函数:
代码即文档,名称就是行为
健壮性强
// 非诚实函数public static int Divide(int numerator, int denominator){ return numerator / denominator;}//诚实函数public static int? Divide(int numerator, int denominator){ if(denominator == 0) return null; return numerator / denominator;}
null
破坏代码健壮性的一大元凶就是null
我们有一些方法来解决这个问题
解决null的最终兵器:Option 类型
Option 类型的值有两种可能:
Some(value):表示确实有值。
None(或 null 的替代):表示值缺失。
Option类型示例
public abstract cla ...
[读书笔记] 函数式编程原则
函数式编程原则
原则
优先使用表达式而不是语句
使用高阶函数
实现函数组合
Dos & Don’ts
Dos
尽力编写纯函数
隔离副作用
促进数据不可变性
使用 [Pure]
Don’ts
修改输入参数
忽视 [Pure]
忽略上下文: 盲目避免副作用,但实际上副作用是无可避免的
[读书笔记] 函数式编程理论
函数式编程理论
Function Programming With C#
函数式编程读书精粹
œ第一章 函数式编程基础
第二章 Expressions && Statements
第三章 纯函数与副作用
第四章 诚实函数、null 与 Option
第五章 错误处理
第六章 高阶函数与委托
第七章 函子与单子
第八章 递归与尾递归
第九章 柯里化
第十章 管道和组合
知乎-如何学习函数式编程
函数式编程原则
