我正在尝试在 Java 1.8 中实现教堂数字。我的第一次尝试是:
import java.util.function.UnaryOperator;
@FunctionalInterface
public interface ChurchNumeral {
public static ChurchNumeral valueOf(int n) {
if (n < 0) {
throw new IllegalArgumentException("Argument n must be non-negative.");
}
if (n == 0) {
return (f, arg) -> arg;
}
return (f, arg) -> f(valueOf(n-1).apply(f, arg));
}
<T> T apply(UnaryOperator<T> f, T arg);
}
这失败了,因为函数方法有一个类型参数。(具体来说,带有 lambda 表达式的行给出了错误:“非法 lambda 表达式:ChurchNumeral 类型的方法应用是通用的”。)
根据对使用泛型和功能接口的相关问题的回答,我尝试对类进行参数化:
import java.util.function.UnaryOperator;
@FunctionalInterface
public interface ChurchNumeral<T> { // This line changed.
public static ChurchNumeral<?> valueOf(int n) { // This line changed.
if (n < 0) {
throw new IllegalArgumentException("Argument n must be non-negative.");
}
if (n == 0) {
return (f, arg) -> arg;
}
return (f, arg) -> f(valueOf(n-1).apply(f, arg));
}
T apply(UnaryOperator<T> f, T arg); // This line changed.
}
第一个 lambda 表达式现在可以编译,但第二个失败并出现以下错误:
ChurchNumeral 类型中的方法 apply(UnaryOperator, capture#1-of ?) 不适用于参数 (UnaryOperator, Object)
此外,我不想为每个可能的函数/参数类型使用不同版本的 ChurchNumeral.ZERO。
有什么建议么?