函数式编程里的currying柯里化
2013-07-02 00:00
363 查看
我认识的大多数人都读过“四人帮”的那本设计模式,任何有自尊的程序员都会告诉你那本书是语言中立的(agnostic),模式在软件工程中是通用的,和使用的语言无关。这个个高贵的宣言,但不幸有违现实。
函数式编程具有突出的表达能力,在函数式语言中,语言已达此高度,设计模式就不再是必需,最终你将能消灭设计模式而以概念编程。适配器 (Adapter)模式就是这样的一个例子(究竟适配器和 Facade 模式区别在哪里?可能有些人需要在这里再多费些篇章),而一旦语言有了叫作 currying (柯里化)的技术,这一模式就可以被消除。
适配器模式最有名的是被应用在 Java 的“默认”行为抽象上。在函数式编程里,模式被应用到函数,模式带有一个接口并将它转换成另一个对他人有用的接口。这有一个适配器模式的例子:
上面的代码把一个整数幂运算接口转换成为了一个平方接口。在学术文章里,这个雕虫小技被叫作 currying(得名于逻辑学家 Haskell Curry,他曾将相关的数学理论形式化)。因为在函数式编程中函数(反之如 class)被作为参数来回传递,currying 很频繁地被用来把函数调整为更适宜的接口。因为函数的接口是他的参数,使用 currying 可以减少参数的数目(如上例所示)。
函数式语言内建了这一技术。不用手动地创建一个包装了原函数的函数,函数式语言可以为你代劳。同样地,扩展我们(假想)的 Java 语言,让他支持这个技术:
这将为我们自动创建出一个有一个参数的函数 square。他把第二个参数设置为 2 再调用函数 pow。这行代码会被编译为如下的 Java 代码:
正如你所见,通过简单地创建一个对原函数的包装,在函数式编程中,这就是 currying —— 快速简易创建包装的捷径。把精力集中在你的业务上,让编译器为你写出必要的代码!什么时候使用 currying?这很简单,任何时候你想要使用适配器模式(包装)时。
关于柯里化(currying),我们可以这么理解:柯里化就是一个函数在参数没给全时返回另一个函数,返回的函数的参数正好是余下的参数。比如:你制定了x和y, 如2的3次方,就返回8, 如果你只制定x为2,y没指定, 那么就返回一个函数:2的y次方, 这个函数只有一个参数:y。这样就非常容易理解吧。
PS:该概念来自 Alonzo Church 的 Lambda calculus,它的 2 大特性:
匿名函数
每个函数只有一个输入参数
函数式编程具有突出的表达能力,在函数式语言中,语言已达此高度,设计模式就不再是必需,最终你将能消灭设计模式而以概念编程。适配器 (Adapter)模式就是这样的一个例子(究竟适配器和 Facade 模式区别在哪里?可能有些人需要在这里再多费些篇章),而一旦语言有了叫作 currying (柯里化)的技术,这一模式就可以被消除。
适配器模式最有名的是被应用在 Java 的“默认”行为抽象上。在函数式编程里,模式被应用到函数,模式带有一个接口并将它转换成另一个对他人有用的接口。这有一个适配器模式的例子:
int pow(int i, int j); int square(int i) { return pow(i, 2); }
上面的代码把一个整数幂运算接口转换成为了一个平方接口。在学术文章里,这个雕虫小技被叫作 currying(得名于逻辑学家 Haskell Curry,他曾将相关的数学理论形式化)。因为在函数式编程中函数(反之如 class)被作为参数来回传递,currying 很频繁地被用来把函数调整为更适宜的接口。因为函数的接口是他的参数,使用 currying 可以减少参数的数目(如上例所示)。
函数式语言内建了这一技术。不用手动地创建一个包装了原函数的函数,函数式语言可以为你代劳。同样地,扩展我们(假想)的 Java 语言,让他支持这个技术:
square = int pow(int i, 2);
这将为我们自动创建出一个有一个参数的函数 square。他把第二个参数设置为 2 再调用函数 pow。这行代码会被编译为如下的 Java 代码:
class square_function_t { int square(int i) { return pow(i, 2); } } square_function_t square = new square_function_t();
正如你所见,通过简单地创建一个对原函数的包装,在函数式编程中,这就是 currying —— 快速简易创建包装的捷径。把精力集中在你的业务上,让编译器为你写出必要的代码!什么时候使用 currying?这很简单,任何时候你想要使用适配器模式(包装)时。
关于柯里化(currying),我们可以这么理解:柯里化就是一个函数在参数没给全时返回另一个函数,返回的函数的参数正好是余下的参数。比如:你制定了x和y, 如2的3次方,就返回8, 如果你只制定x为2,y没指定, 那么就返回一个函数:2的y次方, 这个函数只有一个参数:y。这样就非常容易理解吧。
PS:该概念来自 Alonzo Church 的 Lambda calculus,它的 2 大特性:
匿名函数
每个函数只有一个输入参数
相关文章推荐
- 用Lambda表达式进行函数式编程(续):用C#实现Y组合子
- 函数式编程另类指南 (转载)
- 函数式编程
- 对Winter-cn关于函数式编程的文章评论
- SICP 与函数式编程
- 函数式编程介绍之极简版
- 使用函数式编程语言,该怎么设计软件?
- 函数式编程初探
- 函数式编程初探 zz
- 函数式编程基础(F#,JS)
- 明辨概念:型(type)、类(class)、对象(object)、多态(polymorphism)、函数式编程(functional)
- 函数式编程和过程式编程--对递归和循环的思考
- Python函数式编程指南(二):函数
- Python函数式编程指南(二):函数
- Python函数式编程指南(三):迭代器
- Python函数式编程指南(四):生成器
- 函数式编程
- 函数式编程里面的fold
- Scala 中的函数式编程基础(二)
- 函数式编程