Scala求值策略与高阶函数

1:求值策略

scala> def bar(x:Int , y: => Int) = 1
bar: (x: Int, y: => Int)Int

scala> def loop():Int = loop    //
loop: ()Int

scala> bar(1,loop)         //y为call by name,只有被使用到时才计算
res2: Int = 1

scala> bar(loop,1) -------------x的值为call by value,则首先要拿到第一个表达式的值才可进行下面的运算
一直没有结束,loop进行死循环,没办法退出循环体

2:Scala函数与匿名函数

高阶函数:接受的参数可能是个函数,或者返回值是一个函数,或者两个皆有

例1:f为一个函数,接受两个Int类型的参数,返回值为一个Int类型的值,operate中直接调用f,

f传入(4,4),f最终会返回一个Int类型的值,f返回的值再作为operate的返回值

例子2:表示函数的返回值也是一个函数,定义一个函数greeting,函数的返回值是函数,该函数

接受一个字符串类型的参数,参数类型为name,函数的返回值为“hello”+" "+name

返回值为String => String,即匿名函数

scala> def add(x: Int, y: Int): Int = {x + y}
add: (x: Int, y: Int)Int

scala> def add2(z:Int) = { z+2 }
add2: (z: Int)Int

scala> val k = add2(add(1,2))
k: Int = 5

3:Scala柯里化

例2:实现一个函数,功能是对每个整型加1的操作,_通配后面所有的参数列表

scala> def curriedAdd(a:Int)(b:Int) = a+b
curriedAdd: (a: Int)(b: Int)Int

scala> val addOne = curriedAdd(1)_
addOne: Int => Int = <function1>

scala> addOne(2)
res2: Int = 3

4:Scala递归与尾递归

递归层数较多时可能会出现堆栈溢出,因此需要优化

只需要一个栈,m中保存的是最新的一个累乘的结果

scala> def factorial(n:Int,m:Int):Int = { if(n<=0) m else factorial(n-1,m*n)}
factorial: (n: Int, m: Int)Int

scala> factorial(5,1)
res3: Int = 120

举例:

object sumfunc {
  def sum(f: Int => Int)(a: Int)(b: Int): Int = {

    @annotation.tailrec
    def loop(n: Int, acc: Int): Int = {
      if (n > b) {
        println(s"n=${n},acc=${acc}")
        acc
      } else {
        println(s"n=${n},acc=${acc}")
        loop(n + 1, acc + f(n))
      }
    }
    loop(a,0)
  }                                               //> sum: (f: Int => Int)(a: Int)(b: Int)Int
  sum(x => x)(1)(5)                     //> n=1,acc=0
  //相当于y = x                            //| n=2,acc=1
                                                  //| n=3,acc=3
                                                  //| n=4,acc=6
                                                  //| n=5,acc=10
                                                  //| n=6,acc=15
                                                  //| res0: Int = 15

sum(x => x * x)(1)(5)                 //> n=1,acc=0
                                                  //| n=2,acc=1
                                                  //| n=3,acc=5
                                                  //| n=4,acc=14
                                                  //| n=5,acc=30
                                                  //| n=6,acc=55
                                                  //| res1: Int = 55
  sum(x => x * x * x)(1)(5)                       //> n=1,acc=0
                                                  //| n=2,acc=1
                                                  //| n=3,acc=9
                                                  //| n=4,acc=36
                                                  //| n=5,acc=100
                                                  //| n=6,acc=225
                                                  //| res2: Int = 225

val sumSquare = sum(x => x * x)_                //> sumSquare  : Int => (Int => Int) =sumfunc$$$Lambda$13/885951223@b684286
sumSquare(1)(5)                                           //> n=1,acc=0
//柯里化                                                         //| n=2,acc=1
                                                                      //| n=3,acc=5
                                                                      //| n=4,acc=14
                                                                      //| n=5,acc=30
                                                                      //| n=6,acc=55
                                                                      //| res3: Int = 55
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值