码迷,mamicode.com
首页 > 其他好文 > 详细

Scheme高阶函数之函数作为返回值暨currying/柯里化

时间:2016-05-10 02:49:08      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:

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的匿名函数取名

问题是:

  • 定义了curryingF,应用为((curryingF 2) 3)
  • 定义了(Add_2 y),应用为(Add_2 3)
  • 定义(Add_x y)?x怎么办?

(define  x 2)

(Add_x 3) 13

比较另外两个的函数应用,这个(Add_x y)的函数应用需要一个前置语句!这是一种很有趣的函数应用方式——带有数据的行为,据说是另一个闭包(closure)说法的来源。再次应用:

(set! x 3)
(Add_x 3) 15
((curryingF 3) 3);;;比较

Java中如何currying/柯里化

对于一个方法 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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!