// 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. using GFramework.Core.functional.types; 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; } /// /// 尝试执行一个转换函数,并将结果包装在Result对象中,捕获可能发生的异常 /// /// 输入值的类型 /// 转换函数返回值的类型 /// 要进行转换操作的源值 /// 用于转换源值的函数委托 /// 如果转换成功则返回包含结果的成功状态,如果发生异常则返回包含异常信息的失败状态 public static Result TryResult( this TSource value, Func func) { // 执行转换函数并处理可能的异常 try { return Result.Success(func(value)); } catch (Exception ex) { return Result.Failure(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); }