如何用咖喱实现通用类型

问题描述 投票:0回答:1

给出这样一种通用的库里的实现方式。

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

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

并像这样调用它

Function<Integer, Function<Integer, Integer>> addGen = curry(Curry::add);
System.out.println(addGen.apply(10).apply(20));

我怎样才能扩展这个curry()函数来接受更多的参数?比如说

addGen.apply(10).apply(20).apply(30)....apply(100)

任何帮助都是感激的。

谢谢。

java generics currying
1个回答
1
投票

没有一个干净的或内置的方法可以做到这一点。

你可以通过定义一个具有非常疯狂的返回类型的方法来实现。

Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Integer>>>>>>>>>>

我希望这能说明一个问题,那就是试图用通用的方法来处理这个问题是很啰嗦、很混乱、很难读的... ... (我甚至不确定我得到了正确的数量的 Functions在这里)。)

取10个参数的函数--不管是加密的还是不加密的--其实都没有那么有用。你甚至不能用像 Haskell 这样的函数式语言干净利落地表达。

然后,当你需要一些10以外的数字时会发生什么。简直是一团糟。

不要试图使用咖哩。只要把你的10个(或者多少个)参数当作一个列表,然后把它们减少。

Stream.of(a1, ..., a10).reduce(Integer::sum)

简单,干净,标准。

可以想象,你可以定义一个像这样的接口。

interface StoppableFunction<T> extends Function<T, StoppableFunction<T>> {
  T stop();
}

然后像这样实现它

class Impl<T> implements StoppableFunction<T> {
  Impl(T result, BinaryFunction<T> fn) {
    this.result = result; // field defs omitted
    this.fn = fn;
  }

  public Impl<T> apply(T arg) {
    return new Impl<>(fn.apply(result, arg), fn);
  }

  T stop() {
    return result;
  }
}

然后你可以调用like:

new Impl<>(0, Integer::sum).apply(10).apply(20)....apply(100).stop()

但这并不是真正的讨好。

© www.soinside.com 2019 - 2024. All rights reserved.