你可以通过闭包轻松实现这一点:
/// Takes a binary function and returns a curried version
func curry<A,B,C>(f: (A, B) -> C) -> A -> B -> C {
return { a in { b in f(a, b) } }
}
curry(+)(5)(6) // => 11
let add: Int -> Int -> Int = curry(+)
add(5)(6) // => 11
如果能够对带有 3 个、4 个或更多参数的函数做同样的事情,但又不重复实现,那就太好了。这样一个函数的签名可能会这样开始:
/// Take a function accepting N arguments and return a curried version
func curry<T>(args: T...) -> /* ? */
返回类型是什么?它会根据函数的输入而改变。目前这在 Swift 中绝对是不可能的,而且我认为如果没有某种宏系统,这根本不可能。但即使使用宏,我也不认为编译器会满意,除非它在编译时知道列表的长度。
话虽如此,使用接受 3、4、5 或更多参数的版本手动重载柯里化函数确实非常简单:
func curry<A,B,C,D>(f: (A, B, C) -> D) -> A -> B -> C -> D {
return { a in { b in { c in f(a,b,c) } } }
}
func curry<A,B,C,D,E>(f: (A, B, C, D) -> E) -> A -> B -> C -> D -> E {
return { a in { b in { c in { d in f(a,b,c,d) } } } }
}
// etc.