如何使用柯里化实现泛型
How to implement generic types with currying
鉴于这种通用柯里化的实现:
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)
感谢任何帮助。
谢谢。
没有干净或内置的方法来执行此操作。
您可以通过定义一个非常狂野的 return 类型的方法来做到这一点:
Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Integer>>>>>>>>>>
我希望它能说明这样一个观点,即试图以一般方式解决这个问题是冗长、混乱、难以阅读的...(我什至不确定我在这里得到的 Function
的数量是否正确).
接受 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;
}
}
你可以这样调用:
new Impl<>(0, Integer::sum).apply(10).apply(20)....apply(100).stop()
但这并不是真正的柯里化。
鉴于这种通用柯里化的实现:
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)
感谢任何帮助。
谢谢。
没有干净或内置的方法来执行此操作。
您可以通过定义一个非常狂野的 return 类型的方法来做到这一点:
Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Function<Integer, Integer>>>>>>>>>>
我希望它能说明这样一个观点,即试图以一般方式解决这个问题是冗长、混乱、难以阅读的...(我什至不确定我在这里得到的 Function
的数量是否正确).
接受 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;
}
}
你可以这样调用:
new Impl<>(0, Integer::sum).apply(10).apply(20)....apply(100).stop()
但这并不是真正的柯里化。