- 定义
柯里化(Currying)指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。也就是说,有多个参数列表的函数就是柯里化函数,所谓的参数列表就是使用小括号括起来的函数参数列表。
curry化最大的意义在于把多个参数的function等价转化成多个单参数function的级联,这样所有的函数就都统一了,方便做lambda演算。 在scala里,curry化对类型推演也有帮助,scala的类型推演是局部的,在同一个参数列表中后面的参数不能借助前面的参数类型进行推演,curry化以后,放在两个参数列表里,后面一个参数列表里的参数可以借助前面一个参数列表里的参数类型进行推演。
- 函数
val add_f = (x: Int, y: Int) => x + y
- 方法
def add(x:Int, y: Int) = x + y
def add_f = (x: Int, y: Int) => x + y //转为方法
- 区别
- 方法只能用def接收,函数可以用def接收,也可以用val接收。
- 当函数用def来接收之后,不再显示为function,转换为方法。
- 方法可以省略参数,函数不可以。函数可以作为方法的参数.
- 柯里化实例
def add(x:Int,y:Int)=x+y
现在我们把这个函数变一下形式:
def add(x:Int)(y:Int) = x + y
- 代码
object CurryingInstance {
def strAdd(st1: String)(st2: String): String = {
st1 + st2
}
}
object CurryingTest {
def main(args: Array[String]): Unit = {
val str1: String = "Hello, "
val str2: String = "Scala!"
val result = CurryingInstance.strAdd(str1)(str2)
println(result)
}
}
- 柯里化函数和偏函数的区别
下面代码定义一个普通方法multiply1
和一个currying方法multiply2
,并将其转换相应的函数类型:
def multiply1(x: Int, y:Int, z:Int) = x * y * z
val partialAppliedMultiply = multiply1 _
//类型:(x: Int, y: Int, z: Int) => Int
def multiply2(x: Int)(y: Int)(z: Int) = x * y * z
val curryingMultiply = multiply2 _
//类型:Int => (Int => (Int => Int))
在调用时,curryingMultiply可以依次传入各个参数,而partialAppliedMultiply在传入部分参数时,必须显示指定剩余参数的占位符:
val curryingMultiply1 = curryingMultiply(1)
//类型:Int => (Int => Int)
val partialAppliedMultiply1 = partialAppliedMultiply(1, _:Int, _: Int)
//类型:(Int, Int) => Int
另外,curryingMultiply1的类型仍然是currying类型,而partialAppliedMultiply1的类型仍然是普通函数类型。