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

来源:互联网 发布:淘宝投诉凭证上传失败 编辑:程序博客网 时间:2024/04/27 19:01

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
原创粉丝点击