🪨
Int→Bool な無名再帰
前の記事で掲載した型付きZコンビネータは型引数を1つしか取らず,入力と出力の型が一致していなければなりませんでした.しかし,世の中には
このような関数でも無名再帰ができるようにするために,以前のZコンビネータに手を加え,型引数を2つ取るようにしました.完成したコードを以下に示します.
@FunctionalInterface
interface R<X, Y> {
public X apply(R<X, Y> f);
}
private static <X, Y> Function<X, Y> Z(Function<Function<X, Y>, Function<X, Y>> f) {
R<Function<X, Y>, Y> x1 = (x) -> {
return f.apply((X y) -> x.apply(x).apply(y));
};
R<Function<X, Y>, Y> x2 = (x) -> {
return f.apply((X y) -> x.apply(x).apply(y));
};
return x1.apply(x2);
}
このZコンビネータを使い Function<Integer, Boolean> になっており,整数から真偽値への関数となっていることがわかります.
Function<Function<Integer, Boolean>, Function<Integer, Boolean>> _isOdd =
(Function<Integer, Boolean> f) -> (Integer n) -> n == 0 ? false : !f.apply(n - 1);
Function<Function<Integer, Boolean>, Function<Integer, Boolean>> _isEven =
(Function<Integer, Boolean> f) -> (Integer n) -> n == 0 ? true : !f.apply(n - 1);
Function<Integer, Boolean> isOdd = Z(_isOdd);
Function<Integer, Boolean> isEven = Z(_isEven);
相互再帰で isOdd と isEven
Discussion