type P = any[];
type Nat = (_: (_: P) => P) => (_: P) => P;
 
const zero:  Nat = f => x => x;
const one:   Nat = f => x => f(x);
const two:   Nat = f => x => f(f(x));
const three: Nat = f => x => f(f(f(x)));
const four:  Nat = f => x => f(f(f(f(x))));
const five:  Nat = f => x => f(f(f(f(f(x)))));
const six:   Nat = f => x => f(f(f(f(f(f(x))))));
 
const suc: (n: Nat) => (f: (_: P) => P) => (x: P) => P
  = n => f => x => f(n(f)(x))
const add: (m: Nat) => (n: Nat) => (f: (_: P) => P) => (x: P) => P
  = m => n => f => x => m(f)(n(f)(x));
const mul: (m: Nat) => (n: Nat) => (f: (_: P) => P) => (x: P) => P
  = m => n => f => m(n(f))
 
const f: (_: P) => P = i => [i];
const x: P = [];
 
console.log("0     ", JSON.stringify( zero            (f)(x) ));
console.log("1     ", JSON.stringify( one             (f)(x) ));
console.log("2     ", JSON.stringify( two             (f)(x) ));
console.log("suc(1)", JSON.stringify( suc(one)        (f)(x) ));
console.log("5     ", JSON.stringify( five            (f)(x) ));
console.log("2+3   ", JSON.stringify( add(two)(three) (f)(x) ));
console.log("6     ", JSON.stringify( six             (f)(x) ));
console.log("2*3   ", JSON.stringify( mul(two)(three) (f)(x) ));
$ deno run nat.ts
0      []
1      [[]]
2      [[[]]]
suc(1) [[[]]]
5      [[[[[[]]]]]]
2+3    [[[[[[]]]]]]
6      [[[[[[[]]]]]]]
2*3    [[[[[[[]]]]]]]

"上"のページ: TypeScript, 数学