java - curry一个现有的静态函数

时间:2017-03-15 23:45:22

标签: java functional-programming java-8 currying

为了充分利用Java中的函数组合,我想讨论一些我常用的现有静态函数。一个完美的currying候选人是Apache Commons StringUtils

对于一个具体的例子,假设我想讨论StringUtils.remove(String str, String remove)方法以提供一个名为(例如)removeCommas的函数。

一种可能的实现方式是:

Function<String, String> removeCommas = s -> StringUtils.remove(s, ",");

然而,这并非如此。我希望能够使用方法引用运算符(例如StringUtils::remove)以更实用的方式实现这一点,但我无法弄清楚语法是什么样的。

思想?

3 个答案:

答案 0 :(得分:11)

你可以像这样讨论remove()

Function<String, Function<String, String>> remove = r -> s -> StringUtils.remove(s, r);
Function<String, String> removeCommas = remove.apply(",");

如果你更喜欢方法参考,你可以制作一个通用的辅助方法来讨论任何固定方法:

static <T, U, R> Function<T, Function<U, R>> curry(BiFunction<T, U, R> function) {
    return a -> b -> function.apply(a, b);
}
// ...
Function<String, Function<String, String>> remove = curry(StringUtils::remove);

请注意,此帮助程序遵循参数顺序,因此上述函数将在删除字符串之前捕获目标字符串。无法在方法参考中重新排序参数,因此您必须选择订单并坚持使用。

答案 1 :(得分:3)

普通Java不提供用于currying的语法糖。但是,如果您愿意使用第三方库,则可以使用Javaslang

除了arity 0..8的函数之外,它还包含允许抛出异常的已检查函数(同一个arity)。这些提供以下功能:

  • 部分申请
  • curried functions
  • tupled functions
  • 记忆功能(=结果缓存)
  • 具有反向参数的函数
  • 功能提升
  • ...

在我们这里的具体情况中,在curry(或部分应用)remove方法之前我们需要反向参数列表:

// currying
final Function1<String, Function1<String, String>> curried =
        Function2.of(StringUtils::remove).reversed().curried();

// partial application with reversed parameters
final Function1<String, String> removeCommas =
        Function2.of(StringUtils::remove).reversed().apply(",");

Function1扩展了Java的功能,Function2扩展了Java的BiFunction,以实现互操作性。

免责声明:我是Javaslang的创作者

答案 2 :(得分:0)

函数式语言已经过时,因为许多函数式语言仅限于只有一个参数的函数。这是继承自lambda演算,它是数学逻辑学科中的形式语言/系统。

Currying克服了这个限制,但普通的Java不支持currying。

多年前我写了一个名为jcurry的图书馆,这里是example。也许你觉得它很有用。