【问题标题】:Functional Programming Beginner : Currying in Java函数式编程初学者:Java 中的柯里化
【发布时间】:2018-02-04 16:04:09
【问题描述】:

我正在阅读有关函数式编程中的柯里化,我有一个非常基本的问题:

如果我在 Java 中有两个函数

 int add(int x, int y){
     return x+y;
}

然后我创建另一个方法

  int increment(int y){
       return add(1, y);
   }

在上面的代码中,当我写increment函数时,我真的咖喱add吗?

【问题讨论】:

标签: java functional-programming


【解决方案1】:

您已部分申请add。这与柯里化有关。

在一些支持偏应用的语言中,函数默认是柯里化的。您可能可以编写如下代码:

increment = add(1)
println(increment(2))
# => 3

柯里化函数允许您直接部分应用该函数。如果没有额外的机器,Java 不支持这种东西。

编辑:

在 Java 8 中,使用 lambda 和 java.util.function,您可以定义一个 curry 函数。

import java.util.function.Function;

public class Example {
    public static <T, U, R> Function<T, Function<U, R>> curry(BiFunction<T, U, R> f) {
        return t -> u -> f.apply(t, u);
    }

    public static int add(int x, int y) {
        return x + y;
    }

    public static void main(String[] args) {
        Function<Integer, Function<Integer, Integer>> curriedAdd = curry(Example::add);
        // or
        // BiFunction<Integer, Integer, Integer> add = (x, y) -> x + y;
        // curriedAdd = curry(add);

        Function<Integer, Integer> increment = curriedAdd.apply(1);
        System.out.println(increment.apply(4));
    }
}

编辑#2: 我错了!我已经更正/修改了我的答案。正如 sepp2k 指出的,这只是部分功能应用。这两个概念是相关的并且经常混淆。在我的辩护中,维基百科页面上有一个关于混淆的部分。

【讨论】:

  • increment 不是柯里化add 的结果——它是部分应用add 的结果。柯里化add 的结果将是一个可以称为curriedAdd(arg1)(arg2) 的函数。
  • Flex your PECS!为了获得充分的灵活性,您的 curry 方法的参数应该被声明为 BiFunction&lt;? super T, ? super U, ? extends R&gt;
【解决方案2】:

不,你只是调用它。您需要将函数作为参数传递,并返回对该函数的部分评估以将其称为柯里化。

【讨论】:

    猜你喜欢
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 2011-09-29
    • 1970-01-01
    • 2018-07-25
    • 2016-01-01
    • 2012-03-01
    相关资源
    最近更新 更多