// Copyright (c) 2025 GeWuYou // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. namespace GFramework.Core.functional.functions; /// /// 函数式编程扩展方法集合,提供柯里化、偏函数应用、重复执行、安全执行和缓存等功能 /// public static class FunctionExtensions { /// /// Curry:将二参数函数转换为柯里化形式 /// /// 第一个参数的类型 /// 第二个参数的类型 /// 函数返回结果的类型 /// 要柯里化的二参数函数 /// 柯里化后的函数,接受一个参数并返回另一个函数 public static Func> Curry( this Func func) => x => y => func(x, y); /// /// Uncurry:将柯里化函数转换回二参数函数 /// /// 第一个参数的类型 /// 第二个参数的类型 /// 函数返回结果的类型 /// 要取消柯里化的函数 /// 恢复为二参数的函数 public static Func Uncurry( this Func> func) => (x, y) => func(x)(y); /// /// Partial:部分应用函数(固定第一个参数) /// /// 第一个参数的类型 /// 第二个参数的类型 /// 函数返回结果的类型 /// 要部分应用的二参数函数 /// 要固定的第一个参数值 /// 部分应用后的函数,只接受第二个参数 public static Func Partial( this Func func, T1 firstArg) => x => func(firstArg, x); /// /// Repeat:重复执行函数n次 /// /// 输入值的类型 /// 初始输入值 /// 重复执行的次数 /// 要重复执行的函数 /// 经过多次变换后的最终值 public static TSource Repeat( this TSource value, int times, Func func) { var result = value; // 循环执行指定次数的函数调用 for (int i = 0; i < times; i++) { result = func(result); } return result; } /// /// Try:安全执行,捕获异常 /// /// 输入值的类型 /// 函数返回结果的类型 /// 要传递给函数的输入值 /// 要安全执行的函数 /// 包含执行状态、结果和错误信息的元组 public static (bool success, TResult? result, Exception? error) Try( this TSource value, Func func) { try { return (true, func(value), null); } catch (Exception ex) { return (false, default, ex); } } /// /// Memoize:缓存函数结果 /// /// 函数输入参数的类型 /// 函数返回结果的类型 /// 要缓存结果的函数 /// 带有缓存功能的包装函数 public static Func Memoize( this Func func) where TSource : notnull { var cache = new Dictionary(); return x => { // 尝试从缓存中获取结果 if (cache.TryGetValue(x, out var result)) return result; // 缓存未命中时计算结果并存储 result = func(x); cache[x] = result; return result; }; } /// /// Map:对单个对象应用函数 /// /// 源对象类型 /// 映射后的类型 /// 要映射的源对象 /// 转换函数 /// 映射后的对象 public static TResult Map( this TSource source, Func selector) => selector(source); }