チャーチ数_v2(pow)
code: sample.ts
type Church<FI, FO, N, O> = (f: (fo: FI) => FO) => (n: N) => O;
const W_ZERO = <FI, FO, N>(): Church<FI, FO, N, N> => {
return () => (n) => n;
};
const W_ONE = <N, O>(): Church<N, O, N, O> => {
return (f) => (n) => f(n);
};
const toInt = (c: Church<number, number, number, number>) => {
const inner = (n: number) => n + 1;
return c(inner)(0);
};
const toChurch = <T>(n: number) => {
(prev) => add(W_ONE<T, T>(), prev),
W_ZERO<T, T, T>()
);
};
const add = <FI, FO, N, XO, YO>(
x: Church<FI, FO, YO, XO>,
y: Church<FI, FO, N, YO>
): Church<FI, FO, N, XO> => {
return (f) => (n: N) => x(f)(y(f)(n));
};
const mul = <FI, FO, N, YN, YO, O>(
x: Church<YN, YO, N, O>,
y: Church<FI, FO, YN, YO>
): Church<FI, FO, N, O> => {
return (f) => (n) => x(y(f))(n);
};
// 思考過程
// const pow2 = <N, O>(x: Church<N, O, N, O>): Church<N, O, N, O> => {
// return (f) => (n) => x(x(f))(n);
// };
// const pow2B = <N, O>(x: Church<N, O, N, O>): Church<N, O, N, O> => {
// const F_TWO = <T>(): Church<T, T, T, T> => {
// return (f) => (n) => f(f(n));
// };
// const TWO = F_TWO<(n: N) => O>();
// return (f) => (n) => TWO(x)(f)(n);
// };
const pow = <N, O>(
x: Church<N, O, N, O>,
y: Church<(n: N) => O, (n: N) => O, (n: N) => O, (n: N) => O>
): Church<N, O, N, O> => {
return (f) => (n) => y(x)(f)(n);
};
// console.log(toInt(add(toChurch(100), toChurch(72))));
// console.log(toInt(mul(toChurch(1234), toChurch(100))));
console.log('---add---');
console.log('12 + 34');
console.log(toInt(add(toChurch(12), toChurch(34))));
console.log('1000 + 234');
console.log(toInt(add(toChurch(1000), toChurch(234))));
console.log('');
console.log('---mul---');
console.log('12 * 4');
console.log(toInt(mul(toChurch(12), toChurch(4))));
console.log('34 * 3');
console.log(toInt(mul(toChurch(34), toChurch(3))));
console.log('56 * 2');
console.log(toInt(mul(toChurch(56), toChurch(2))));
console.log('');
console.log('---pow---');
console.log('2 ** 2');
console.log(toInt(pow(toChurch(2), toChurch(2))));
console.log('3 ** 2');
console.log(toInt(pow(toChurch(3), toChurch(2))));
console.log('10 ** 2');
console.log(toInt(pow(toChurch(10), toChurch(2))));
console.log('');