文档章节

函数式编程(2) 高阶函数

IT周见智
 IT周见智
发布于 2015/06/05 17:18
字数 1150
阅读 7
收藏 0

  上一篇博客介绍了函数式编程中的基础知识:

1)什么是编程范式;

2)编程函数与数学函数的关系。

  上篇文章介绍了函数式编程属于声明式编程范式中的一种,它仿照数学概念中的公式演算去解决问题,是一种更接近数学语言的编程方式。并且我们知道函数式编程中所有的函数都是“纯函数(Pure Function)”,因为只有纯函数才符合数学中对函数的定义,即:

1)函数均有输入(均带有参数)、均有输出(函数有返回值);

2)使用相同参数调用函数,得到的返回值无论何时均相等(不受其他因素影响)。

  数学函数中包含一类函数叫“高阶函数”,它指“接收一个(多个)函数作为输入,或者返回一个函数”的函数。在函数式编程中,同样存在这样的高阶函数。只要一个函数包含有一个(多个)函数作为参数,或者返回另外一个函数,那么这个函数就称为“高阶函数”。在.NET中我们使用委托来封装方法,这样方法就可以像普通类型一样作为程序之间传递的参数、返回值。在.NET中已经有很多场合使用委托作为函数的参数,比如在异步编程时调用的一些方法均带有AsyncCallback委托类型的参数(BeginInvoke等),尤其是C#3.0出现之后,我们在使用一些类似Select()、Where()等扩展方法时,这些方法均会包含一个委托类型的参数:

1 string[] names = { "abc", "def", "ghi", "jkl", "mno" };
2 IEnumerable<string> query = names
3     .Where(n => n.Contains("a"))
4     .OrderBy(n => n.Length)
5     .Select(n => n.ToUpper());
6 foreach (string name in query) Console.WriteLine(name);

注意上面代码中使用Lambda表达式就是快速创建委托的一种方式。并且每个委托的签名几乎都一致:包含输入参数,有返回值

  到现在为止,我们很少碰到返回值是委托类型的函数。并不是没有这样的函数,只能说C#在容纳“函数式编程”的程度还不是很够。我们完全可以自己编写一个返回委托类型的“高阶函数”,比如数学中为一个函数求导函数的过程:

1 public delegate double Function1X(double x);   //一元函数
2 public Function1X GetDerivative(Function1X func)  //高阶函数,函数作为输入、返回值
3 {
4      double deltaX = 0.00000001;
5      return x => (func(x+deltaX)-func(x))/deltaX;  //导数定义(近似)
6 }

如上代码所示,GetDerivative()方法包含一个委托类型参数,代表需要求导函数的函数;并且返回一个委托类型,代表求得的导函数。GetDerivative()方法既包含函数作为参数,又能返回一个函数,因此它属于“高阶函数”。

总结:

1)在编程中,我们可以使用“纯函数”来代表一个数学函数。“纯函数”无副作用(Side-Effect),并且符合数学中对函数的定义。可以这么说,编程函数涵盖的范围包含数学函数;

2)如果一个纯函数的参数又是一个函数,或者该纯函数能够返回另一个函数,那么这个纯函数就称为“高阶函数”,它与数学中的高阶函数对应。

到目前为止,我所讲到的所有内容都是为了让你在“程序”和“数学”之间找到一个共同点,能够一一类比。而这个过程中,“纯函数”无疑是重点。

  下面分享一个demo,能够绘制任意给定函数的曲线图,并能够绘制指定点(X)处的切线。demo中主要演示一个求导函数的高阶函数和一个求切线函数的高阶函数

 1   /// <summary>
 2         /// 求导函数 近似
 3         /// </summary>
 4         /// <param name="func"></param>
 5         /// <returns></returns>
 6         private Function1X Get(Function1X func)
 7         {
 8             double delatX = 0.00000000001;
 9             return x => (func(x + delatX) - func(x)) / delatX;
10         }
11 
12         /// <summary>
13         /// 根据斜率和(x,y)得到切线方程
14         /// </summary>
15         /// <param name="k"></param>
16         /// <param name="x"></param>
17         /// <param name="y"></param>
18         /// <returns></returns>
19         private Function1X Get2(double k, double x, double y)
20         {
21             // y = kx + b
22             // b = y - kx
23             double b = y - k * x;
24             return a => k * a + b;
25         }
View Code

(demo中解析函数表达式的过程使用到了老外的方法,站在巨人肩膀上:))下面是效果图:

源码下载地址:http://files.cnblogs.com/xiaozhi_5638/Functional_Program.rar

 

函数式编程(1)

© 著作权归作者所有

共有 人打赏支持
IT周见智

IT周见智

粉丝 10
博文 61
码字总数 185891
作品 0
西青
函数式编程

函数式编程 函数式编程(Functional Programming)之前都只是听说过,没有使用过所谓的函数式编程思想。不大理解这个概念。最近弄python的时候遇到了这个概念。 函数式编程对应的是命令式编程...

王二狗子11
01/07
0
0
Scala 函数式编程_高阶函数_Higher Order Function

Scala 函数式编程高阶函数Higher Order Function 高阶函数的基础就是 函数作为参数传递给另外一个函数,作为参数的函数可以是匿名函数或者函数字面量,也包括用def 关键字定义的函数。 ht...

秋风醉了
2014/12/22
0
0
Scala笔记整理(六):Scala集合库

[TOC] Scala主要集合结构 1、Scala中的集合体系主要包括:、、、。其中Iterable是所有集合trait的根trait。实际上Seq、Set、和Map都是子trait Seq 是一个有先后次序的值的序列,比如数组或列...

xpleaf
04/21
0
0
(转)现代C++函数式编程

本文转自:http://geek.csdn.net/news/detail/96636 {public: { 评论 添加评论 发布链接 发布图文 返回顶部 发布到 主题 发布 评论

wangxiaocvpr
2016/08/22
0
0
React前奏,函数式编程基本概念

函数式编程基本概念 写在之前,这些内容参考自O`REILLY系列图书《React学习手册》 在React中,UI是用纯函数表示的,并且在构造DOM时,是以声明式(与此相对的,是命令式)的方式。而声明式的...

小铭星
07/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSX | SafariBookmarksSyncAgent意外退出解决方法

1. 启动系统, 按住⌘-R不松手2. 在实用工具(Utilities)下打开终端,输入csrutil disable, 然后回车; 你就看到提示系统完整性保护(SIP: System Integrity Protection)已禁用3. 输入reboot回车...

云迹
今天
4
0
面向对象类之间的关系

面向对象类之间的关系:is-a、has-a、use-a is-a关系也叫继承或泛化,比如大雁和鸟类之间的关系就是继承。 has-a关系称为关联关系,例如企鹅在气候寒冷的地方生活,“企鹅”和“气候”就是关...

gackey
今天
4
0
读书(附电子书)|小狗钱钱之白色的拉布拉多

关注公众号,在公众号中回复“小狗钱钱”可免费获得电子书。 一、背景 之前写了一篇文章 《小狗钱钱》 理财小白应该读的一本书,那时候我才看那本书,现在看了一大半了,发现这本书确实不错,...

tiankonguse
今天
4
0
Permissions 0777 for ‘***’ are too open

异常显示: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ......

李玉长
今天
5
0
区块链10年了,还未落地,它失败了吗?

导读 几乎每个人,甚至是对通证持怀疑态度的人,都对区块链的技术有积极的看法,因为它有可能改变世界。然而,区块链技术问世已经10年了,我们仍然没有真正的用上区块链技术。 几乎每个人,甚...

问题终结者
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部