目录
一、柯里化函数定义
柯里化函数(Curried Functoin)把具有多个参数的函数转换为一条函数链,每个节点上是单一参数。
柯里化(Currying)指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。
eg:以下两个add函数定义是等价的
def add(x:Int,y:Int) = x + y
def add(x:Int)(y:Int) = x + y //Scala柯里化的语法
二、柯里化函数的实现
函数里2传给了a,3传给了b。函数curriedAdd=2 +3
在addOne中1传给了a,_传给了b,之后调用CurriedAdd时4传给了_,此时采用Call By Value的方式,xian运算_ = 4,此时函数curriedAdd(1)(4)= 1 + 4。
第二种一般用于对某种函数进行统一计算。
这是复用了通用型函数的定义,为了缩小适用范围,创建一个针对性更强的函数。
优点:可复用性,延迟计算
三、递归函数
递归函数(Recursive Function)在函数式编程中实现循环的一种技术。
eg:计算n!
def factorial (n: Int) :Int =
if (n <= 0) 1
else n * factorial(n - 1)
弊区:在现代计算机中,我们大都使用堆栈来进行函数的调用,那递归的层数一深栈就越多,就容易导致堆栈溢出,这也是为什么其他编程不太推荐使用递归函数编程的原因。
为了解决以上弊区的问题的方案,我们叫做尾递归函数。
四、尾递归函数
尾递归函数(Tail Recursive Function)中所有递归形式的调用都出现在函数的末尾。
当编译器检测到一个函数调用时尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。
在函数上写明“ @annotation.tailrec”表示函数将进行尾递归的优化。如果不写这句,Scala编译器时不会主动进行尾递归优化的。
object tailrec extendsApp{
@annotation.tailrec
def factorial(n:Int,m:Int):Int=
if(n<=0) m
else factorial(n-1,m*n)
println(factorial(5,1))
}
五、综合性栗子:求
object work_hetong {
def WeWant(f: Int => Int)(a: Int)(b: Int): Int = {
@annotation.tailrec
def loop(n: Int, sum: Int): Int = {
if (n > b) {
println(s"n = ${n}, sum = ${sum}")
sum
} else {
println(s"n = ${n}, sum = ${sum}")
loop(n + 1, sum + f(n))
}
}
loop(a, 0)
} //> WeWant: (f: Int => Int)(a: Int)(b: Int)Int
def WeWantResult = WeWant(x => x)_ //> WeWantResult: => Int => (Int => Int)
WeWantResult(1)(5) //> n = 1, sum = 0
//| n = 2, sum = 1
//| n = 3, sum = 3
//| n = 4, sum = 6
//| n = 5, sum = 10
//| n = 6, sum = 15
//| res0: Int = 15
}
另一种从大到小的写写法,注意参数的改变。