C#中的高阶函数介绍
作者:junjie 发布时间:2022-12-05 02:41:46
介绍
我们都知道函数是程序中的基本模块,代码段。那高阶函数呢?听起来很好理解吧,就是函数的高阶(级)版本。它怎么高阶了呢?我们来看下它的基本定义:
1:函数自身接受一个或多个函数作为输入
2:函数自身能输出一个函数。 //函数生产函数
满足其中一个就可以称为高阶函数。高阶函数在函数式编程中大量应用。c#在3.0推出Lambda表达式后,也开始慢慢使用了。
目录
1:接受函数
2:输出函数
3:Currying(科里化)
一、接受函数
为了方便理解,都用了自定义。
代码中TakeWhileSelf 能接受一个函数,可称为高阶函数。
//自定义委托
public delegate TResult Function<in T, out TResult>(T arg);
//定义扩展方法
public static class ExtensionByIEnumerable
{
public static IEnumerable<TSource> TakeWhileSelf<TSource>(this IEnumerable<TSource> source, Function<TSource, bool> predicate)
{
foreach (TSource iteratorVariable0 in source)
{
if (!predicate(iteratorVariable0))
{
break;
}
yield return iteratorVariable0;
}
}
}
class Program
{
//定义个委托
static void Main(string[] args)
{
List<int> myAry = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
Function<int, bool> predicate = (num) => num < 4; //定义一个函数
IEnumerable<int> q2 = myAry.TakeWhileSelf(predicate); //
foreach (var item in q2)
{
Console.WriteLine(item);
}
/*
* output:
* 1
* 2
* 3
*/
}
}
二、输出函数
代码中OutPutMehtod函数输出一个函数,供调用。
var t = OutPutMehtod(); //输出函数
bool result = t(1);
/*
* output:
* true
*/
static Function<int, bool> OutPutMehtod()
{
Function<int, bool> predicate = (num) => num < 4; //定义一个函数
return predicate;
}
三、Currying(科里化)
一位数理逻辑学家(Haskell Curry)推出的,连Haskell语言也是由他命名的。然后根据姓氏命名Currying这个概念了。
上面例子是一元函数f(x)=y 的例子。
那Currying如何进行的呢? 这里引下园子兄弟的片段。
假设有如下函数:f(x, y, z) = x / y +z. 要求f(4,2, 1)的值。
首先,用4替换f(x, y, z)中的x,得到新的函数g(y, z) = f(4, y, z) = 4 / y + z
然后,用2替换g(y, z)中的参数y,得到h(z) = g(2, z) = 4/2 + z
最后,用1替换掉h(z)中的z,得到h(1) = g(2, 1) = f(4, 2, 1) = 4/2 + 1 = 3
很显然,如果是一个n元函数求值,这样的替换会发生n次,注意,这里的每次替换都是顺序发生的,这和我们在做数学时上直接将4,2,1带入x / y + z求解不一样。
在这个顺序执行的替换过程中,每一步代入一个参数,每一步都有新的一元函数诞生,最后形成一个嵌套的一元函数链。
于是,通过Currying,我们可以对任何一个多元函数进行化简,使之能够进行Lambda演算。
用C#来演绎上述Currying的例子就是:
var fun=Currying();
Console.WriteLine(fun(6)(2)(1));
/*
* output:
* 4
*/
static Function<int, Function<int, Function<int, int>>> Currying()
{
return x => y => z => x / y + z;
}


猜你喜欢
- 前言前一段时间使用java来调用chatgpt的接口,然后写了一个简单小程序,java调用chatgpt接口,实现专属于自己的人工智能助手,
- 本文实例为大家分享了C#实现学生成绩管理系统的具体代码,供大家参考,具体内容如下C#作业 用循环结构/数组实现进入启动页面管理员身份登入用户
- * 惯,先上图,着急用的朋友,直接带走Demo,先拿来用吧,毕竟老板催的紧,先把工作完成了,再看也来得及,是吧!在项目中这种添加图片上传的效
- openid可以标识一个用户,session_key会变,所以来获取一下openid。openid不能在微信小程序中直接获取,需要后台发送请
- 本文实例为大家分享了Android Studio实现帧动画的具体代码,供大家参考,具体内容如下按一定的顺序播放静态的图片1、几张联系的图片2
- SpringMVC服务器验证一种是有两种方式,一种是基于Validator接口,一种是使用Annotaion JSR-303标准的验证,下面
- 一、树概念及结构1.1 树的概念树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因 为
- 本文针对java * 进行知识点整理,具体内容如下一. JAVA的 * (比较官方说法) 代理模式是常用的java设计模式,他的特征是代
- 本文实例为大家分享了Unity通过代码修改按钮点击效果的具体代码,供大家参考,具体内容如下效果:创建一个脚本,挂载到按钮上,主要是实现鼠标移
- 在很多其他框架中,比如Python的Flask、node.js的KOA,Controller要想能够响应前端的请求都需要我们主动去注册到应用
- Druid是数据库连接池,它能够提供强大的监控和扩展功能。官方文档Spring Boot整合第三方技术的两种方式:自定义找starter场景
- 归并排序简单解释:该算法是采用分治法,把数组不断分割,直至成为单个元素,然后比较再合并(合并的过程就是两部分分别从头开始比较,取出最小或最大
- 作者:精致码农出处:http://cnblogs.com/willick联系:liam.wang@live.com最近工作中遇到一个这样的需
- 首先打开vs,右击解决方案,点击管理解决方案的Nuget包管理然后我们点击浏览,搜索log4net,进行安装然后我们需要新建一个名为log4
- 前言系统很多地方都会抛出异常, 而Java的异常体系目标就是与逻辑解耦,Spring提供了统一的异常处理注解,用户只需要在错误的时候提示信息
- 在这里,我们将用到finish(),简单介绍一下它的使用:finish()官方解析:Call this when your activity
- 一、场景描述仪器数据文件的格式包含Pdf、Word、Excel等多种,不同种格式的文件其数据的采集方式不同,因此定义仪器数据采集接口,并定义
- 写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?讲讲字
- 本文实例讲述了Java排序算法总结之希尔排序。分享给大家供大家参考。具体分析如下:前言:希尔排序(Shell Sort)是插入排序的一种。是
- 一、File流概念JAVA中针对文件的读写操作设置了一系列的流,其中主要有FileInputStream,FileOutputStream,