scala的柯里化的作用是结合scala的高阶函数,从而允许用户自建立控制结构。
柯里化(Currying)技术 Christopher Strachey 以逻辑学家Haskell Curry 命名的(尽管它是Moses Schnfinkel 和Gottlob Frege 发明的)。它是把接受多个参数的函数变换成接受一个单一参数的函数, 并且返回接受余下的参数且返回结果的新函数的技术。
案例1:
object Demo08 {
def main(args: Array[String]): Unit = {
//首先我们定义一个函数:
def f1(a:Int,b:Int):Int={a+b}
//现在我们把这个函数变一下形: def f2(a:Int)(b:Int)={a+b}
//那么我们应用的时候,应该是这样用:f2(2)(3),最后结果都一样是5,这种方式(过程)就叫柯里化。
val r1=f2(2)(3)
//柯里化实质上会演变成这样一个函数:
//接收一个参数a,返回一个匿名函数,
//该匿名函数又接收一个参数b,函数体为a+b def f3(a:Int)=(b:Int)=>a+b
val f4=f3(2)
//请思考 f4(3)的值是多少?答案是:5 f4(3)
}
}
示例2:
object Demo09 {
def f1(a:Int,b:Int,c:Int):Int={a+b+c}
def f2(a:Int)(b:Int)(c:Int):Int={a+b+c}
def f3(a:Int)(b:Int,c:Int):Int={a+b+c}
def f4(a:Int,b:Int)(c:Int):Int={a+b+c}
def main(args: Array[String]): Unit = {
//f1和f2的函数的体现的是传入三个数,马上得到结果f1(1,2,3)
f2(1)(2)(3)
//f3函数则可以体现:延迟执行的思想以及固定易变因素的思想val r1=f3(1)(2,3)
}
}
示例3:
object Demo10 {
def f1(a:Int,b:Int,f:(Int,Int)=>Int):Int={f(a,b)}
def f2(a:Int)(b:Int)(f:(Int,Int)=>Int):Int={f(a,b)}
def f3(a:Int,b:Int)(f:(Int,Int)=>Int):Int={f(a,b)}
def f4(a:Int)(b:Int,f:(Int,Int)=>Int):Int={f(a,b)}
def main(args: Array[String]): Unit = {
// 调 用 f3 f3(2,3){(a:Int,b:Int)=>a+b}
//可简化为下面的形式,我们发现这和scala中很多函数的形式很相近,比如:for(x<-1 to 10){print()}
//所以,柯里化的另外一个作用是让用户灵活的自义定自建控制结构f3(2,3){+}
f3(2,3){*_}
// 延迟处理思想
def f3(a:Int)=(b:Int)=>a+b val f4=f3(2)
f4(3)
}
}
柯里化技术在提高适用性、延迟执行或者固定易变因素等方面有着重要重要的作用,加上scala语言本身就是推崇简洁编码,使得同样功能的函数在定义与转换的时候会更加灵活多样。另外在Spark的源码中有大量运用scala柯里化技术的情况,需要掌握好该技术才能看得懂相关的源代码。
在scala柯里化中,闭包也发挥着重要的作用。所谓的闭包就是变量出了函数的定义域外在其他代码块还能其作用,这样的情况称之为闭包。就上述讨论的案例而言,如果没有闭包作用,那么转换后函数其实返回的匿名函数是无法在与第一个参数a相关结合的,自然也就无法保证其所实现的功能是跟原来一致的。