# Swift 中的柯里化

## 上集：理论预备

### 偏函数应用 (Partial Application || Partial Function Application)

``````int foo(int a, int b, int c) {
return a + b + c;
}

int foo23(int a, int c) {
return foo(a, 23, c);
}
``````

### 柯里化

``````var foo = function(a) {
return a * a;
}
``````

``````var foo = function(a) {
return function(b) {
return a * a + b * b;
}
}
``````

### 小结

``````var foo = function(a) {
return function(b) {
return a * a + b * b;
}
}
var foo3 = foo(3);
foo3(4);
``````

• 偏函数应用：固定原函数的几个参数值，从而得到一个新的函数。
• 函数柯里化：一种使用匿名单参数函数来实现多参数函数的方法。
• 关系：柯里化能够轻松的实现某些偏函数应用。

## 中集：柯里化与偏函数

### 传统手段：老老实实传参数

``````func add(a:Int) -> Int{
return a + 1;
}

var a = 0

``````

``````func add(a:Int, b:Int) -> Int{
return a + b ;
}

var a = 0

a = add(a, 1)   // 1
a = add(a, 2)   // 3
``````

### 进阶手段：可以设置默认值

``````func add(a:Int, b:Int=1) -> Int{
return a + b ;
}

var a = 0

a = add(a, b:2)   // 3
``````

### 柯学手段：通过柯里化实现

``````func add(b:Int)(a:Int) -> Int{
return a + b ;
}

var a = 0

a = addOne(a: a)    // 1
a = addTwo(a: a)    // 3
``````

## 下集：实例方法与柯里化

``````class Counter {
var b: Int = 1

return a + b ;
}
}
``````

``````let counter = Counter()
var a = counter.add(1)  // 2
``````

``````let add = Counter.add   // Function
let counter = Counter()
var a = add(counter)(1) // 2
``````

Instance Methods are Curried Functions in Swift 这篇文章里，作者举了一个例子：用 Target-Action 模式实现一个 `Control`

``````protocol TargetAction {
func performAction()
}

struct TargetActionWrapper<T: AnyObject> : TargetAction {
weak var target: T?
let action: (T) -> () -> ()

func performAction() -> () {
if let t = target {
action(t)()
}
}
}

enum ControlEvent {
case TouchUpInside
case ValueChanged
// ...
}

class Control {
var actions = [ControlEvent: TargetAction]()

func setTarget<T: AnyObject>(target: T, action: (T) -> () -> (), controlEvent: ControlEvent) {
actions[controlEvent] = TargetActionWrapper(target: target, action: action)
}

func removeTargetForControlEvent(controlEvent: ControlEvent) {
actions[controlEvent] = nil
}

func performActionForControlEvent(controlEvent: ControlEvent) {
actions[controlEvent]?.performAction()
}
}
``````

``````class MyViewController {
let button = Control()

button.setTarget(self, action: MyViewController.onButtonTap, controlEvent: .TouchUpInside)
}

func onButtonTap() {
println("Button was tapped")
}
``````

## References

#### 你可能感兴趣的

2 条评论
robin · 2017年02月24日

zhanglei5415 · 2018年07月13日