标签:
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