import { $, Term, _, _l, cnst, g, id, n, pipe, undef } from './core'; import { EQ, GT, LT, eq as eqc } from './ord'; import { False, True, and, iif, or } from './bool'; import { Zero, succ } from './num'; n('list'); export const Nil = g('Nil', _l(z => _l(_ => z))); export const Cons = g('Cons', _l(x => _l(xs => _l(_ => _l(f => f._(x)._(xs)))))); export const cons = g('cons', Cons); export const snoc = g('snoc', _l(xs => _l(x => xs._(cons._(x)._(Nil))._(_l(y => _l(ys => cons._(y)._(snoc._(ys)._(x)))))))); export const nul = g('nul', _l(xs => xs._(True)._(cnst._(cnst._(False))))); export const len = g('len', _l(xs => xs._(Zero)._(cnst._(pipe._(succ)._(len))))); export const singleton = g('singleton', _l(x => cons._(x)._(Nil))); export const append = g('append', _l(l => _l(r => l._(r)._(_l(x => _l(xs => cons._(x)._(append._(xs)._(r)))))))); export const concat = g('concat', _l(ls => ls._(Nil)._(_l(x => pipe._(append._(x))._(concat))))); export const repeat = g('repeat', _l(x => cons._(x)._(repeat._(x)))); export const iterate = g('iterate', _l(f => _l(x => cons._(x)._(iterate._(f)._(f._(x)))))); export const head = g('head', _l(xs => xs._(undef)._(cnst))); export const tail = g('tail', _l(xs => xs._(undef)._(cnst._(id)))); export const foldl = g('foldl', _l(f => _l(z => _l(xs => xs._(z)._(pipe._(foldl._(f))._(f._(z))))))); export const foldlz = g('foldlz', _l(f => _l(xs => xs._(undef)._(foldl._(f))))); export const foldr = g('foldr', _l(f => _l(z => _l(xs => xs._(z)._(_l(x => pipe._(f._(x))._(foldr._(f)._(z)))))))); export const foldrz = g('foldrz', undef); export const cmp = g('cmp', _l(ecmp => _l(l => _l(r => l._(r._(EQ)._(cnst._(cnst._(LT))))._(_l(lx => _l(lxs => r._(GT)._(_l(rx => _l(rxs => iif._(eqc._(EQ)._(ecmp._(lx)._(rx)))._(cmp._(ecmp)._(lxs)._(rxs))._(ecmp._(lx)._(rx)))))))))))); export const lt = g('lt', _l(ecmp => _l(l => _l(r => r._(False)._(_l(rx => _l(rxs => l._(True)._(_l(lx => _l(lxs => ecmp._(lx)._(rx)._(True)._(lt._(ecmp)._(lxs)._(rxs))._(False))))))))))); export const le = g('le', _l(ecmp => _l(l => _l(r => l._(True)._(_l(lx => _l(lxs => r._(False)._(_l(rx => _l(rxs => ecmp._(lx)._(rx)._(True)._(le._(ecmp)._(lxs)._(rxs))._(False))))))))))); export const eq = g('eq', _l(eeq => _l(l => _l(r => l._(r._(True)._(cnst._(cnst._(False))))._(_l(lx => _l(lxs => r._(False)._(_l(rx => _l(rxs => and._(eeq._(lx)._(rx))._(eq._(eeq)._(lxs)._(rxs)))))))))))); export const ge = g('ge', _l(ecmp => _l(l => _l(r => r._(True)._(_l(rx => _l(rxs => l._(False)._(_l(lx => _l(lxs => ecmp._(lx)._(rx)._(False)._(ge._(ecmp)._(lxs)._(rxs))._(True))))))))))); export const gt = g('gt', _l(ecmp => _l(l => _l(r => l._(False)._(_l(lx => _l(lxs => r._(True)._(_l(rx => _l(rxs => ecmp._(lx)._(rx)._(False)._(gt._(ecmp)._(lxs)._(rxs))._(True))))))))))); export const map = g('map', _l(f => _l(xs => xs._(Nil)._(_l(x => pipe._(cons._(f._(x)))._(map._(f))))))); export const filter = g('filter', _l(f => _l(xs => xs._(Nil)._(_l(x => pipe._(iif._(f._(x))._(cons._(x))._(id))._(filter._(f))))))); export const any = g('any', _l(f => _l(xs => xs._(False)._(_l(x => pipe._(or._(f._(x)))._(any._(f))))))); export const all = g('all', _l(f => _l(xs => xs._(True)._(_l(x => pipe._(and._(f._(x)))._(all._(f))))))); export const get = g('get', _l(i => _l(xs => xs._(undef)._(_l(x => i._(cnst._(x))._(get)))))); export const update = g('update', _l(f => _l(i => _l(xs => xs._(undef)._(_l(x => _l(xs => i._(cons._(f._(x))._(xs))._(_l(pi => cons._(x)._(update._(f)._(pi)._(xs))))))))))); export const set = g('set', pipe._(update)._(cnst)); export const intersperse = g('intersperse', _l(v => _l(xs => xs._(xs)._(_l(x => _l(rxs => rxs._(xs)._(cnst._(cnst._(cons._(x)._(cons._(v)._(intersperse._(v)._(rxs)))))))))))); export const fromArray: (xs: Term[]) => Term = xs => !xs.length ? Nil : Cons._(xs[0])._(_(() => fromArray(xs.slice(1)))); export const toArray: (xs: Term) => Term[] = xs => $(xs._(_([]))._(_l(x => _l(xs => _(({ x, xs }) => _([x, ...toArray(xs)]))))));