scala学习笔记(十一) 高阶函数

Scala作为函数式语言,函数自然是头等公民

 

一个接收函数作为参数的函数称为高阶函数

比如定义如下:

defvalueAtOneQuarter(f: (Double) => Double) = f(0.25)

这个函数接收一个参数为Double返回值为Double的函数作为参数。

 

高阶函数还可以是返回一个函数作为参数的函数,如下

defmulBy(factor : Double) = (x : Double) => factor * x

valquintuple = mulBy(5)

quintuple(20)

mulBy的类型为:

(Double)=> ((Double) => Double)

 

这里的高阶函数看上有点蛋疼,他的用处在于可以将一个多参数的函数转换成几个一元函数。(后面知道这种叫闭包,并且也是柯里化的结果)

 

 

调用valueAtOneQuarter函数时,如果传入的参数是匿名的,调用可以是以下方式:

valueAtOneQuarter((x: Double) => 3 * x)

 

由于类型推断的存在以上调用的最终简化版是

valueAtOneQuarter(3* _)

 

Scala中的控制抽象是一个比较复杂的概念,如下函数在线程中执行某段代码:

defrunInThread(block : () => Unit){

new Thread{

Override def run() { block() }

}.start()

}

 

上面代码runInThread 函数的参数是一个无参数无返回值的函数

调用代码如下

runInThread

 

看上去代码并不美观(()=> ),这里scala允许一种换名调用表示法: 在参数声明和调用该函数参数的地方省略() 但是在声明的地方保留 =>  ,如下:

defrunInThread(block : => Unit){

new Thread{

Override def run() { block() }

}.start()

}

 

现在调用可以变成下面这样:

runInThread{

println("Hi")

Thread.sleep(10000)

 println("Bye")

}

 

看看下面神奇代码:

defuntil( condition : => Boolean)(block : => Unit){

If(!condition){

block

until( condition)(block)

}

}

来看看调用:

var x =10

until (x== 0){

x -= 1

println(x)

}

以上代码类似于while循环,只不过把条件反过来了,一个函数定义利用递归、柯里化、以及换名调用就实现了一个自定义版本的while

 

package demo

/**
 * @author Administrator
 */
object ScalaHighMethod {

  def main(args: Array[String]): Unit = {
    var x = 10
    until(x == 0) {
      x -= 1
      println(x)
    }

    val r = values(-5, 5, x => x * x)
    r.foreach(println)
    r.foreach(p => println(p._1 + "->" + p._2))

    val ar = Array(4, 6, 9, 12, 45, 2, 5, 14, 12, 46)

    val maxV = ar.reduceLeft((v1: Int, v2: Int) => { if (v1 > v2) v1 else v2 })
    val maxV2 = ar.reduceLeft(_ max _)

    println(maxV)

    val fun = (x: Int) => (1 to x) reduceLeft (_ * _)

    val fun2 = (x: Int) => (1 to x).foldLeft(1)(_ * _)

    println(fun(4))
    println(fun2(4))

    println(largest(x => 10 * x - x * x, 1 to 10))
    println(largest2(x => 10 * x - x * x, 1 to 10))

    val pairs = (1 to 10) zip (11 to 20)

    pairs map (adToPair(_ + _)) foreach {
      println(_)
    }

    //原集合并没有变化
    pairs foreach {
      println(_)
    }

    println(adToPair(_ * _)(6, 7))

    val strs = Array("yang", "ming", "wei")
    val ints = Array(4, 4, 3)

    println(corresponds(strs, ints, _.length == _))

    val vc = 10
    unless(vc > 10) {
      println(vc)
    }
  }

  def corresponds(arg1: Seq[String], agr2: Seq[Int], fun: (String, Int) => Boolean) = {
    arg1.corresponds(agr2)(fun)
  }

  def adToPair(p: (Int, Int) => Int) = {
    (arg: Tuple2[Int, Int]) => p(arg._1, arg._2)
  }

  def largest(fun: (Int) => Int, input: Seq[Int]) = {
    input map (fun) max
  }

  def largest2(fun: (Int) => Int, input: Seq[Int]) = {
    input maxBy { fun }
  }

  def until(condition: => Boolean)(block: => Unit) {
    if (!condition) {
      block
      until(condition)(block)
    }
  }

  def unless(condition: => Boolean)(block: => Unit) {
    if (!condition) {
      block
    }
  }

  def values(low: Int, high: Int, fun: (Int) => Int) = {
    var ab = Map[Int, Int]()
    for (i <- low to high) {
      ab += (i -> fun(i))
    }
    ab
  }
}


 


 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ALAN-YOUNG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值