scala中的高阶函数和柯里化
高阶函数在计算机科学中,高阶函数是至少满足下列一个条件的函数:
在数学中它们也叫做算子(运算符)或泛函。微积分中的导数就是常见的例子,因为它映射一个函数到另一个函数。 高阶函数的例子假设有一个函数对给定两个数区间中的所有整数求和: def sumInts(a: Int,b: Int): Int =
if(a > b) 0 else a + sumInts(a + 1,b)
如果现在要求连续整数的平方和: def square(x: Int): Int = x * x
def sumSquares(a: Int,b: Int): Int =
if(a > b) 0 else square(a) + sumSquares(a + 1,b)
如果要计算2的幂次的和: def powerOfTwo(x: Int): Int = if(x == 0) 1 else 2 * powerOfTwo(x-1)
def sumPowersOfTwo(a: Int,b: Int): Int =
if(a > b) 0 else powerOfTwo(a) + sumPowersOfTwo(a+1,b)
上面的函数都是从a到b的f(n)的累加形式,我们可以抽取这些函数中共同的部分重新编写函数sum,其中定义的f作为一个参数传入到高阶函数sum中: def sum(f: Int => Int,a: Int,b: Int): Int =
if(a > b) 0 else f(a) + sum(f,a+1,b)
def id(x: Int): Int = x
def square(x: Int): Int = x * x
def powerOfTwo(x: Int): Int = if(x == 0) 1 else 2 * powerOfTwo(x-1)
def sumInts(a: Int,b: Int): Int = sum(id,a,b)
def sumSquared(a: Int,b: Int): Int = sum(square,b)
def sumPowersOfTwo(a: Int,b: Int): Int = sum(powerOfTwo,b)
改写成尾递归的写法 object Demo {
def sum(f: Int => Int,b: Int) = {
def loop(a: Int,acc: Int): Int =
if(a > b) acc
else loop(a + 1,f(a) + acc)
loop(a,0)
}
def main(args: Array[String]) = {
println(sum(x => x * x,3,5))
}
}
应用map方法将一个函数应用到某个集合的所有元素并返回结果; //打印三角形
scala> (1 to 9).map("^" * _).foreach(println _)
/* ^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^ ^^^^^^^ ^^^^^^^^ ^^^^^^^^^ */
filter方法输出所有匹配某个特定条件的元素: scala> (1 to 9).filter(_ % 2 == 0)
res14: scala.collection.immutable.IndexedSeq[Int] = Vector(2,4,6,8)
这些在Java、Python、Javascript和新版本的C++里都有实现。 柯里化最简单的柯里化指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。如下代码段, 推广来说,柯里化函数有多个参数列表,所谓的参数列表就是使用小括号括起来的函数参数列表。 def add(x: Int,y: Int) = x + y
def addCurry(x: Int)(y: Int) = x + y
返回函数的函数在上面高阶函数的例子中,我们通过 def sum1(f: Int => Int): (Int,Int) => Int = {
def sumF(a: Int,b: Int): Int =
if(a > b) 0
else f(a) + sumF(a+1,b)
sumF
}
def sumInts = sum1(x => x)
def sumSquared = sum1(x => x * x)
def sumPowersOfTwo = sum1(powerOfTwo)
多个参数列表我们可以这样定义sum函数,进一步简化,省去sumInts、sumSquared、sumPowersOfTwo这几个中间函数的形式(当然,不省去也行): def sum2(f: Int => Int)(a: Int,b: Int): Int =
if(a > b) 1
else f(a) + sum2(f)(a+1,b)
def sumInts(a: Int,b:Int) = sum2(x => x)(a,b:Int) = sum2(x => x * x)(a,b:Int) = sum2(powerOfTwo)(a,b)
这使得函数编写更加简洁。 一般的,多参数函数定义为 如果重复这个过程n次,得到 这种函数定义称为柯里化(Currying)。 参考资料1.scala中的柯里化函数 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |