介绍

如果说函数是程序中的基本模块,代码段,那高阶函数就是函数的高阶(级)版本,其基本定义如下:
  • 函数自身接受一个或多个函数作为输入。
  • 函数自身能输出一个函数,即函数生产函数。
满足其中一个条件就可以称为高阶函数。高阶函数在函数式编程中大量应用,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> { , , , , , , , , , }; Function<int, bool> predicate = (num) => num < ; //定义一个函数 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(); /*
* output:
* true
*/ static Function<int, bool> OutPutMehtod()
{
Function<int, bool> predicate = (num) => num < ; //定义一个函数 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;
}

参考 http://www.cnblogs.com/fox23/archive/2009/10/22/intro-to-Lambda-calculus-and-currying.html

c#语言-高阶函数的更多相关文章

  1. Erlang高阶函数

    对于函数式语言来说,函数也想普通的数据类型一样无处不在.函数即可以当成参数进行传递,也可以当成函数的返回值.当我第一次学习函数式编程的时候,我被这样的写法弄的头昏脑涨.下面我举例说明下(例子摘录自Le ...

  2. [Effective JavaScript 笔记]第19条:熟练掌握高阶函数

    高阶函数介绍 高阶函数曾经是函数式编程的一个概念,感觉是很高深的术语.但开发简洁优雅的函数可以使代码更加简单明了.过去几年中脚本语言采用了这些个技术,揭开了函数式编程的最佳惯用法的神秘面纱.高阶函数就 ...

  3. JavaScript高阶函数的应用

    定义 高阶函数是指至少满足下列条件之一的函数: 函数可以作为参数被传递: 函数可以作为返回值输出. JavaScript语言中的函数显然满足高阶函数的条件,在实际开发中,无论是将函数当作参数传递,还是 ...

  4. ES6中的高阶函数:如同 a => b => c 一样简单

    作者:Sequoia McDowell 2016年01月16日 ES6来啦!随着越来越多的代码库和思潮引领者开始在他们的代码中使用ES6,以往被认为是"仅需了解"的ES6特性变成了 ...

  5. JavaScript 高阶函数 + generator生成器

    map/reduce map()方法定义在JavaScript的Array中,我们调用Array的map()方法,传入我们自己的函数,就得到了一个新的Array作为结果: function pow(x ...

  6. Haskell高阶函数

    Haskell functions can take functions as parameters and return functions as return values. A function ...

  7. 【SICP归纳】2 高阶函数和数据抽象

    上一篇博文相应的是书中的第一章的一二两节,我们已经大致的有了一种构造的感觉不是么. 书中展示了非常多有趣的句法(syntax). 如今我们要让思想进一步的抽象.写这篇博客的时候并未学完整本书.更不敢说 ...

  8. 匿名方法,Lambda表达式,高阶函数

    原文:匿名方法,Lambda表达式,高阶函数 匿名方法 c#2.0引入匿名方法,不必创建单独的方法,因此减少了所需的编码系统开销. 常用于将委托和匿名方法关联,例如1. 使用委托和方法关联: this ...

  9. C#函数式编程-高阶函数

    随笔分类 -函数式编程 C#函数式编程之标准高阶函数 2015-01-27 09:20 by y-z-f, 344 阅读, 收藏, 编辑 何为高阶函数 大家可能对这个名词并不熟悉,但是这个名词所表达的 ...

随机推荐

  1. 【leetcode】Roman to Integer

    题目描述: Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range fr ...

  2. JDK7和JDK8一些重要新特性

    jdk7新特性(部分) switch支持字符串 List AutoCloseable接口实现自动关闭,在try()中 新增获取环境信息的工具方法,getJavaHomeDir,getUserHomeD ...

  3. 《UML大战需求分析》阅读随笔(三)

    一: 需求中提到的各种业务概念.人物等,经过抽象后都可以视之为类. 平时遇到的人.物,我们将遇到的都是具体的人.物,也就如程序中的对象,是一个实实在在的东西. 当我们分析需求的时候,设计模型的时候,我 ...

  4. 递归 CTE

    公用表表达式 (CTE) 具有一个重要的优点,那就是能够引用其自身,从而创建递归 CTE.递归 CTE 是一个重复执行初始 CTE 以返回数据子集直到获取完整结果集的公用表表达式. 当某个查询引用递归 ...

  5. Matlab中一些函数的区别

    1.fix, floor,ceil,round   都是对x取整,但取整方向不同.   fix(x):向0取整(也可以理解为向中间取整)   floor(x):向左取整(从名字看,地板,表示下面) c ...

  6. jsp中如何判断el表达式中的BigDecimal==0

    比较蠢一点的做法: <c:if test="${not ((someBigDecimal < 0) or (someBigDecimal > 0))}"> ...

  7. Format

    strTimeZone := Format('%s ~ %s',[formatdatetime('yyyy-mm-dd',dtpStartTime.DateTime), formatdatetime( ...

  8. iOS之 利用通知(NSNotificationCenter)获取键盘的高度,以及显示和隐藏键盘时修改界面的注意事项

    我们在开发中会遇到这样的情况:调用键盘时需要界面有一个调整,避免键盘遮掩输入框. 但实现时你会发现,在不同的手机上键盘的高度是不同的.这里列举一下: //获取键盘的高度 /* iphone 6: 中文 ...

  9. DB2数据库参数建议(AIX)

    修改用户最大进程数: chdev -l sys0 -a maxuproc=' 用户资源配置:对实例用户,fence用户,应用用户添加如下限制: db2inst1 : fsize=- fsize_har ...

  10. springmvc上传文件,抄别人的

    SpringMVC中的文件上传 分类: SpringMVC 2012-05-17 12:55 26426人阅读 评论(13) 收藏 举报 stringuserinputclassencoding 这是 ...