Thinking in scala (5)----高阶函数* 里面,我们演示了如何把一个函数作为参数传递给另外一个函数。

在本文里面,我们来演示函数式编程另外一个重要的特性:返回一个函数。首先来看这么一段代码:

code piece 1:

def sum(f:Int=>Int):(Int,Int)=>Int={
       def sumF(a:Int,b:Int):Int=
         if(a>b) 0
         else f(a)+sumF(a+1,b)
       sumF
   }

一点点来看,f:Int=>Int 是sum函数接收的参数,该参数是一个函数。

":" 号后面的 (Int,Int) => Int 是sum函数的返回值,又(Int,Int) => Int是一个函数的类型:接收两个Int型的数,

返回一个Int的数。也就是说调用sum函数,其返回的值是一个函数。  这一点对于已经习惯C、C++、Java等编程语言的

程序员来说有一点难以理解。

继续看例子吧,如果执行下面的一行代码会发生什么呢?

sum(x=>x*x)(1,4)

结果会返回30。为什么是30呢? 30= 1^2+ 2^2 + 3^2 + 4^2.

首先,sum(x=>x*x) 是一个函数,并且sum(x=>x*x)的类型是(Int,Int)=>Int,正因为sum(x=>x*x)是一个函数,

所以它才可以继续接收参数(1,4).

好吧,我可能没有把这个事儿说清楚,实在是太抽象了。但是,读者应该有了一个基本的印象,那就是:

在函数式编程里面,函数f可以接收函数g作为参数,也可以返回函数h。

到这里还没完。。。。。。

Scala里面可以继续对code piece1 进行简化,如下:

code piece2:

object higherorderfuntion{
   def sum(f:Int=>Int)(a:Int,b:Int):Int={
      if(a>b) 0  else f(a)+sum(f)(a+1,b)
   }

   def fac(a:Int):Int=
   {
     def loop(a:Int,acc:Int):Int=
       if(a==0) acc
       else loop(a-1,a*acc)
     loop(a,1)
   }
   def main(args:Array[String])={
     println(sum(x=>x)(1,4))
     println(sum(x=>x*x*x)(1,4))
     println(sum(fac)(1,4))
   }

}

这里我们需要特别注意,这里sum函数的参数列表变成了两个:(f:Int=>Int)和(a:Int,b:Int)

在scala里面,函数可以有多个参数列表。比如下面的函数定义:

def f(args_1)(args_2)...(args_n)=E

E代表一个函数体,且n>1

那么上述定义等价于:

def f(args_1)(args_2)...(args_n-1)={def g(args_n)=E;g}

还是以code piece2中的sum函数为例:

def sum(f:Int=>Int)(a:Int,b:Int):Int={
      if(a>b) 0  else f(a)+sum(f)(a+1,b)
   }

等价于:

def sum(f:Int=>Int):(Int,Int)=>Int={
     def g(a:Int,b:Int):Int =
      if(a>b) 0  else f(a)+sum(f)(a+1,b)
     g
   }

这个定义和code piece1中的sum函数的定义是一致的。

