2.3.1 函数也是值

728 篇文章 1 订阅
349 篇文章 0 订阅
2.3.1 函数也是值


这一节是源于问题,“我们如何把每次使用的不同功能从递归性质的代码中分离出来,而递归的代码始终保持不变?”答案很简单:把递归部分写成一个带参数的函数,由这些参数指定函数应该执行的“唯一操作”。
我们还用 SumNumbers 方法来演示。在 2.2.3 节,我们写了一个函数,它取一个起始值,在指定的数值范围内循环,用前面的状态,和这个范围内当前的数进行计算,计算出每次迭代的新“状态”。到目前为止,我们用零作为初始值,用加法汇总这个范围中的数字,因此,从 5 到 10 的计算结果将会是这样:5 + (6 + (7 + (8 + (9 + (10 + 0)))))。
如果我们决定要修改个函数,使它更为通用,能够执行不同操作的计算,又该如何呢?例如,我们想把指定范围内的所有数乘起来,生成以下计算:5 * (6 * (7 * (8* (9 * (10 * 1)))))。如果我们看一下这两个计算之间的不同,就会发现,只有两个变化:把初始值从 0 改成 1(因为我们不想把调用的结果乘以零!),再把计算过程中的运算符从 + 改成 *。现在,让我们看看应该怎样写这个函数,在 C# 中就像这样:


int AggregateNumbers(Func<int, int, int> op, int init, int from, int to) {
  if (from > to) return init;
  int sumRest = AggregateNumbers(op, init, from + 1, to);
  return op(from, sumRest);



我们给函数添加两个参数,初始值(init)和运算(op),它指定如何把中间结果和范围中的一个数转换成下一个结果。指定第二个参数,我们使用委托 Func<int, int, int>,表示一个函数有两个 int 类型的参数,并返回一个 int 类型。在 .NET 3.5 中有这个委托类型(我们将在第三章进行讨论)。
在函数语言中,我们不必使用委托,因为这些语言有更简单的概念:函数。这正是“函数也是值”的概念的内容,使用函数的方法与语言中任何可用的其他数据类型一样。函数不仅可以把函数作为参数(如同我们这个示例一样),而且也可以把函数作为结果返回,甚至创建函数列表,等等。在解决问题时,函数作为一种心理概念,也很有用。


以函数方式思考问题


对于很多知道函数编程的人来说,最重要的事情不是函数语言有多少特别有用的功能,而是整个环境鼓励你,在设计和编写应用程序时,不要考虑使用的语言,以不同的和更简单的方式思考所遇到的问题。
把函数当作普通的值来使用的想法,是非常有用的概念,我们用一个示例来说明。假设有一个客户的列表,我们想以特别的方式对它进行排序。
解决这种问题,经典的面向对象的方法,是使用 Sort (排序)方法,参数为某种接口类型(在 .NET 中,可能是 IComparer<Customer>),这个参数说明如何比较两个元素。现在,如果我们想按客户名称对列表进行排序,就要创建一个类,实现这个接口,再用这个类的实例。总而言之,需要写一个包含成员的接口,用来表示想要使用的操作,再创建类来实现这个接口,再创建这个类的实例,再把它作为参数传递。
在函数编程中,我们可以使用函数的概念。我们知道,C# 可以使用委托表示类似的概念,这绝对比接口简单,但函数还要更简单。函数不必事先声明,唯一要考虑的,是需要什么参数,以及返回什么结果。在 .NET 3.5 中,泛型 Fun(函数)委托已经接近于函数的概念,如果我们习惯了考虑用函数,就会发现,比用委托适用范围更广。
函数式 Sort 方法的参数就是函数,取两个客户作为参数,并返回一个整数。这是说明参数的简洁方式;相反,当使用接口或委托时,必须事先声明一些类型,然后,当要以面向对象的方式使用 Sort 方法时,再引用它。使用函数更简单,因为看到函数式 Sort 方法时,立即就能知道它需要什么参数。即使在最终实现的代码使用接口时,函数概念仍然有用,它能以更简洁的方法来思考问题,因此,你必须要记住的元素会更少。


在第一章,我们说过,声明式风格为我们提供了一种新途径,扩展词汇,用来说明解决某一类问题。这一总体目标可以通过使用函数,把其他函数作为参数来实现。在下一节,我们将讨论相关内容。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值