Scala柯里化函数和递归函数

目录

一、柯里化函数定义

二、柯里化函数的实现

三、递归函数

四、尾递归函数

五、综合性栗子:求​


一、柯里化函数定义

柯里化函数(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
}

另一种从大到小的写写法,注意参数的改变。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值