Thinking in scala (6)----高阶函数----返回一个函数的更多相关文章

  1. Thinking in scala (5)----高阶函数*

    高阶函数是函数式编程里面一个非常重要的特色,所谓的高阶函数,就是以其它函数作为参数的函数. 下面以一个小例子演示Scala的高阶函数特性,非常有意思,也非常强大. 首先看这么一个程序: code1: ...

  2. 用javascript 写个函数返回一个页面里共使用了多少种HTML 标签

    今天我无意间看到一个面试题: 如何用javascript 写个函数返回一个页面里共使用了多少种HTML 标签? 不知你看到 是否蒙B了,如果是我 面试,肯定脑子嗡嗡的响.... 网上搜了搜也没有找到答 ...

  3. Entity Framework 6 Recipes 2nd Edition(11-1)译 -> 从“模型定义”函数返回一个标量值

    第11章函数 函数提供了一个有力代码复用机制, 并且让你的代码保持简洁和易懂. 它们同样也是EF运行时能利用的数据库层代码.函数有几类: Rowset Functions, 聚合函数, Ranking ...

  4. Entity Framework 6 Recipes 2nd Edition(11-2)译 -> 为一个”模型定义”函数返回一个计算列

    11-3. 为一个”模型定义”函数返回一个计算列 问题 想从”模型定义”函数里返回一个计算列 解决方案 假设我们有一个员工(Employee)实体,属性有: FirstName, LastName,和 ...

  5. Entity Framework 6 Recipes 2nd Edition(11-5)译 -> 从”模型定义”函数返回一个匿名类型

    11-5. 从”模型定义”函数返回一个匿名类型 问题 想创建一个返回一个匿名类型的”模型定义”函数 解决方案 假设已有游客(Visitor) 预订(reservation)房间(hotel ) 的模型 ...

  6. 【转载】让c++ 函数返回一个数组

    在c++中是不允许数组作为函数的返回值的 int [] someFunction( ); //ILLEGAL 要想实现函数返回一个数组,那返回对应数组里面类型的指针 you must return a ...

  7. Python--遍历文件夹下所有文件和目录的方法(os.walk(rootdir)函数返回一个三元素元祖)

    import os import os.path # This folder is custom rootdir = '/Users/macbookpro/Desktop/test' for pare ...

  8. array_flip() 函数返回一个反转后的数组

    定义和用法 array_flip() 函数返回一个反转后的数组,如果同一值出现了多次,则最后一个键名将作为它的值,所有其他的键名都将丢失. 如果原数组中的值的数据类型不是字符串或整数,函数将报错 ar ...

  9. scala面向对象.高阶函数,柯里化,Actor编程简介

    1.定义一个类 class Person{ //用val修饰的变量是只读属性,有getter但是没有setter val id ="111" //用var修饰的变量既有getter ...

随机推荐

  1. list遍历

     一.对List的遍历有三种方式            List<String>    list    =    new    ArrayList<String>();    ...

  2. Android开发10.2:UI组件AutoCompleteTextView(自动完成文本框)

    概述 AutoCompleteTextVeiw(自动完成文本框)从 EditText派生而出  PS :EditText用法介绍           当用户输入一定字符后,自动完成自动完成文本框会显示 ...

  3. Django - 用户注册

    使用Django工程自动创建的auth_user表来存储用户信息 在app目录下创建forms.py mysite/music/forms.py from django.contrib.auth.mo ...

  4. ubuntu 12.04 安装snort acidbase相关注意事项

    一.安装Snort 1.安装libpcap 1 apt-get install libpcap-dev 2.安装snort 1 2 apt-get install snort apt-get inst ...

  5. JNDI深入浅出

    1.什么是JNDI JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API.命名服务将名称和 ...

  6. Effective java -- 4 泛型

    第二十三条:请不要在代码中使用原生态类型就是像Set这种待泛型的,就把泛型明确写出来. 第二十四条:消除非受检警告就是Set<String> sets = new HashSet();这种 ...

  7. 《云阅》一个仿网易云音乐UI,使用Gank.Io及豆瓣Api开发的开源项目

    CloudReader 一款基于网易云音乐UI,使用GankIo及豆瓣api开发的符合Google Material Desgin阅读类的开源项目.项目采取的是Retrofit + RxJava + ...

  8. DP CF 319 div1B

    http://codeforces.com/contest/319/problem/B 题目大意: 有删除操作,每次都删除数组右边比自己小的.且紧挨着自己的数字.问最小需要删除几次. 思路: 我们定义 ...

  9. linux logrotate配置

    对于Linux 的系统安全来说,日志文件是极其重要的工具.系统管理员可以使用logrotate 程序用来管理系统中的最新的事件,对于Linux 的系统安全来说,日志文件是极其重要的工具.系统管理员可以 ...

  10. java dom4j解析xml实例(3)

    代码运行前需要先导入dom4j架包. 需要解析的XML文件test.xml如下: <students> <student age="25"><!--如 ...