import { Bool, not, True } from './bool'; import { Lazy, _, id } from './core'; export type Num = (z: Lazy) => (n: (p: Lazy) => Lazy) => Lazy; export const Zero: Lazy = _(z => _ => z); export const Succ: (p: Lazy) => Lazy = p => _(_ => n => n(p)); export const ifz: (n: Lazy) => (t: Lazy) => (f: Lazy) => Lazy = n => t => f => n.then(n => n(t)(_ => f)); export const succ: (n: Lazy) => Lazy = Succ; export const pred: (n: Lazy) => Lazy = n => n.then(n => n(Zero)(id)); export const even: (n: Lazy) => Lazy = n => n.then(n => n(True)(odd)); export const odd: (n: Lazy) => Lazy = n => not(even(n)); export const sum: (l: Lazy) => (r: Lazy) => Lazy = l => r => r.then(r => r(l)(sum(Succ(l)))); export const sub: (l: Lazy) => (r: Lazy) => Lazy = l => r => r.then(r => r(l)(pr => l.then(l => l(Zero)(pl => sub(pl)(pr))))); export const mul: (l: Lazy) => (r: Lazy) => Lazy = l => r => l.then(l => l(Zero)(pl => sum(r)(mul(pl)(r)))); export const fromNumber: (n: number) => Lazy = n => !n ? Zero : new Lazy(() => Succ(fromNumber(n - 1)).value); export const toNumber: (n: Lazy) => Lazy = n => n.then(n => n(_(0))(p => toNumber(p).then(p => _(1 + p))));