博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#函数式程序设计之局部套用与部分应用
阅读量:5305 次
发布时间:2019-06-14

本文共 1904 字,大约阅读时间需要 6 分钟。

函数式设计的核心与函数的应用以及函数如何作为算法的基本模块有关。利用局部套用技术可以把所有函数看成是函数类的成员,这些函数只有一个形参,有了局部套用,才有部分应用。部分应用是使函数模块化成为可能的两个技术之一,另一个是组合。

C#函数式程序设计之参数的解耦

局部套用是一种转换技术,它把一个需要接收多个参数的函数转换为一系列函数,后者每次只接受一个参数并返回序列中的下一个函数。在这个函数链的末尾,所有的参数都可以使用,并允许原算法执行自己的操作。

考虑下面这个简单的函数,它使用了与C#2.0兼容的匿名方法定义语法:

Func
add = delegate(int x, int y) { return x + y; };

这个加法函数接受两个参数后返回两个数的相加结果,调用这个函数时,调用程序必须同时提供两个参数,C#语法约束不允许任何其他方法。

要把局部套用技术应用于这个函数,意味着要创建一个一次只能接受一个参数且返回下一个函数的函数,即如下:

Func
> add = delegate(int x) { return delegate(int y) { return x + y; }; };

局部套用的基本原理也可以应用于用Lambda语法定义的函数:

Func
addTest = (x, y) => x + y;

使用局部套用后的函数如下:

Func
> addTest = x => (y => x + y);

现在把局部套用技术应用于任意个参数上,假设有一个函数有以下的参数列表:

Func<...> f = (part1, part2, part3, ..., partX) => ...;

局部套用后的函数签名格式如下:

Func<...> cf = part1 => part2 => part3 => ... => partX => ...;

Lambda表达式主体部分代码,即最后一个=> 运算符的右侧部分,在转换过程中保持不变。

类型排列形式的变化遵从同样的规则,考虑如下的泛型委托类型:

Func

应用局部套用后得到如下的类型排列形式:

Func
>>>

有趣的是,如果显式提供Lambda表达式的类型或者C#2.0匿名方法的类型,则采用类型推断也可以推断出泛型参数,这令人感到奇怪,因为在同样的情形下,无法用var关键字把函数保存到一个变量中:

// this is invalidvar mult = (int x, int y) => x * y;

对于内联的Lambda表达式无法调用扩展方法。

局部套用技术也可以应用于C#类声明的比较常规的方法。静态方法和实例方法都可以应用局部套用技术。此外,类使得局部套用函数的外部调用成为可能。

C#函数式程序设计之调用函数的各部分

使用局部套用格式函数的最主要理由是只需要部分计算参数而不是全部参数就可以调用这个函数。这个过程就是所谓的部分应用,部分应用是一种函数构建技术。

考虑下面这段代码,它使用一个从零开始采用局部套用格式的函数:

Func
> add = x => y => x + y;var add5 = add(5);

这里调用了局部套用函数add,但是只给它传递一个参数,显然, 在这种情况下无法进行加法计算,因为它需要两个参数,用一个参数调用将返回一个新函数。我们不是立即调用这个新函数,而是把它保存在变量中供以后使用。

调用这个新创建的函数可以像调用其他函数那样:

int result = add5(37);

通常,部分应用接受一个本质属于泛型的函数,创建一个毕竟专用的新函数。

C#函数式程序设计之参数顺序的重要性

当应用局部套用技术和部分应用技术时,说明参数顺序的重要性有一个简单的理由:函数的部分应用只能从参数列表的起始位置开始。在决定参数的顺序时,最重要的是考虑函数中哪个参数最有可能使用部分应用。

转载于:https://www.cnblogs.com/Ribbon/p/3643042.html

你可能感兴趣的文章
MyBaits学习
查看>>
管道,数据共享,进程池
查看>>
CSS
查看>>
[LeetCode] 55. Jump Game_ Medium tag: Dynamic Programming
查看>>
[Cypress] Stub a Post Request for Successful Form Submission with Cypress
查看>>
程序集的混淆及签名
查看>>
判断9X9数组是否是数独的java代码
查看>>
00-自测1. 打印沙漏
查看>>
UNITY在VS中调试
查看>>
SDUTOJ3754_黑白棋(纯模拟)
查看>>
Scala入门(1)Linux下Scala(2.12.1)安装
查看>>
如何改善下面的代码 领导说了很耗资源
查看>>
Quartus II 中常见Warning 原因及解决方法
查看>>
php中的isset和empty的用法区别
查看>>
Android ViewPager 动画效果
查看>>
pip和easy_install使用方式
查看>>
博弈论
查看>>
Redis sentinel & cluster 原理分析
查看>>
我的工作习惯小结
查看>>
把word文档中的所有图片导出
查看>>