您的位置:首页 > 其它

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

2014-10-30 22:21 141 查看
高阶函数是函数式编程里面一个非常重要的特色,所谓的高阶函数,就是以其它函数作为参数的函数。

下面以一个小例子演示Scala的高阶函数特性,非常有意思,也非常强大。

首先看这么一个程序:

code1:

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

def sum2(a:Int,b:Int):Int=
if(a>b) 0
else cube(a)+sum2(a+1,b)

def sum3(a:Int,b:Int):Int=
if(a>b) 0
else fac(a)+sum3(a+1,b)

def cube(a:Int):Int=a*a*a

def fac(a:Int):Int=
if (a==0) 1
else a*fac(a-1)

def main(args:Array[String])={
println(sum1(1,3))
println(sum2(1,3))
println(sum3(1,3))
}
}


上面这个例子“没有”用到高阶函数,sum1是计算a+(a+1)+(a+2)+...+(b), sum2是计算a^3+(a+1)^3+(a+2)^3+...+b^3,

sum3是计算a!+(a+1)!+(a+2)!+...+b!。分析sum1,sum2,sum3的代码,很容易发现这三个函数有着相似的“Pattern”,

抛开函数名不论,这三个函数唯一的区别在于,在 else语句中对a的处理:a, cube(a) , fac(a). 那么来看,在函数式

编程里面,是如何非常精彩的利用这个“Pattern”来使得代码更加精简的:

code2:

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 sumInt(a:Int,b:Int):Int = sum(id,a,b)
def sumCube(a:Int,b:Int):Int = sum(cube,a,b)
def sumFac(a:Int,b:Int):Int = sum(fac,a,b)

def id(a:Int) = a
def cube(a:Int):Int=a*a*a
def fac(a:Int):Int=
if (a==0) 1
else a*fac(a-1)

def main(args:Array[String])={
println(sumInt(1,3))
println(sumCube(1,3))
println(sumFac(1,3))
}

}


重头戏来了,我们来看sum函数的实现:

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


sum函数接收三个参数,第二个和第三个参数分别是: a:Int 和 b:Int, 这和第一个例子中是一样的。

比较令人费解的是sum函数的第一个参数:f:Int=>Int

这个是什么意思呢?意思是sum函数接收一个名字叫做 “f” 的函数作为参数,而 Int=>Int 是对f的说明:

=>左边的Int是说:函数f接收一个Int类型的参数,

=>右边的Int是说:函数f的返回值是Int类型的。

好了,那么既然sum函数接收函数f作为一个参数,那么sum就可以利用f了,事实也是这样的,看sum

函数的else语句就知道了:f(a)

然后再看sumInt、sumCube和sumFac三个函数的定义:

def sumInt(a:Int,b:Int):Int = sum(id,a,b)
def sumCube(a:Int,b:Int):Int = sum(cube,a,b)
def sumFac(a:Int,b:Int):Int = sum(fac,a,b)


以sumCube函数为例吧,它在定义的时候,把cube函数作为参数,传递给sum函数,

而我们看cube函数的定义:

def cube(a:Int):Int=a*a*a


发现,cube函数接收一个Int作为参数,并且返回一个Int,也就是说cube函数是符合sum函数的第一个

参数: f:Int=>Int 的

是不是很精彩呢?

事实上上述代码还可以进一步简化,因为我们观察到id函数和cube函数的功能非常简单,不需要单独作为

一个函数出现,进一步简化后的代码如下:

code3:

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 sumInt(a:Int,b:Int):Int = sum(x=>x,a,b) def sumCube(a:Int,b:Int):Int = sum(x=>x*x*x,a,b)
def sumFac(a:Int,b:Int):Int = sum(fac,a,b)

def fac(a:Int):Int=
if (a==0) 1
else a*fac(a-1)

def main(args:Array[String])={
println(sumInt(1,3))
println(sumCube(1,3))
println(sumFac(1,3))
}
}


code3和code2相比,去掉了id函数和cube这两个函数,并且sumInt和sumCube函数的声明也发生了

一点变化:

def sumInt(a:Int,b:Int):Int = sum(x=>x,a,b)
def sumCube(a:Int,b:Int):Int = sum(x=>x*x*x,a,b)


像: x=>x 和 x=>x*x*x 这样的东西是什么呢?在函数式编程里面,这被叫做“function literal”,又称“匿名函数”,

说白了,这也是函数的一种表达方式,只是这个函数没有名字罢了。

code3其实也还有点小毛病,那就是sum函数和fac函数都不是“尾递归”,所以呢,把它们改成尾递归如下:

code4:

object higherorderfuntion{
def sum(f:Int=>Int,a:Int,b:Int):Int={
def loop(a:Int,acc:Int):Int=
if(a>b) acc
else loop(a+1,f(a)+acc)
loop(a,0)
}
def sumInt(a:Int,b:Int):Int = sum(x=>x,a,b) def sumCube(a:Int,b:Int):Int = sum(x=>x*x*x,a,b)
def sumFac(a:Int,b:Int):Int = sum(fac,a,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(sumInt(1,4))
println(sumCube(1,4))
println(sumFac(1,4))
}

}


希望把这个事儿说明白了...........

For any questions, feel free to contact me via email or QQ.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: