You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
6.7 KiB
141 lines
6.7 KiB
import { toNative as $$, L, P, _, fromNative as __, ___, cnst, id, undef } from './core';
|
|
import { EQ, GT, LT, Ord, eq as eqc } from './ord';
|
|
import { Bool, False, True, and, iif, or } from './bool';
|
|
import { Num, Zero, succ } from './num';
|
|
import { String, fromString as _s } from './string';
|
|
|
|
export type List<T extends P> = L<<R extends P>(z: R) => L<(f: L<(x: T) => L<(xs: List<T>) => R>>) => R>>;
|
|
|
|
export const Nil: List<any>
|
|
= _(z => _(_f => z)) as List<any>;
|
|
|
|
export const Cons: L<<T extends P>(x: T) => L<(xs: List<T>) => List<T>>>
|
|
= _(<T extends P>(x: T) => _((xs: List<T>) => _(_z => _(f => f(x)(xs))) as List<T>));
|
|
|
|
export const cons: L<<T extends P>(x: T) => L<(xs: List<T>) => List<T>>>
|
|
= Cons;
|
|
|
|
export const snoc: L<<T extends P>(xs: List<T>) => L<(x: T) => List<T>>>
|
|
= _(<T extends P>(xs: List<T>) =>
|
|
_((x: T) => xs(cons(x)(Nil))(_(y => _(ys => cons(y)(snoc(ys)(x)))))));
|
|
|
|
export const nul: L<<T extends P>(xs: List<T>) => Bool>
|
|
= _(xs => xs(True)(cnst(cnst(False))));
|
|
|
|
export const len: L<<T extends P>(xs: List<T>) => Num>
|
|
= _(xs => xs(Zero)(_(_x => _(xs => succ(len(xs))))));
|
|
|
|
export const append: L<<T extends P>(l: List<T>) => L<(r: List<T>) => List<T>>>
|
|
= _(l => _(r => l(r)(_(x => _(xs => cons(x)(append(xs)(r)))))));
|
|
|
|
export const concat: L<<T extends P>(ls: List<List<T>>) => List<T>>
|
|
= _(ls => ls(Nil)(_(x => _(xs => append(x)(concat(xs))))));
|
|
|
|
export const repeat: L<<T extends P>(x: T) => List<T>>
|
|
= _(x => cons(x)(repeat(x)));
|
|
|
|
export const iterate: L<<T extends P>(f: L<(x: T) => T>) => L<(x: T) => List<T>>>
|
|
= _(<T extends P>(f: L<(x: T) => T>) => _((x: T) => cons(x)(iterate(f)(f(x)))));
|
|
|
|
export const head: L<<T extends P>(xs: List<T>) => T>
|
|
= _(xs => xs(undef)(cnst));
|
|
|
|
export const tail: L<<T extends P>(xs: List<T>) => List<T>>
|
|
= _(xs => xs(undef)(cnst(id)));
|
|
|
|
export const foldl: L<<T extends P, R extends P>(f: L<(a: R) => L<(x: T) => R>>) => L<(z: R) => L<(xs: List<T>) => R>>>
|
|
= _(<T extends P, R extends P>(f: L<(a: R) => L<(x: T) => R>>) =>
|
|
_((z: R) =>
|
|
_((xs: List<T>) => xs(z)(_(x => foldl(f)(f(z)(x)))))));
|
|
|
|
export const foldlz: L<<T extends P>(f: L<(a: T) => L<(x: T) => T>>) => L<(xs: List<T>) => T>>
|
|
= _(<T extends P>(f: L<(a: T) => L<(x: T) => T>>) => _((xs: List<T>) => xs(undef)(foldl(f))));
|
|
|
|
export const foldr: L<<T extends P, R extends P>(f: L<(x: T) => L<(a: R) => R>>) => L<(z: R) => L<(xs: List<T>) => R>>>
|
|
= _(<T extends P, R extends P>(f: L<(x: T) => L<(a: R) => R>>) =>
|
|
_((z: R) =>
|
|
_((xs: List<T>) => xs(z)(_(x => _(xs => f(x)(foldr(f)(z)(xs))))))));
|
|
|
|
export const foldrz: L<<T extends P>(f: L<(x: T) => L<(a: T) => T>>) => L<(xs: List<T>) => T>>
|
|
= undef;
|
|
|
|
export const cmp: L<<T extends P>(ecmp: L<(l: T) => L <(r: T) => Ord>>) => L<(l: List<T>) => L<(r: List<T>) => Ord>>>
|
|
= _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
|
|
_((l: List<T>) =>
|
|
_((r: List<T>) => l
|
|
(r(EQ)(cnst(cnst(LT))))
|
|
(_(lx => _(lxs => r(GT)(_(rx => _(rxs => iif
|
|
(eqc(EQ)(ecmp(lx)(rx)))
|
|
(cmp(ecmp)(lxs)(rxs))
|
|
(ecmp(lx)(rx)))))))))));
|
|
|
|
export const lt: L<<T extends P>(ecmp: L<(l: T) => L <(r: T) => Ord>>) => L<(l: List<T>) => L<(r: List<T>) => Bool>>>
|
|
= _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
|
|
_((l: List<T>) =>
|
|
_((r: List<T>) =>
|
|
r(False)(_(rx => _(rxs => l(True)(_(lx => _(lxs => ecmp(lx)(rx)(True)(lt(ecmp)(lxs)(rxs))(False))))))))));
|
|
|
|
export const le: L<<T extends P>(ecmp: L<(l: T) => L <(r: T) => Ord>>) => L<(l: List<T>) => L<(r: List<T>) => Bool>>>
|
|
= _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
|
|
_((l: List<T>) =>
|
|
_((r: List<T>) =>
|
|
l(True)(_(lx => _(lxs => r(False)(_(rx => _(rxs => ecmp(lx)(rx)(True)(le(ecmp)(lxs)(rxs))(False))))))))));
|
|
|
|
export const eq: L<<T extends P>(eeq: L<(l: T) => L <(r: T) => Bool>>) => L<(l: List<T>) => L<(r: List<T>) => Bool>>>
|
|
= _(<T extends P>(eeq: L<(l: T) => L<(r: T) => Bool>>) =>
|
|
_((l: List<T>) =>
|
|
_((r: List<T>) => l
|
|
(r(True)(cnst(cnst(False))))
|
|
(_(lx => _(lxs => r(False)(_(rx => _(rxs => and(eeq(lx)(rx))(eq(eeq)(lxs)(rxs)))))))))));
|
|
|
|
export const ge: L<<T extends P>(ecmp: L<(l: T) => L <(r: T) => Ord>>) => L<(l: List<T>) => L<(r: List<T>) => Bool>>>
|
|
= _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
|
|
_((l: List<T>) =>
|
|
_((r: List<T>) =>
|
|
r(True)(_(rx => _(rxs => l(False)(_(lx => _(lxs => ecmp(lx)(rx)(False)(ge(ecmp)(lxs)(rxs))(True))))))))));
|
|
|
|
export const gt: L<<T extends P>(ecmp: L<(l: T) => L <(r: T) => Ord>>) => L<(l: List<T>) => L<(r: List<T>) => Bool>>>
|
|
= _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
|
|
_((l: List<T>) =>
|
|
_((r: List<T>) =>
|
|
l(False)(_(lx => _(lxs => r(True)(_(rx => _(rxs => ecmp(lx)(rx)(False)(gt(ecmp)(lxs)(rxs))(True))))))))));
|
|
|
|
export const map: L<<T extends P, R extends P>(f: L<(x: T) => R>) => L<(xs: List<T>) => List<R>>>
|
|
= _(<T extends P, R extends P>(f: L<(x: T) => R>) =>
|
|
_((xs: List<T>) => xs(Nil)(_(x => _(xs => cons(f(x))(map(f)(xs)))))));
|
|
|
|
export const filter: L<<T extends P>(f: L<(x: T) => Bool>) => L<(xs: List<T>) => List<T>>>
|
|
= _(<T extends P>(f: L<(x: T) => Bool>) =>
|
|
_((xs: List<T>) => xs(Nil)(_(x => _(xs => iif(f(x))(cons(x))(id)(filter(f)(xs)))))));
|
|
|
|
export const any: L<<T extends P>(f: L<(x: T) => Bool>) => L<(xs: List<T>) => Bool>>
|
|
= _(<T extends P>(f: L<(x: T) => Bool>) =>
|
|
_((xs: List<T>) => xs(False)(_(x => _(xs => or(f(x))(any(f)(xs)))))));
|
|
|
|
export const all: L<<T extends P>(f: L<(x: T) => Bool>) => L<(xs: List<T>) => Bool>>
|
|
= _(<T extends P>(f: L<(x: T) => Bool>) =>
|
|
_((xs: List<T>) => xs(True)(_(x => _(xs => and(f(x))(all(f)(xs)))))));
|
|
|
|
export const get: L<<T extends P>(i: Num) => L<(xs: List<T>) => T>>
|
|
= _(i => _(xs => xs(undef)(_(x => i(cnst(x))(get)))));
|
|
|
|
export const update: L<<T extends P>(f: L< (p: T) => T>) => L<(i: Num) => L<(xs: List<T>) => List<T>>>>
|
|
= _(<T extends P>(f: L< (p: T) => T>) =>
|
|
_((i: Num) =>
|
|
_((xs: List<T>) =>
|
|
xs(undef)(_(x => _(xs => i(cons(f(x))(xs))(_(pi => cons(x)(update(f)(pi)(xs))))))))));
|
|
|
|
export const set: L<<T extends P>(v: T) => L<(i: Num) => L<(xs: List<T>) => List<T>>>>
|
|
= _(v => update(cnst(v)));
|
|
|
|
export const intersperse: L<<T extends P>(v: T) => L<(xs: List<T>) => List<T>>>
|
|
= _(v => _(xs => xs(xs)(_(x => _(rxs => rxs(xs)(cnst(cnst(cons(x)(cons(v)(intersperse(v)(rxs)))))))))));
|
|
|
|
export const show: L<<T extends P>(eshow: L<(e: T) => String>) => L<(xs: List<T>) => String>>
|
|
= _(eshow => _(xs => concat(snoc(cons(_s('['))(intersperse(_s(', '))(map(eshow)(xs))))(_s(']')))));
|
|
|
|
export const fromArray: <T extends P>(xs: T[]) => List<T>
|
|
= xs => xs.length === 0 ? Nil : cons(xs[0])(___(() => fromArray(xs.slice(1)).run()));
|
|
|
|
export const toArray: <T extends P>(xs: List<T>) => P[]
|
|
= xs => $$(xs(__([]))(_(x => _(xs => __([x, ...toArray(xs)])))));
|
|
|