标签:
1.4.1currying/柯里化
通常,编程的函数可以有一个参数列表,而λ表达式要求单参数。所以,currying/柯里化——多个参数的函数转化为只有一个参数的多个函数的连续调用,需要函数作为返回值。
有λ表达式,λx. λy. ( 2x+3y)
(define (F x y)(+ ( * 2 x) (* 3 y)));;;等价于下面的表示 (define F (lambda ( x y) (+ ( * 2 x) (* 3 y)) ) )
(F 2 3) → 13
函数F经过currying/柯里化,currying F具有单个参数。(define curryingF (lambda ( x) (lambda ( y) (+ ( * 2 x) (* 3 y)) ) ) );;;或者 (define (curryingF x) (lambda ( y) (+ ( * 2 x) (* 3 y)) ) )函数应用时,必须按照顺序一次次的应用函数。
((curryingF 2) 3) → 13
其计算过程如下:
((curryingF 2) 3) = (((+ ( * 2 x) (* 3 y)) 2) 3) ;;;展开curryingF
=( (+ ( * 2 2) (* 3 y)) 3);;;按照一般的想象,先替换x
=( (+ 4 (* 3 y)) 3);;;不管applicative-order evaluation还是标准序,结果一样
=( + 4 (* 3 3)) ;;替换y
=( + 4 9)
=13
从((curryingF 2) 3)函数应用中明显地可以看出,(curryingF 2)作为操作符,它表示一个匿名函数,该匿名函数应用于实参3。假设我们希望给(curryingF 2)这个匿名函数一个名字,这里发生了一个有趣的事情:x被定格在2上。
(define (Add_2 y)(( curryingF 2) y))
(Add_2 3) → 13
再比如说计算((curryingF 4) 3) → 17
而且假设也希望给(F 4)的匿名函数一个名字,则x被定格在4上。(define (Add_4 y)(( curryingF 4) y))
显然,yqj2065不愿意为每一个实参常数定义一个有名字的函数。所以一般地,
(define (Add_x y)(( curryingF x) y));;;为curryingF的匿名函数取名
问题是:(define x 2)
(Add_x 3)→ 13
比较另外两个的函数应用,这个(Add_x y)的函数应用需要一个前置语句!这是一种很有趣的函数应用方式——带有数据的行为,据说是另一个闭包(closure)说法的来源。再次应用:
(set! x 3)
(Add_x 3) → 15
((curryingF 3) 3);;;比较
对于一个方法 public static int add(int x, int y) { return x + y; }
修改称单参数的函数,需要用到函数接口
package higherOrderFunction; /** * * @author yqj2065 */ public class Currying { public static int add(int x, int y) { return x + y; } public static AddInterface add_x(int x) { // return new AddInterface(){ // @Override public int add_y(int y){ // return x + y; // } // }; return (int y) -> x + y;//闭包 } public interface AddInterface { int add_y(int y); } public static void main(String[] a) { System.out.println(add(2, 3)); System.out.println(add_x(2).add_y(3)); } }
或者在包外测试:
package test; import higherOrderFunction.Currying; import static higherOrderFunction.Currying.add; import static higherOrderFunction.Currying.add_x; public class Test { public static void main(String[] a) { System.out.println(add(2, 3)); Currying.AddInterface x2=add_x(2); System.out.println(x2.add_y(3)); System.out.println(add_x(2).add_y(3)); } }
add_x(2).add_y(3)//Java
((add 2) 3);;;Scheme
Scheme高阶函数之函数作为返回值暨currying/柯里化
标签:
原文地址:http://blog.csdn.net/yqj2065/article/details/51357314