vlambda博客
学习文章列表

函数式编程———柯里化(Currying)

柯里化(Currying)是把接收多个参数的函数变成接收一个单一参数的函数,并且返回接收剩余参数且返回结果的新函数,看定义可能有点懵,我们直接上代码:

//定义一个打印日志的函数fun log(tag: String, target: OutputStream, message: Any?) { target.write("[$tag] $message \n".toByteArray())}
//将log函数柯里化后如下fun log1(tag: String)  = fun(target: OutputStream) fun(message: Any?)  = target.write("[$tag$message \n".toByteArray()) //扩展Function3函数类型,为其增加一个curried函数,实现将一个函数柯里化的功能fun <P1, P2, P3, R> Function3<P1, P2, P3, R>.curried()       = fun(p1: P1)       = fun(p2: P2)       = fun(p3: P3)       = this(p1, p2, p3)       fun main() {    //柯里化后函数的调用写法如下,实质上就是偏函数的调用 log1("日志")(System.out)("记录日志")    //log函数调用curried函数,::是获取函数的引用 ::log.curried()("日志")(System.out)("记录日志")}


上述代码第1行定义了一个打印日志的函数,其参数有3个,第7行是将其柯里化的写法,将其柯里化之后这个三元函数就变成了3个一元函数的调用链。对于多参数函数,指定某个参数后,得到的还是一个函数,这个函数称为原来函数的偏函数。第13行是为Function3函数类型扩展了一个curried函数(在Kotlin中函数为一等公民,所有的函数都有其所属类型,无参函数是Function0类型,1个参数是Function1类型,2个参数是Function2类型,3个参数是Function3类型,以此类推),curried函数实现了把一个3个参数的函数柯里化,其中的泛型参数P1,P2和P3是函数参数的类型,R是函数返回值的类型。