Callable lambdas

master
Freywar Ulvnaudgari 2 years ago
parent 7bb8cdc1ec
commit acec69fbac
  1. 81
      src/bf.ts
  2. 28
      src/bool.ts
  3. 10
      src/byte.ts
  4. 4
      src/char.ts
  5. 33
      src/core.ts
  6. 2
      src/index.ts
  7. 84
      src/list.ts
  8. 44
      src/num.ts
  9. 10
      src/ord.ts
  10. 65
      src/pair.ts
  11. 27
      src/string.ts
  12. 20
      test/bf.spec.ts
  13. 100
      test/bool.spec.ts
  14. 208
      test/byte.spec.ts
  15. 78
      test/char.spec.ts
  16. 6
      test/core.spec.ts
  17. 334
      test/list.spec.ts
  18. 186
      test/num.spec.ts
  19. 100
      test/pair.spec.ts
  20. 186
      test/string.spec.ts

@ -1,4 +1,4 @@
import { L, _, fromNative as __ } from './core'; import { L, _, fromNative as __, cnst, id } from './core';
import { Bool, iif } from './bool'; import { Bool, iif } from './bool';
import { Num, Zero, ge, ifz, pred, succ } from './num'; import { Num, Zero, ge, ifz, pred, succ } from './num';
import { x00 } from './byte'; import { x00 } from './byte';
@ -15,71 +15,72 @@ type IO = Pair<String, String>;
type State = Pair<Program, Pair<Tape, IO>>; type State = Pair<Program, Pair<Tape, IO>>;
const pcommand: L<(p: Program) => Char>
= uncurry._(_(is => get._(head._(is))));
const padvance: L<(p: Program) => Program>
= first._(update._(succ)._(Zero));
const pjump: L<(d: Num) => L<(p: Program) => Program>>
= _(d => _(p =>
iif._<Program>(eq._(_c('['))._(pcommand._(p)))._(pjump._(succ._(d))._(padvance._(p)))
._(iif._<Program>(eq._(_c(']'))._(pcommand._(p)))._(ifz._<Program>(pred._(d))._(p)._(pjump._(pred._(d))._(padvance._(p))))
._(pjump._(d)._(padvance._(p))))));
const done: L<(s: State) => Bool> const done: L<(s: State) => Bool>
= _(s => uncurry._(_(is => _(cs => ge._(head._(is))._(len._(cs)))))._(fst._(s))); = uncurry(_(p => cnst(uncurry(_(is => _(cs => ge(head(is))(len(cs)))))(p))));
const command: L<(s: State) => Char> const command: L<(c: String) => L<(s: State) => Bool>>
= _(s => pcommand._(fst._(s))); = _(c => uncurry(_(p => cnst(eq(c)(uncurry(_(is => get(head(is))))(p))))));
const advance: L<(s: State) => State> const advance: L<(s: State) => State>
= first._(padvance); = first(first(update(succ)(Zero)));
const jump: L<(s: State) => State>
= first._(pjump._(Zero));
const save: L<(s: State) => State> const save: L<(s: State) => State>
= first._(first._(_(is => cons._(head._(is))._(is)))); = first(first(_(is => cons(head(is))(is))));
const restore: L<(s: State) => State> const restore: L<(s: State) => State>
= first._(first._(tail)); = first(first(tail));
const reset: L<(s: State) => State> const reset: L<(s: State) => State>
= first._(first._(_(is => cons._(head._(is))._(tail._(tail._(is)))))); = first(first(_(is => cons(head(is))(tail(tail(is))))));
const inc: L<(t: State) => State> const inc: L<(t: State) => State>
= second._(first._(_(t => second._(update._(cinc)._(fst._(t)))._(t)))); = second(first(_(t => second(update(cinc)(fst(t)))(t))));
const dec: L<(t: State) => State> const dec: L<(t: State) => State>
= second._(first._(_(t => second._(update._(cdec)._(fst._(t)))._(t)))); = second(first(_(t => second(update(cdec)(fst(t)))(t))));
const read: L<(s: State) => Char> const read: L<(s: State) => Char>
= _(s => uncurry._(get)._(fst._(snd._(s)))); = _(s => uncurry(get)(fst(snd(s))));
const input: L<(s: State) => State> const input: L<(s: State) => State>
= second._(uncurry._(_(t => _(io => Pair._(second._(set._(head._(fst._(io)))._(fst._(t)))._(t))._(first._(tail)._(io)))))); = second(uncurry(_(t => _(io => Pair(second(set(head(fst(io)))(fst(t)))(t))(first(tail)(io))))));
const output: L<(s: State) => State> const output: L<(s: State) => State>
= second._(uncurry._(_(t => _(io => Pair._(t)._(second._(_(os => snoc._(os)._(uncurry._(get)._(t))))._(io)))))); = second(uncurry(_(t => _(io => Pair(t)(second(_(os => snoc(os)(uncurry(get)(t))))(io))))));
const next: L<(t: State) => State> const next: L<(t: State) => State>
= second._(first._(first._(succ))); = second(first(first(succ)));
const prev: L<(t: State) => State> const prev: L<(t: State) => State>
= second._(first._(first._(pred))); = second(first(first(pred)));
const jump: L<(d: Num) => L<(s: State) => State>>
= _(d => _(s =>
iif(command(_c('['))(s))(jump(succ(d)))
(iif(command(_c(']'))(s))(ifz(pred(d))(cnst(s))(jump(pred(d))))
(jump(d)))(advance(s))));
const whlnz: L<(t: State) => State>
= _(s => ifn(read(s))(jump(Zero))(save)(s));
const endwhl: L<(t: State) => State>
= _(s => ifn(read(s))(reset(s))(save(restore(s))));
const when: L<(c: String) => L<(f: L<(s: State) => State>) => L<(s:State)=>State>>>
= _(c => _(f => _(s => iif(command(c)(s))(f(s))(s))));
const exec: L<(s: State) => State> const exec: L<(s: State) => State>
= _(s => iif._<State>(done._(s))._(s)._(exec._(advance = _(s => iif<State>(done(s))(s)(exec(advance
._(iif._<State>(eq._(_c('>'))._(command._(s)))._(next._(s)) (iif(command(_c('>'))(s))(next)
._(iif._<State>(eq._(_c('<'))._(command._(s)))._(prev._(s)) (iif(command(_c('<'))(s))(prev)
._(iif._<State>(eq._(_c('+'))._(command._(s)))._(inc._(s)) (iif(command(_c('+'))(s))(inc)
._(iif._<State>(eq._(_c('-'))._(command._(s)))._(dec._(s)) (iif(command(_c('-'))(s))(dec)
._(iif._<State>(eq._(_c('.'))._(command._(s)))._(output._(s)) (iif(command(_c('.'))(s))(output)
._(iif._<State>(eq._(_c(','))._(command._(s)))._(input._(s)) (iif(command(_c(','))(s))(input)
._(iif._<State>(eq._(_c('['))._(command._(s)))._(ifn._<State>(read._(s))._(jump._(s))._(save._(s))) (iif(command(_c('['))(s))(whlnz)
._(iif._<State>(eq._(_c(']'))._(command._(s)))._(ifn._<State>(read._(s))._(reset._(s))._(save._(restore._(s)))) (iif(command(_c(']'))(s))(endwhl)
._(s)))))))))))); (id))))))))(s)))));
export const run: L<(p: String) => L<(i: String) => String>> export const run: L<(p: String) => L<(i: String) => String>>
= _(p => _(i => snd._(snd._(snd._(exec._(Pair._(Pair._(cons._(Zero)._(Nil))._(p))._(Pair._(Pair._(Zero)._(repeat._(x00)))._(Pair._(i)._(Empty))))))))); = _(p => _(i => snd(snd(snd(exec(Pair(Pair(cons(Zero)(Nil))(p))(Pair(Pair(Zero)(repeat(x00)))(Pair(i)(Empty)))))))));

@ -1,4 +1,4 @@
import { toNative as $$, L, P, _, fromNative as __ } from './core'; import { toNative as $$, L, P, _, fromNative as __, id } from './core';
import { EQ, GT, LT, Ord } from './ord'; import { EQ, GT, LT, Ord } from './ord';
import { String, fromString as _s } from './string'; import { String, fromString as _s } from './string';
@ -11,43 +11,43 @@ export const False: Bool
= _(_t => _(f => f)); = _(_t => _(f => f));
export const iif: L<<T extends P>(b: Bool) => L<(t: T) => L<(f: T) => T>>> export const iif: L<<T extends P>(b: Bool) => L<(t: T) => L<(f: T) => T>>>
= _(b => _(t => _(f => b._(t)._(f)))); = id;
export const not: L<(b: Bool) => Bool> export const not: L<(b: Bool) => Bool>
= _(b => b._(False)._(True)); = _(b => b(False)(True));
export const cmp: L<(l: Bool) => L<(r: Bool) => Ord>> export const cmp: L<(l: Bool) => L<(r: Bool) => Ord>>
= _(l => _(r => l._(r._(EQ)._(GT))._(r._(LT)._(EQ)))); = _(l => _(r => l(r(EQ)(GT))(r(LT)(EQ))));
export const lt: L<(l: Bool) => L<(r: Bool) => Bool>> export const lt: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(False)._(r))); = _(l => l(False));
export const le: L<(l: Bool) => L<(r: Bool) => Bool>> export const le: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(r)._(True))); = _(l => not(l)(True));
export const eq: L<(l: Bool) => L<(r: Bool) => Bool>> export const eq: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(r)._(not._(r)))); = _(l => _(r => l(r)(not(r))));
export const ge: L<(l: Bool) => L<(r: Bool) => Bool>> export const ge: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(True)._(not._(r)))); = _(l => _(r => not(lt(l)(r))));
export const gt: L<(l: Bool) => L<(r: Bool) => Bool>> export const gt: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(not._(r))._(False))); = _(l => _(r => not(le(l)(r))));
export const and: L<(l: Bool) => L<(r: Bool) => Bool>> export const and: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(r)._(False))); = _(l => not(l)(False));
export const or: L<(l: Bool) => L<(r: Bool) => Bool>> export const or: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(True)._(r))); = _(l => l(True));
export const xor: L<(l: Bool) => L<(r: Bool) => Bool>> export const xor: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(not._(r))._(r))); = _(l => _(r => l(not(r))(r)));
export const show: L<(b: Bool) => String> export const show: L<(b: Bool) => String>
= _(b => iif._(b)._(_s('True'))._(_s('False'))); = _(b => iif(b)(_s('True'))(_s('False')));
export const fromBoolean: (b: boolean) => Bool export const fromBoolean: (b: boolean) => Bool
= b => b ? True : False; = b => b ? True : False;
export const toBoolean: (b: Bool) => boolean export const toBoolean: (b: Bool) => boolean
= b => $$(b._(__(true))._(__(false))); = b => $$(b(__(true))(__(false)));

@ -11,7 +11,7 @@ export const xFF: Num
= _n(255); = _n(255);
export const Inc: L<(p: Byte) => Byte> export const Inc: L<(p: Byte) => Byte>
= _(p => iif._(eq._(xFF)._(p))._(x00)._(Succ._(p))); = _(p => iif(eq(xFF)(p))(x00)(Succ(p)));
export { ifz, cmp, lt, le, eq, ge, gt, even, odd, div, mod, show, toNumber } from './num'; export { ifz, cmp, lt, le, eq, ge, gt, even, odd, div, mod, show, toNumber } from './num';
@ -19,16 +19,16 @@ export const inc: L<(n: Byte) => Byte>
= Inc; = Inc;
export const dec: L<(n: Byte) => Byte> export const dec: L<(n: Byte) => Byte>
= _(n => n._(xFF)._(id)); = _(n => n(xFF)(id));
export const sum: L<(l: Byte) => L<(r: Byte) => Byte>> export const sum: L<(l: Byte) => L<(r: Byte) => Byte>>
= _(l => _(r => r._(l)._(_(pr => sum._(inc._(l))._(pr))))); = _(l => _(r => r(l)(sum(inc(l)))));
export const sub: L<(l: Byte) => L<(r: Byte) => Byte>> export const sub: L<(l: Byte) => L<(r: Byte) => Byte>>
= _(l => _(r => r._(l)._(_(pr => sub._(dec._(l))._(pr))))); = _(l => _(r => r(l)(sub(dec(l)))));
export const mul: L<(l: Byte) => L<(r: Byte) => Byte>> export const mul: L<(l: Byte) => L<(r: Byte) => Byte>>
= _(l => _(r => l._(x00)._(_(pl => sum._(r)._(mul._(pl)._(r)))))); = _(l => _(r => l(x00)(_(pl => sum(r)(mul(pl)(r))))));
export const fromNumber: (n: number) => Byte export const fromNumber: (n: number) => Byte
= n => _n(n % 256); = n => _n(n % 256);

@ -1,6 +1,6 @@
import { L, _ } from './core'; import { L, _ } from './core';
import { toNumber as $n, Byte, fromNumber as _n, x00 } from './byte'; import { toNumber as $n, Byte, fromNumber as _n, x00 } from './byte';
import { Empty, String, cons } from './string'; import { Empty, String, cons, fromString as _s, wrap } from './string';
export type Char = Byte; export type Char = Byte;
@ -10,7 +10,7 @@ export const Null: Char
export { inc, dec, ifz as ifn, cmp, lt, le, eq, ge, gt } from './byte'; export { inc, dec, ifz as ifn, cmp, lt, le, eq, ge, gt } from './byte';
export const show: L<(c: Char) => String> export const show: L<(c: Char) => String>
= _(c => cons._(fromChar('\''))._(cons._(c)._(cons._(fromChar('\''))._(Empty)))); = _(c => wrap(_s('\''))(cons(c)(Empty)));
export const fromChar: (c: string) => Char export const fromChar: (c: string) => Char
= c => _n(c.charCodeAt(0)); = c => _n(c.charCodeAt(0));

@ -1,33 +1,28 @@
export class L<T extends (v: unknown) => L<any>> { export type L<T extends (v: P) => L<any>> = T & { run: () => T; }
protected _value?: T;
constructor(private _eval: () => T) { } export function ___<T extends (v: P) => L<any>>(run: () => T): L<T>{
const r: T = ((p: Parameters<T>[0]) => {
let v: any;
return ___(() => run()(
___(() => v ??= p.run())
).run());
}) as T;
public evaluated: boolean = false; (r as L<T>).run = run;
public get value(): T { return r as L<T>;
if (this.evaluated) {
return this._value!;
}
this.evaluated = true;
return this._value = this._eval();
}
public get _(): T {
return ((p: Parameters<T>[0]) => new L(() => this.value(p).value)) as T;
}
} }
export type P = L<(v: unknown) => L<any>>; export type P = L<(v: unknown) => L<any>>;
export const _ = <T extends ((v: unknown) => L<any>)>(v: T): L<T> => new L(() => v); export const _ = <T extends ((v: unknown) => L<any>)>(v: T): L<T> => ___(() => v);
export const fromNative: <T>(v: T) => L<any> export const fromNative: <T>(v: T) => L<any>
= v => new L(() => v as any); = v => ___(() => v as any);
export const toNative: <T>(v: L<any>) => T export const toNative: <T>(v: L<any>) => T
= <T>(v: L<any>) => v.value as T; = <T>(v: L<any>) => v.run() as T;
export const undef: any = new L(() => { export const undef: any = ___(() => {
throw new Error('undefined'); throw new Error('undefined');
}); });

@ -1,3 +1,3 @@
import { toNative as $$, _, fromNative as __, id } from './core'; import { toNative as $$, _, fromNative as __, id } from './core';
console.log($$(id._(__('first')))); console.log($$(id(__('first'))));

@ -1,4 +1,4 @@
import { toNative as $$, L, P, _, fromNative as __, undef } from './core'; import { toNative as $$, L, P, _, fromNative as __, ___, cnst, id, undef } from './core';
import { EQ, GT, LT, Ord, eq as eqc } from './ord'; import { EQ, GT, LT, Ord, eq as eqc } from './ord';
import { Bool, False, True, and, iif, or } from './bool'; import { Bool, False, True, and, iif, or } from './bool';
import { Num, Zero, succ } from './num'; import { Num, Zero, succ } from './num';
@ -10,142 +10,132 @@ export const Nil: List<any>
= _(z => _(_f => z)) as List<any>; = _(z => _(_f => z)) as List<any>;
export const Cons: L<<T extends P>(x: T) => L<(xs: List<T>) => List<T>>> 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>)); = _(<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>>> export const cons: L<<T extends P>(x: T) => L<(xs: List<T>) => List<T>>>
= Cons; = Cons;
export const snoc: L<<T extends P>(xs: List<T>) => L<(x: T) => List<T>>> export const snoc: L<<T extends P>(xs: List<T>) => L<(x: T) => List<T>>>
= _(<T extends P>(xs: List<T>) => = _(<T extends P>(xs: List<T>) =>
_((x: T) => xs._(cons._(x)._(Nil))._(_(y => _(ys => cons._(y)._(snoc._(ys)._(x))))))); _((x: T) => xs(cons(x)(Nil))(_(y => _(ys => cons(y)(snoc(ys)(x)))))));
export const nul: L<<T extends P>(xs: List<T>) => Bool> export const nul: L<<T extends P>(xs: List<T>) => Bool>
= _(xs => xs._(True)._(_(_x => _(_xs => False)))); = _(xs => xs(True)(cnst(cnst(False))));
export const len: L<<T extends P>(xs: List<T>) => Num> export const len: L<<T extends P>(xs: List<T>) => Num>
= _(xs => xs._(Zero)._(_(_x => _(xs => succ._(len._(xs)))))); = _(xs => xs(Zero)(_(_x => _(xs => succ(len(xs))))));
export const append: L<<T extends P>(l: List<T>) => L<(r: List<T>) => List<T>>> 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))))))); = _(l => _(r => l(r)(_(x => _(xs => cons(x)(append(xs)(r)))))));
export const concat: L<<T extends P>(ls: List<List<T>>) => List<T>> export const concat: L<<T extends P>(ls: List<List<T>>) => List<T>>
= _(ls => ls._(Nil)._(_(x => _(xs => append._(x)._(concat._(xs)))))); = _(ls => ls(Nil)(_(x => _(xs => append(x)(concat(xs))))));
export const repeat: L<<T extends P>(x: T) => List<T>> export const repeat: L<<T extends P>(x: T) => List<T>>
= _(x => cons._(x)._(repeat._(x))); = _(x => cons(x)(repeat(x)));
export const iterate: L<<T extends P>(f: L<(x: T) => T>) => L<(x: T) => List<T>>> 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>) => = _(<T extends P>(f: L<(x: T) => T>) => _((x: T) => cons(x)(iterate(f)(f(x)))));
_((x: T) =>
cons._(x)._(iterate._(f)._(f._(x)))));
export const head: L<<T extends P>(xs: List<T>) => T> export const head: L<<T extends P>(xs: List<T>) => T>
= _(xs => xs._(undef)._(_(x => _(_xs => x)))); = _(xs => xs(undef)(cnst));
export const tail: L<<T extends P>(xs: List<T>) => List<T>> export const tail: L<<T extends P>(xs: List<T>) => List<T>>
= _(xs => xs._(undef)._(_(_x => _(xs => xs)))); = _(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>>> 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>>) => = _(<T extends P, R extends P>(f: L<(a: R) => L<(x: T) => R>>) =>
_((z: R) => _((z: R) =>
_((xs: List<T>) => xs._(z)._(_(x => _((xs: List<T>) => xs(z)(_(x => foldl(f)(f(z)(x)))))));
_(xs => foldl._(f)._(f._(z)._(x))._(xs)))))));
export const foldlz: L<<T extends P>(f: L<(a: T) => L<(x: T) => T>>) => L<(xs: List<T>) => T>> 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>>) => = _(<T extends P>(f: L<(a: T) => L<(x: T) => T>>) => _((xs: List<T>) => xs(undef)(foldl(f))));
_((xs: List<T>) =>
xs._(undef)._(_(x =>
_(xs => foldl._(f)._(x)._(xs))))));
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>>> 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>>) => = _(<T extends P, R extends P>(f: L<(x: T) => L<(a: R) => R>>) =>
_((z: R) => _((z: R) =>
_((xs: List<T>) => xs._(z)._(_(x => _(xs => f._(x)._(foldr._(f)._(z)._(xs)))))))); _((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>> export const foldrz: L<<T extends P>(f: L<(x: T) => L<(a: T) => T>>) => L<(xs: List<T>) => T>>
= _(_f => _(_z => undef)); = 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>>> 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>>) => = _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
_((l: List<T>) => _((l: List<T>) =>
_((r: List<T>) => l _((r: List<T>) => l
._(r._(EQ)._(_(_x => _(_xs => LT)))) (r(EQ)(cnst(cnst(LT))))
._(_(lx => _(lxs => r._(GT)._(_(rx => _(rxs => iif (_(lx => _(lxs => r(GT)(_(rx => _(rxs => iif
._(eqc._(EQ)._(ecmp._(lx)._(rx))) (eqc(EQ)(ecmp(lx)(rx)))
._(cmp._(ecmp)._(lxs)._(rxs)) (cmp(ecmp)(lxs)(rxs))
._(ecmp._(lx)._(rx))))))))))); (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>>> 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>>) => = _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
_((l: List<T>) => _((l: List<T>) =>
_((r: List<T>) => _((r: List<T>) =>
r._(False)._(_(rx => _(rxs => l._(True)._(_(lx => _(lxs => ecmp._(lx)._(rx)._(True)._(lt._(ecmp)._(lxs)._(rxs))._(False)))))))))); 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>>> 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>>) => = _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
_((l: List<T>) => _((l: List<T>) =>
_((r: List<T>) => _((r: List<T>) =>
l._(True)._(_(lx => _(lxs => r._(False)._(_(rx => _(rxs => ecmp._(lx)._(rx)._(True)._(le._(ecmp)._(lxs)._(rxs))._(False)))))))))); 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>>> 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>>) => = _(<T extends P>(eeq: L<(l: T) => L<(r: T) => Bool>>) =>
_((l: List<T>) => _((l: List<T>) =>
_((r: List<T>) => l _((r: List<T>) => l
._(r._(True)._(_(_x => _(_xs => False)))) (r(True)(cnst(cnst(False))))
._(_(lx => _(lxs => r._(False)._(_(rx => _(rxs => and._(eeq._(lx)._(rx))._(eq._(eeq)._(lxs)._(rxs))))))))))); (_(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>>> 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>>) => = _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
_((l: List<T>) => _((l: List<T>) =>
_((r: List<T>) => _((r: List<T>) =>
r._(True)._(_(rx => _(rxs => l._(False)._(_(lx => _(lxs => ecmp._(lx)._(rx)._(False)._(ge._(ecmp)._(lxs)._(rxs))._(True)))))))))); 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>>> 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>>) => = _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
_((l: List<T>) => _((l: List<T>) =>
_((r: List<T>) => _((r: List<T>) =>
l._(False)._(_(lx => _(lxs => r._(True)._(_(rx => _(rxs => ecmp._(lx)._(rx)._(False)._(gt._(ecmp)._(lxs)._(rxs))._(True)))))))))); 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>>> 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>) => = _(<T extends P, R extends P>(f: L<(x: T) => R>) =>
_((xs: List<T>) => xs._(Nil)._(_(x => _(xs => Cons._(f._(x))._(map._(f)._(xs))))))); _((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>>> 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>) => = _(<T extends P>(f: L<(x: T) => Bool>) =>
_((xs: List<T>) => xs._(Nil)._(_(x => _(xs => iif._(f._(x))._(Cons._(x)._(filter._(f)._(xs)))._(filter._(f)._(xs))))))); _((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>> 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>) => = _(<T extends P>(f: L<(x: T) => Bool>) =>
_((xs: List<T>) => xs._(False)._(_(x => _(xs => or._(f._(x))._(any._(f)._(xs))))))); _((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>> 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>) => = _(<T extends P>(f: L<(x: T) => Bool>) =>
_((xs: List<T>) => xs._(True)._(_(x => _(xs => and._(f._(x))._(all._(f)._(xs))))))); _((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>> export const get: L<<T extends P>(i: Num) => L<(xs: List<T>) => T>>
= _(<T extends P>(i: Num) => = _(i => _(xs => xs(undef)(_(x => i(cnst(x))(get)))));
_((xs: List<T>) =>
xs._(undef)._(_((x: T) => _((xs: List<T>) => i._(x)._(_(pi => get._<T>(pi)._(xs))))))));
export const update: L<<T extends P>(f: L< (p: T) => T>) => L<(i: Num) => L<(xs: List<T>) => List<T>>>> 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>) => = _(<T extends P>(f: L< (p: T) => T>) =>
_((i: Num) => _((i: Num) =>
_((xs: List<T>) => _((xs: List<T>) =>
xs._(undef)._(_(x => _(xs => i._(cons._(f._(x))._(xs))._(_(pi => cons._(x)._(update._(f)._(pi)._(xs)))))))))); 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>>>> export const set: L<<T extends P>(v: T) => L<(i: Num) => L<(xs: List<T>) => List<T>>>>
= _(<T extends P>(v: T) => update._<T>(_(_ => v))); = _(v => update(cnst(v)));
export const intersperse: L<<T extends P>(v: T) => L<(xs: List<T>) => List<T>>> export const intersperse: L<<T extends P>(v: T) => L<(xs: List<T>) => List<T>>>
= _(v => _(xs => = _(v => _(xs => xs(xs)(_(x => _(rxs => rxs(xs)(cnst(cnst(cons(x)(cons(v)(intersperse(v)(rxs)))))))))));
xs._(xs)._(_(x => _(rxs => rxs._(xs)._(_(_rx => _(_rrxs => cons._(x)._(cons._(v)._(intersperse._(v)._(rxs)))))))))));
export const show: L<<T extends P>(eshow: L<(e: T) => String>) => L<(xs: List<T>) => String>> export const show: L<<T extends P>(eshow: L<(e: T) => String>) => L<(xs: List<T>) => String>>
= _(eshow => _(xs => = _(eshow => _(xs => concat(snoc(cons(_s('['))(intersperse(_s(', '))(map(eshow)(xs))))(_s(']')))));
concat._(snoc._(cons._(_s('['))._(intersperse._(_s(', '))._(map._(eshow)._(xs))))._(_s(']')))));
export const fromArray: <T extends P>(xs: T[]) => List<T> export const fromArray: <T extends P>(xs: T[]) => List<T>
= xs => xs.length === 0 ? Nil : Cons._(xs[0])._(new L(() => fromArray(xs.slice(1)).value)); = xs => xs.length === 0 ? Nil : cons(xs[0])(___(() => fromArray(xs.slice(1)).run()));
export const toArray: <T extends P>(xs: List<T>) => P[] export const toArray: <T extends P>(xs: List<T>) => P[]
= xs => $$(xs._(__([]))._(_(x => _(xs => __([x, ...toArray(xs)]))))); = xs => $$(xs(__([]))(_(x => _(xs => __([x, ...toArray(xs)])))));

@ -1,4 +1,4 @@
import { toNative as $$, L, P, _, fromNative as __, id } from './core'; import { toNative as $$, L, P, _, fromNative as __, ___, cnst, id } from './core';
import { EQ, GT, LT, Ord } from './ord'; import { EQ, GT, LT, Ord } from './ord';
import { Bool, False, True, iif } from './bool'; import { Bool, False, True, iif } from './bool';
import { Empty, String, append, cons } from './string'; import { Empty, String, append, cons } from './string';
@ -9,63 +9,63 @@ export const Zero: Num
= _(z => _(_n => z)) as Num; = _(z => _(_n => z)) as Num;
export const Succ: L<(p: Num) => Num> export const Succ: L<(p: Num) => Num>
= _(p => _(_z => _(n => n._(p)))); = _(p => _(_z => _(n => n(p))));
export const ifz: L<<T extends P>(n: Num) => L<(t: T) => L<(f: T) => T>>> export const ifz: L<<T extends P>(n: Num) => L<(t: T) => L<(f: T) => T>>>
= _(n => _(t => _(f => n._(t)._(_(_ => f))))); = _(n => _(t => _(f => n(t)(cnst(f)))));
export const succ: L<(n: Num) => Num> export const succ: L<(n: Num) => Num>
= Succ; = Succ;
export const pred: L<(n: Num) => Num> export const pred: L<(n: Num) => Num>
= _(n => n._(Zero)._(id)); = _(n => n(Zero)(id));
export const cmp: L<(l: Num) => L<(r: Num) => Ord>> export const cmp: L<(l: Num) => L<(r: Num) => Ord>>
= _(l => _(r => l._(r._(EQ)._(_(_ => LT)))._(_(pl => r._(GT)._(_(pr => cmp._(pl)._(pr))))))); = _(l => _(r => l(r(EQ)(cnst(LT)))(_(pl => r(GT)(cmp(pl))))));
export const lt: L<(l: Num) => L<(r: Num) => Bool>> export const lt: L<(l: Num) => L<(r: Num) => Bool>>
= _(l => _(r => r._(False)._(_(pr => l._(True)._(_(pl => lt._(pl)._(pr))))))); = _(l => _(r => r(False)(l(cnst(True))(lt))));
export const le: L<(l: Num) => L<(r: Num) => Bool>> export const le: L<(l: Num) => L<(r: Num) => Bool>>
= _(l => _(r => l._(True)._(_(pl => r._(False)._(_(pr => le._(pl)._(pr))))))); = _(l => _(r => l(True)(r(cnst(False))(ge))));
export const eq: L<(l: Num) => L<(r: Num) => Bool>> export const eq: L<(l: Num) => L<(r: Num) => Bool>>
= _(l => _(r => l._(r._(True)._(_(_ => False)))._(_(pl => r._(False)._(_(pr => eq._(pl)._(pr))))))); = _(l => _(r => l(r(True)(cnst(False)))(r(cnst(False))(eq))));
export const ge: L<(l: Num) => L<(r: Num) => Bool>> export const ge: L<(l: Num) => L<(r: Num) => Bool>>
= _(l => _(r => r._(True)._(_(pr => l._(False)._(_(pl => ge._(pl)._(pr))))))); = _(l => _(r => r(True)(l(cnst(False))(ge))));
export const gt: L<(l: Num) => L<(r: Num) => Bool>> export const gt: L<(l: Num) => L<(r: Num) => Bool>>
= _(l => _(r => l._(False)._(_(pl => r._(True)._(_(pr => gt._(pl)._(pr))))))); = _(l => _(r => l(False)(r(cnst(True))(lt))));
export const even: L<(n: Num) => Bool> export const even: L<(n: Num) => Bool>
= _(n => n._(True)._(odd)); = _(n => n(True)(odd));
export const odd: L<(n: Num) => Bool> export const odd: L<(n: Num) => Bool>
= _(n => n._(False)._(even)); = _(n => n(False)(even));
export const sum: L<(l: Num) => L<(r: Num) => Num>> export const sum: L<(l: Num) => L<(r: Num) => Num>>
= _(l => _(r => r._(l)._(_(t => sum._(Succ._(l))._(t))))); = _(l => _(r => r(l)(sum(Succ(l)))));
export const sub: L<(l: Num) => L<(r: Num) => Num>> export const sub: L<(l: Num) => L<(r: Num) => Num>>
= _(l => _(r => r._(l)._(_(pr => l._(Zero)._(_(pl => sub._(pl)._(pr))))))); = _(l => _(r => r(l)(l(cnst(Zero))(sub))));
export const mul: L<(l: Num) => L<(r: Num) => Num>> export const mul: L<(l: Num) => L<(r: Num) => Num>>
= _(l => _(r => l._(Zero)._(_(pl => sum._(r)._(mul._(pl)._(r)))))); = _(l => _(r => l(Zero)(_(pl => sum(r)(mul(pl)(r))))));
export const div: L<(l: Num) => L<(r: Num) => Num>> export const div: L<(l: Num) => L<(r: Num) => Num>>
= _(l => _(r => iif._(lt._(l)._(r))._(Zero)._(succ._(div._(sub._(l)._(r))._(r))))); = _(l => _(r => iif(lt(l)(r))(Zero)(succ(div(sub(l)(r))(r)))));
export const mod: L<(l: Num) => L<(r: Num) => Num>> export const mod: L<(l: Num) => L<(r: Num) => Num>>
= _(l => _(r => iif._(lt._(l)._(r))._(l)._(mod._(sub._(l)._(r))._(r)))); = _(l => _(r => iif(lt(l)(r))(l)(mod(sub(l)(r))(r))));
export const show: L<(n: Num) => String> export const show: L<(n: Num) => String>
= _(n => iif._(lt._(n)._(fromNumber(10))) = _(n => iif(lt(n)(fromNumber(10)))
._(cons._(sum._(n)._(fromNumber(48)))._(Empty)) (cons(sum(n)(fromNumber(48)))(Empty))
._(append._(show._(div._(n)._(fromNumber(10))))._(show._(mod._(n)._(fromNumber(10)))))); (append(show(div(n)(fromNumber(10))))(show(mod(n)(fromNumber(10))))));
export const fromNumber: (n: number) => Num export const fromNumber: (n: number) => Num
= n => !n ? Zero : Succ._(new L(() => fromNumber(n - 1).value)); = n => !n ? Zero : Succ(___(() => fromNumber(n - 1).run()));
export const toNumber: (n: Num) => number export const toNumber: (n: Num) => number
= n => $$(n._(__(0))._(_(p => __(1 + toNumber(p))))); = n => $$(n(__(0))(_(p => __(1 + toNumber(p)))));

@ -21,15 +21,15 @@ export const GT: Ord
export const eq: L<(l: Ord) => L<(r: Ord) => Bool>> export const eq: L<(l: Ord) => L<(r: Ord) => Bool>>
= _(l => _(r => l = _(l => _(r => l
._(r._(True)._(False)._(False)) (r(True)(False)(False))
._(r._(False)._(True)._(False)) (r(False)(True)(False))
._(r._(False)._(False)._(True)))); (r(False)(False)(True))));
export const show: L<(o: Ord) => String> export const show: L<(o: Ord) => String>
= _(o => o._(_s('LT'))._(_s('EQ'))._(_s('GT'))); = _(o => o(_s('LT'))(_s('EQ'))(_s('GT')));
export const fromNOrd: (b: NOrd) => Ord export const fromNOrd: (b: NOrd) => Ord
= o => o === NOrd.LT ? LT : o === NOrd.EQ ? EQ : GT; = o => o === NOrd.LT ? LT : o === NOrd.EQ ? EQ : GT;
export const toNOrd: (b: Ord) => NOrd export const toNOrd: (b: Ord) => NOrd
= o => $$(o._(__(NOrd.LT))._(__(NOrd.EQ))._(__(NOrd.GT))); = o => $$(o(__(NOrd.LT))(__(NOrd.EQ))(__(NOrd.GT)));

@ -9,75 +9,74 @@ export type Pair<F extends P, S extends P> = L<<R extends P>(f: L<(f: F) => L<(s
export const Pair: L<<F extends P, S extends P>(f: F) => L<(s: S) => Pair<F, S>>> export const Pair: L<<F extends P, S extends P>(f: F) => L<(s: S) => Pair<F, S>>>
= _(<F extends P, S extends P>(f: F) => = _(<F extends P, S extends P>(f: F) =>
_((s: S) => _((s: S) =>
_(<R extends P>(p: L<(f: F) => L<(s: S) => R>>) => p._(f)._(s)))); _(<R extends P>(p: L<(f: F) => L<(s: S) => R>>) => p(f)(s))));
export const fst: L<<F extends P, S extends P>(p: Pair<F, S>) => F> export const fst: L<<F extends P, S extends P>(p: Pair<F, S>) => F>
= _(p => p._(_(f => _(_s => f)))); = _(p => p(_(f => _(_s => f))));
export const snd: L<<F extends P, S extends P>(p: Pair<F, S>) => S> export const snd: L<<F extends P, S extends P>(p: Pair<F, S>) => S>
= _(p => p._(_(_f => _(s => s)))); = _(p => p(_(_f => _(s => s))));
export const first: L<<F extends P, FR extends P, S extends P>(t: L<(f: F) => FR>) => L<(p: Pair<F, S>) => Pair<FR, S>>> export const first: L<<F extends P, FR extends P, S extends P>(t: L<(f: F) => FR>) => L<(p: Pair<F, S>) => Pair<FR, S>>>
= _(<F extends P, FR extends P>(t: L<(f: F) => FR>) => = _(<F extends P, FR extends P>(t: L<(f: F) => FR>) =>
_(<S extends P>(p: Pair<F, S>) => p._(_(f => _(s => Pair._(t._(f))._(s)))))); _(<S extends P>(p: Pair<F, S>) => p(_(f => _(s => Pair(t(f))(s))))));
export const second: L<<F extends P, S extends P, SR extends P>(t: L<(s: S) => SR>) => L<(p: Pair<F, S>) => Pair<F, SR>>> export const second: L<<F extends P, S extends P, SR extends P>(t: L<(s: S) => SR>) => L<(p: Pair<F, S>) => Pair<F, SR>>>
= _(<S extends P, SR extends P>(t: L<(s: S) => SR>) => = _(<S extends P, SR extends P>(t: L<(s: S) => SR>) =>
_(<F extends P>(p: Pair<F, S>) => p._(_(f => _(s => Pair._(f)._(t._(s))))))); _(<F extends P>(p: Pair<F, S>) => p(_(f => _(s => Pair(f)(t(s)))))));
export const both: L<<F extends P, FR extends P, S extends P, SR extends P>(tf: L<(f: F) => FR>) => L<(ts: L<(s: S) => SR>) => L<(p: Pair<F, S>) => Pair<FR, SR>>>> export const both: L<<F extends P, FR extends P, S extends P, SR extends P>(tf: L<(f: F) => FR>) => L<(ts: L<(s: S) => SR>) => L<(p: Pair<F, S>) => Pair<FR, SR>>>>
= _(<F extends P, FR extends P>(tf: L<(f: F) => FR>) => = _(<F extends P, FR extends P>(tf: L<(f: F) => FR>) =>
_(<S extends P, SR extends P>(ts: L<(s: S) => SR>) => _(<S extends P, SR extends P>(ts: L<(s: S) => SR>) =>
_((p: Pair<F, S>) => p._(_(f => _(s => Pair._(tf._(f))._(ts._(s)))))))); _((p: Pair<F, S>) => p(_(f => _(s => Pair(tf(f))(ts(s))))))));
export const uncurry: L<<F extends P, S extends P, R extends P>(t: L<(f: F) => L<(s: S) => R>>) => L<(p: Pair<F, S>) => R>> export const uncurry: L<<F extends P, S extends P, R extends P>(t: L<(f: F) => L<(s: S) => R>>) => L<(p: Pair<F, S>) => R>>
= _(<F extends P, S extends P, R extends P>(t: L<(f: F) => L<(s: S) => R>>) => = _(<F extends P, S extends P, R extends P>(t: L<(f: F) => L<(s: S) => R>>) =>
_((p: Pair<F, S>) => p._(t))); _((p: Pair<F, S>) => p(t)));
export const cmp: L<<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => L<(scmp: L<(l: S) => L<(r: S) => Ord>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Ord>>>> export const cmp: L<<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => L<(scmp: L<(l: S) => L<(r: S) => Ord>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Ord>>>>
= _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => = _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) =>
_((scmp: L<(l: S) => L<(r: S) => Ord>>) => _((scmp: L<(l: S) => L<(r: S) => Ord>>) =>
_((l: Pair<F, S>) => uncurry(_((lf: F) => _((ls: S) =>
_((r: Pair<F, S>) => uncurry(_((rf: F) => _((rs: S) =>
fcmp._(fst._(l))._(fst._(r))._(LT)._(scmp._(snd._(l))._(snd._(r)))._(GT))))); fcmp(lf)(rf)(LT)(scmp(ls)(rs))(GT)))))))));
export const lt: L<<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => L<(scmp: L<(l: S) => L<(r: S) => Bool>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Bool>>>> export const lt: L<<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => L<(scmp: L<(l: S) => L<(r: S) => Bool>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Bool>>>>
= _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => = _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) =>
_((scmp: L<(l: S) => L<(r: S) => Ord>>) => _((scmp: L<(l: S) => L<(r: S) => Ord>>) =>
_((l: Pair<F, S>) => uncurry(_((lf: F) => _((ls: S) =>
_((r: Pair<F, S>) => uncurry(_((rf: F) => _((rs: S) =>
fcmp._(fst._(l))._(fst._(r))._(True)._(scmp._(snd._(l))._(snd._(r))._(True)._(False)._(False))._(False))))); fcmp(lf)(rf)(True)(scmp(ls)(rs)(True)(False)(False))(False)))))))));
export const le: L<<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => L<(scmp: L<(l: S) => L<(r: S) => Bool>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Bool>>>> export const le: L<<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => L<(scmp: L<(l: S) => L<(r: S) => Bool>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Bool>>>>
= _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => = _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) =>
_((scmp: L<(l: S) => L<(r: S) => Ord>>) => _((scmp: L<(l: S) => L<(r: S) => Ord>>) =>
_((l: Pair<F, S>) => uncurry(_((lf: F) => _((ls: S) =>
_((r: Pair<F, S>) => uncurry(_((rf: F) => _((rs: S) =>
fcmp._(fst._(l))._(fst._(r))._(True)._(scmp._(snd._(l))._(snd._(r))._(True)._(True)._(False))._(False))))); fcmp(lf)(rf)(True)(scmp(ls)(rs)(True)(True)(False))(False)))))))));
export const eq: L<<F extends P, S extends P>(feq: L<(l: F) => L<(r: F) => Bool>>) => L<(seq: L<(l: S) => L<(r: S) => Bool>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Bool>>>> export const eq: L<<F extends P, S extends P>(feq: L<(l: F) => L<(r: F) => Bool>>) => L<(seq: L<(l: S) => L<(r: S) => Bool>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Bool>>>>
= _(<F extends P, S extends P>(feq: L<(l: F) => L<(r: F) => Bool>>) => = _(<F extends P, S extends P>(feq: L<(l: F) => L<(r: F) => Bool>>) =>
_((seq: L<(l: S) => L<(r: S) => Bool>>) => _((seq: L<(l: S) => L<(r: S) => Bool>>) =>
_((l: Pair<F, S>) => uncurry(_((lf: F) => _((ls: S) =>
_((r: Pair<F, S>) => uncurry(_((rf: F) => _((rs: S) =>
and._(feq._(fst._(l))._(fst._(r)))._(seq._(snd._(l))._(snd._(r))))))); and(feq(lf)(rf))(seq(ls)(rs))))))))));
export const ge: L<<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => L<(scmp: L<(l: S) => L<(r: S) => Bool>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Bool>>>> export const ge: L<<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => L<(scmp: L<(l: S) => L<(r: S) => Bool>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Bool>>>>
= _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => = _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) =>
_((scmp: L<(l: S) => L<(r: S) => Ord>>) => _((scmp: L<(l: S) => L<(r: S) => Ord>>) =>
_((l: Pair<F, S>) => uncurry(_((lf: F) => _((ls: S) =>
_((r: Pair<F, S>) => uncurry(_((rf: F) => _((rs: S) =>
fcmp._(fst._(l))._(fst._(r))._(False)._(scmp._(snd._(l))._(snd._(r))._(False)._(True)._(True))._(True))))); fcmp(lf)(rf)(False)(scmp(ls)(rs)(False)(True)(True))(True)))))))));
export const gt: L<<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => L<(scmp: L<(l: S) => L<(r: S) => Bool>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Bool>>>> export const gt: L<<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => L<(scmp: L<(l: S) => L<(r: S) => Bool>>) => L<(l: Pair<F, S>) => L<(r: Pair<F, S>) => Bool>>>>
= _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) => = _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) =>
_((scmp: L<(l: S) => L<(r: S) => Ord>>) => _((scmp: L<(l: S) => L<(r: S) => Ord>>) =>
_((l: Pair<F, S>) => uncurry(_((lf: F) => _((ls: S) =>
_((r: Pair<F, S>) => uncurry(_((rf: F) => _((rs: S) =>
fcmp._(fst._(l))._(fst._(r))._(False)._(scmp._(snd._(l))._(snd._(r))._(False)._(False)._(True))._(True))))); fcmp(lf)(rf)(False)(scmp(ls)(rs)(False)(False)(True))(True)))))))));
export const show: L<<F extends P, S extends P>(fshow: L<(f: F) => String>) => L<(sshow: L<(s: S) => String>) => L<(p: Pair<F, S>) => String>>> export const show: L<<F extends P, S extends P>(fshow: L<(f: F) => String>) => L<(sshow: L<(s: S) => String>) => L<(p: Pair<F, S>) => String>>>
= _(<F extends P>(fshow: L<(f: F) => String>) => = _(<F extends P>(fshow: L<(f: F) => String>) =>
_(<S extends P>(sshow: L<(s: S) => String>) => _(<S extends P>(sshow: L<(s: S) => String>) =>
_((p: Pair<F, S>) => uncurry(_((f: F) => _((s: S) => concat(cons(_s('('))(cons(fshow(f))(cons(_s(', '))(cons(sshow(s))(cons(_s(')'))(Nil)))))))))));
uncurry._(_(f => _(s => concat._(cons._(_s('('))._(cons._(fshow._(f))._(cons._(_s(', '))._(cons._(sshow._(s))._(cons._(_s(')'))._(Nil)))))))))._(p))));

@ -1,37 +1,40 @@
import { toNative as $$, L, _, fromNative as __ } from './core'; import { toNative as $$, L, _, fromNative as __, ___ } from './core';
import { Ord } from './ord'; import { Ord } from './ord';
import { Bool } from './bool'; import { Bool } from './bool';
import { fromNumber as _nn } from './num'; import { fromNumber as _nn } from './num';
import { toChar as $c, Char, fromChar as _c, cmp as cmpc, eq as eqc } from './char'; import { toChar as $c, Char, fromChar as _c, cmp as cmpc, eq as eqc } from './char';
import { Cons, List, Nil, cmp as cmpl, concat, cons, eq as eql, ge as gel, gt as gtl, le as lel, lt as ltl } from './list'; import { Cons, List, Nil, append, cmp as cmpl, concat, cons, eq as eql, ge as gel, gt as gtl, le as lel, lt as ltl } from './list';
export type String = List<Char>; export type String = List<Char>;
export { Nil as Empty, nul as empty, len, Cons, cons, snoc, append, repeat, iterate, get, update, set } from './list'; export { Nil as Empty, nul as empty, len, Cons, cons, snoc, append, repeat, iterate, get, update, set } from './list';
export const cmp: L<(l: String) => L<(r: String) => Ord>> export const cmp: L<(l: String) => L<(r: String) => Ord>>
= cmpl._(cmpc); = cmpl(cmpc);
export const lt: L<(l: String) => L<(r: String) => Bool>> export const lt: L<(l: String) => L<(r: String) => Bool>>
= ltl._(cmpc); = ltl(cmpc);
export const le: L<(l: String) => L<(r: String) => Bool>> export const le: L<(l: String) => L<(r: String) => Bool>>
= lel._(cmpc); = lel(cmpc);
export const eq: L<(l: String) => L<(r: String) => Bool>> export const eq: L<(l: String) => L<(r: String) => Bool>>
= eql._(eqc); = eql(eqc);
export const ge: L<(l: String) => L<(r: String) => Bool>> export const ge: L<(l: String) => L<(r: String) => Bool>>
= gel._(cmpc); = gel(cmpc);
export const gt: L<(l: String) => L<(r: String) => Bool>> export const gt: L<(l: String) => L<(r: String) => Bool>>
= gtl._(cmpc); = gtl(cmpc);
export const show: L<(s: String) => String> export const wrap: L<(w: String) => L<(c: String) => String>>
= _(s => concat._(cons._(fromString('"'))._(cons._(s)._(cons._(fromString('"'))._(Nil))))); = _(w => _(c => append(w)(append(c)(w))));
export const fromString: (xs: string) => String export const fromString: (xs: string) => String
= xs => xs.length === 0 ? Nil : Cons._(_c(xs[0]))._(new L(() => fromString(xs.slice(1)).value)); = xs => xs.length === 0 ? Nil : Cons(_c(xs[0]))(___(() => fromString(xs.slice(1)).run()));
export const toString: (xs: String) => string export const toString: (xs: String) => string
= xs => $$(xs._(__(''))._(_(x => _(xs => __($c(x) + toString(xs)))))); = xs => $$(xs(__(''))(_(x => _(xs => __($c(x) + toString(xs))))));
export const show: L<(s: String) => String>
= wrap(fromString('"'));

@ -7,41 +7,41 @@ import { run } from '../src/bf';
describe('BF', () => { describe('BF', () => {
describe('run', () => { describe('run', () => {
it('handles output command', () => { it('handles output command', () => {
expect($s(run._(_s('.'))._(_s('')))).toBe(String.fromCharCode(0)); expect($s(run(_s('.'))(_s('')))).toBe(String.fromCharCode(0));
}); });
it('handles input command', () => { it('handles input command', () => {
expect($s(run._(_s(',.'))._(_s('a')))).toBe('a'); expect($s(run(_s(',.'))(_s('a')))).toBe('a');
}); });
it('handles inc command', () => { it('handles inc command', () => {
expect($s(run._(_s('+.'))._(_s('')))).toBe(String.fromCharCode(1)); expect($s(run(_s('+.'))(_s('')))).toBe(String.fromCharCode(1));
}); });
it('handles dec command', () => { it('handles dec command', () => {
expect($s(run._(_s('-.'))._(_s('')))).toBe(String.fromCharCode(255)); expect($s(run(_s('-.'))(_s('')))).toBe(String.fromCharCode(255));
}); });
it('handles next command', () => { it('handles next command', () => {
expect($s(run._(_s('+++++>++.'))._(_s('')))).toBe(String.fromCharCode(2)); expect($s(run(_s('+++++>++.'))(_s('')))).toBe(String.fromCharCode(2));
}); });
it('handles prev command', () => { it('handles prev command', () => {
expect($s(run._(_s('+++++>++<+++++.'))._(_s('')))).toBe(String.fromCharCode(10)); expect($s(run(_s('+++++>++<+++++.'))(_s('')))).toBe(String.fromCharCode(10));
}); });
it('skips loop block on zero', () => { it('skips loop block on zero', () => {
expect($s(run._(_s('[+++++].'))._(_s('')))).toBe(String.fromCharCode(0)); expect($s(run(_s('[+++++].'))(_s('')))).toBe(String.fromCharCode(0));
}); });
it('repeats loop block while not zero', () => { it('repeats loop block while not zero', () => {
expect($s(run._(_s('+++++[-].'))._(_s('')))).toBe(String.fromCharCode(0)); expect($s(run(_s('+++++[-].'))(_s('')))).toBe(String.fromCharCode(0));
}); });
it('prints "Hello World!"', () => { it('prints "Hello World!"', () => {
expect($s(run expect($s(run
._(_s('++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.')) (_s('++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.'))
._(_s('')))) (_s(''))))
.toBe('Hello World!\n'); .toBe('Hello World!\n');
}); });
}); });

@ -27,222 +27,222 @@ describe('Bool', () => {
describe('iif', () => { describe('iif', () => {
it('returns true argument', () => { it('returns true argument', () => {
expect($b(iif._(True)._(True)._(False))).toBe(true); expect($b(iif(True)(True)(False))).toBe(true);
}); });
it('returns false argument', () => { it('returns false argument', () => {
expect($b(iif._(False)._(True)._(False))).toBe(false); expect($b(iif(False)(True)(False))).toBe(false);
}); });
it('ignores other argument', () => { it('ignores other argument', () => {
expect($b(iif._(True)._(True)._(undef))).toBe(true); expect($b(iif(True)(True)(undef))).toBe(true);
expect($b(iif._(False)._(undef)._(False))).toBe(false); expect($b(iif(False)(undef)(False))).toBe(false);
}); });
}); });
describe('not', () => { describe('not', () => {
it('not False is True', () => { it('not False is True', () => {
expect($b(not._(False))).toBe(true); expect($b(not(False))).toBe(true);
}); });
it('not True is False', () => { it('not True is False', () => {
expect($b(not._(True))).toBe(false); expect($b(not(True))).toBe(false);
}); });
}); });
describe('lt', () => { describe('lt', () => {
it('False lt False is False', () => { it('False lt False is False', () => {
expect($b(lt._(False)._(False))).toBe(false); expect($b(lt(False)(False))).toBe(false);
}); });
it('False lt True is True', () => { it('False lt True is True', () => {
expect($b(lt._(False)._(True))).toBe(true); expect($b(lt(False)(True))).toBe(true);
}); });
it('True lt False is False', () => { it('True lt False is False', () => {
expect($b(lt._(True)._(False))).toBe(false); expect($b(lt(True)(False))).toBe(false);
}); });
it('True lt True is False', () => { it('True lt True is False', () => {
expect($b(lt._(True)._(True))).toBe(false); expect($b(lt(True)(True))).toBe(false);
}); });
it('True lt ignores second argument', () => { it('True lt ignores second argument', () => {
expect($b(lt._(True)._(undef))).toBe(false); expect($b(lt(True)(undef))).toBe(false);
}); });
}); });
describe('le', () => { describe('le', () => {
it('False le False is True', () => { it('False le False is True', () => {
expect($b(le._(False)._(False))).toBe(true); expect($b(le(False)(False))).toBe(true);
}); });
it('False le True is True', () => { it('False le True is True', () => {
expect($b(le._(False)._(True))).toBe(true); expect($b(le(False)(True))).toBe(true);
}); });
it('True le False is False', () => { it('True le False is False', () => {
expect($b(le._(True)._(False))).toBe(false); expect($b(le(True)(False))).toBe(false);
}); });
it('True le True is True', () => { it('True le True is True', () => {
expect($b(le._(True)._(True))).toBe(true); expect($b(le(True)(True))).toBe(true);
}); });
it('False le ignores second argument', () => { it('False le ignores second argument', () => {
expect($b(le._(False)._(undef))).toBe(true); expect($b(le(False)(undef))).toBe(true);
}); });
}); });
describe('eq', () => { describe('eq', () => {
it('False eq False is True', () => { it('False eq False is True', () => {
expect($b(eq._(False)._(False))).toBe(true); expect($b(eq(False)(False))).toBe(true);
}); });
it('False eq True is False', () => { it('False eq True is False', () => {
expect($b(eq._(False)._(True))).toBe(false); expect($b(eq(False)(True))).toBe(false);
}); });
it('True eq False is False', () => { it('True eq False is False', () => {
expect($b(eq._(True)._(False))).toBe(false); expect($b(eq(True)(False))).toBe(false);
}); });
it('True eq True is True', () => { it('True eq True is True', () => {
expect($b(eq._(True)._(True))).toBe(true); expect($b(eq(True)(True))).toBe(true);
}); });
}); });
describe('ge', () => { describe('ge', () => {
it('False ge False is True', () => { it('False ge False is True', () => {
expect($b(ge._(False)._(False))).toBe(true); expect($b(ge(False)(False))).toBe(true);
}); });
it('False ge True is False', () => { it('False ge True is False', () => {
expect($b(ge._(False)._(True))).toBe(false); expect($b(ge(False)(True))).toBe(false);
}); });
it('True ge False is True', () => { it('True ge False is True', () => {
expect($b(ge._(True)._(False))).toBe(true); expect($b(ge(True)(False))).toBe(true);
}); });
it('True ge True is True', () => { it('True ge True is True', () => {
expect($b(ge._(True)._(True))).toBe(true); expect($b(ge(True)(True))).toBe(true);
}); });
it('True ge ignores second argument', () => { it('True ge ignores second argument', () => {
expect($b(ge._(True)._(undef))).toBe(true); expect($b(ge(True)(undef))).toBe(true);
}); });
}); });
describe('gt', () => { describe('gt', () => {
it('False gt False is False', () => { it('False gt False is False', () => {
expect($b(gt._(False)._(False))).toBe(false); expect($b(gt(False)(False))).toBe(false);
}); });
it('False gt True is False', () => { it('False gt True is False', () => {
expect($b(gt._(False)._(True))).toBe(false); expect($b(gt(False)(True))).toBe(false);
}); });
it('True gt False is True', () => { it('True gt False is True', () => {
expect($b(gt._(True)._(False))).toBe(true); expect($b(gt(True)(False))).toBe(true);
}); });
it('True gt True is False', () => { it('True gt True is False', () => {
expect($b(gt._(True)._(True))).toBe(false); expect($b(gt(True)(True))).toBe(false);
}); });
it('False gt ignores second argument', () => { it('False gt ignores second argument', () => {
expect($b(gt._(False)._(undef))).toBe(false); expect($b(gt(False)(undef))).toBe(false);
}); });
}); });
describe('cmp', () => { describe('cmp', () => {
it('False cmp False is EQ', () => { it('False cmp False is EQ', () => {
expect($o(cmp._(False)._(False))).toBe(NOrd.EQ); expect($o(cmp(False)(False))).toBe(NOrd.EQ);
}); });
it('False cmp True is LT', () => { it('False cmp True is LT', () => {
expect($o(cmp._(False)._(True))).toBe(NOrd.LT); expect($o(cmp(False)(True))).toBe(NOrd.LT);
}); });
it('True cmp False is GT', () => { it('True cmp False is GT', () => {
expect($o(cmp._(True)._(False))).toBe(NOrd.GT); expect($o(cmp(True)(False))).toBe(NOrd.GT);
}); });
it('True cmp True is EQ', () => { it('True cmp True is EQ', () => {
expect($o(cmp._(True)._(True))).toBe(NOrd.EQ); expect($o(cmp(True)(True))).toBe(NOrd.EQ);
}); });
}); });
describe('and', () => { describe('and', () => {
it('False and False is False', () => { it('False and False is False', () => {
expect($b(and._(False)._(False))).toBe(false); expect($b(and(False)(False))).toBe(false);
}); });
it('False and True is False', () => { it('False and True is False', () => {
expect($b(and._(False)._(True))).toBe(false); expect($b(and(False)(True))).toBe(false);
}); });
it('True and False is False', () => { it('True and False is False', () => {
expect($b(and._(True)._(False))).toBe(false); expect($b(and(True)(False))).toBe(false);
}); });
it('True and True is True', () => { it('True and True is True', () => {
expect($b(and._(True)._(True))).toBe(true); expect($b(and(True)(True))).toBe(true);
}); });
it('False and ignores other argument', () => { it('False and ignores other argument', () => {
expect($b(and._(False)._(undef))).toBe(false); expect($b(and(False)(undef))).toBe(false);
}); });
}); });
describe('or', () => { describe('or', () => {
it('False or False is False', () => { it('False or False is False', () => {
expect($b(or._(False)._(False))).toBe(false); expect($b(or(False)(False))).toBe(false);
}); });
it('False or True is True', () => { it('False or True is True', () => {
expect($b(or._(False)._(True))).toBe(true); expect($b(or(False)(True))).toBe(true);
}); });
it('True or False is True', () => { it('True or False is True', () => {
expect($b(or._(True)._(False))).toBe(true); expect($b(or(True)(False))).toBe(true);
}); });
it('True or True is True', () => { it('True or True is True', () => {
expect($b(or._(True)._(True))).toBe(true); expect($b(or(True)(True))).toBe(true);
}); });
it('True or ignores other argument', () => { it('True or ignores other argument', () => {
expect($b(or._(True)._(undef))).toBe(true); expect($b(or(True)(undef))).toBe(true);
}); });
}); });
describe('xor', () => { describe('xor', () => {
it('False xor False is False', () => { it('False xor False is False', () => {
expect($b(xor._(False)._(False))).toBe(false); expect($b(xor(False)(False))).toBe(false);
}); });
it('False xor True is True', () => { it('False xor True is True', () => {
expect($b(xor._(False)._(True))).toBe(true); expect($b(xor(False)(True))).toBe(true);
}); });
it('True xor False is True', () => { it('True xor False is True', () => {
expect($b(xor._(True)._(False))).toBe(true); expect($b(xor(True)(False))).toBe(true);
}); });
it('True xor True is False', () => { it('True xor True is False', () => {
expect($b(xor._(True)._(True))).toBe(false); expect($b(xor(True)(True))).toBe(false);
}); });
}); });
describe('show', () => { describe('show', () => {
it('show False is "False"', () => { it('show False is "False"', () => {
expect($s(show._(False))).toBe('False'); expect($s(show(False))).toBe('False');
}); });
it('show True is "True"', () => { it('show True is "True"', () => {
expect($s(show._(True))).toBe('True'); expect($s(show(True))).toBe('True');
}); });
}); });
}); });

@ -12,11 +12,11 @@ describe('Byte', () => {
}); });
it('converts 1', () => { it('converts 1', () => {
expect($n(Inc._(x00))).toBe(1); expect($n(Inc(x00))).toBe(1);
}); });
it('converts 2', () => { it('converts 2', () => {
expect($n(Inc._(Inc._(x00)))).toBe(2); expect($n(Inc(Inc(x00)))).toBe(2);
}); });
}); });
@ -40,436 +40,436 @@ describe('Byte', () => {
describe('ifz', () => { describe('ifz', () => {
it('returns zero branch', () => { it('returns zero branch', () => {
expect($b(ifz._(_n(0))._(_b(true))._(_b(false)))).toBe(true); expect($b(ifz(_n(0))(_b(true))(_b(false)))).toBe(true);
}); });
it('returns non-zero branch', () => { it('returns non-zero branch', () => {
expect($b(ifz._(_n(1))._(_b(true))._(_b(false)))).toBe(false); expect($b(ifz(_n(1))(_b(true))(_b(false)))).toBe(false);
}); });
it('returns non-zero branch', () => { it('returns non-zero branch', () => {
expect($b(ifz._(_n(10))._(_b(true))._(_b(false)))).toBe(false); expect($b(ifz(_n(10))(_b(true))(_b(false)))).toBe(false);
}); });
it('skips other branch', () => { it('skips other branch', () => {
expect($b(ifz._(_n(0))._(_b(true))._(undef))).toBe(true); expect($b(ifz(_n(0))(_b(true))(undef))).toBe(true);
expect($b(ifz._(_n(1))._(undef)._(_b(false)))).toBe(false); expect($b(ifz(_n(1))(undef)(_b(false)))).toBe(false);
}); });
}); });
describe('inc', () => { describe('inc', () => {
it('inc 0 is 1', () => { it('inc 0 is 1', () => {
expect($n(inc._(_n(0)))).toBe(1); expect($n(inc(_n(0)))).toBe(1);
}); });
it('inc 1 is 2', () => { it('inc 1 is 2', () => {
expect($n(inc._(_n(1)))).toBe(2); expect($n(inc(_n(1)))).toBe(2);
}); });
it('inc 10 is 11', () => { it('inc 10 is 11', () => {
expect($n(inc._(_n(10)))).toBe(11); expect($n(inc(_n(10)))).toBe(11);
}); });
it('inc 255 is 0', () => { it('inc 255 is 0', () => {
expect($n(inc._(_n(255)))).toBe(0); expect($n(inc(_n(255)))).toBe(0);
}); });
}); });
describe('dec', () => { describe('dec', () => {
it('dec 0 is 255', () => { it('dec 0 is 255', () => {
expect($n(dec._(_n(0)))).toBe(255); expect($n(dec(_n(0)))).toBe(255);
}); });
it('dec 1 is 0', () => { it('dec 1 is 0', () => {
expect($n(dec._(_n(1)))).toBe(0); expect($n(dec(_n(1)))).toBe(0);
}); });
it('dec 10 is 9', () => { it('dec 10 is 9', () => {
expect($n(dec._(_n(10)))).toBe(9); expect($n(dec(_n(10)))).toBe(9);
}); });
it('dec 255 is 254', () => { it('dec 255 is 254', () => {
expect($n(dec._(_n(255)))).toBe(254); expect($n(dec(_n(255)))).toBe(254);
}); });
}); });
describe('cmp', () => { describe('cmp', () => {
it('0 cmp 0 is EQ', () => { it('0 cmp 0 is EQ', () => {
expect($o(cmp._(_n(0))._(_n(0)))).toBe(NOrd.EQ); expect($o(cmp(_n(0))(_n(0)))).toBe(NOrd.EQ);
}); });
it('0 cmp 1 is LT', () => { it('0 cmp 1 is LT', () => {
expect($o(cmp._(_n(0))._(_n(1)))).toBe(NOrd.LT); expect($o(cmp(_n(0))(_n(1)))).toBe(NOrd.LT);
}); });
it('1 cmp 0 is GT', () => { it('1 cmp 0 is GT', () => {
expect($o(cmp._(_n(1))._(_n(0)))).toBe(NOrd.GT); expect($o(cmp(_n(1))(_n(0)))).toBe(NOrd.GT);
}); });
it('3 cmp 3 is EQ', () => { it('3 cmp 3 is EQ', () => {
expect($o(cmp._(_n(3))._(_n(3)))).toBe(NOrd.EQ); expect($o(cmp(_n(3))(_n(3)))).toBe(NOrd.EQ);
}); });
it('3 cmp 7 is LT', () => { it('3 cmp 7 is LT', () => {
expect($o(cmp._(_n(3))._(_n(7)))).toBe(NOrd.LT); expect($o(cmp(_n(3))(_n(7)))).toBe(NOrd.LT);
}); });
it('7 cmp 3 is GT', () => { it('7 cmp 3 is GT', () => {
expect($o(cmp._(_n(7))._(_n(3)))).toBe(NOrd.GT); expect($o(cmp(_n(7))(_n(3)))).toBe(NOrd.GT);
}); });
it('0 cmp 255 is LT', () => { it('0 cmp 255 is LT', () => {
expect($o(cmp._(_n(0))._(_n(255)))).toBe(NOrd.LT); expect($o(cmp(_n(0))(_n(255)))).toBe(NOrd.LT);
}); });
it('255 cmp 0 is GT', () => { it('255 cmp 0 is GT', () => {
expect($o(cmp._(_n(255))._(_n(0)))).toBe(NOrd.GT); expect($o(cmp(_n(255))(_n(0)))).toBe(NOrd.GT);
}); });
it('255 cmp 255 is EQ', () => { it('255 cmp 255 is EQ', () => {
expect($o(cmp._(_n(255))._(_n(255)))).toBe(NOrd.EQ); expect($o(cmp(_n(255))(_n(255)))).toBe(NOrd.EQ);
}); });
}); });
describe('lt', () => { describe('lt', () => {
it('0 lt 0 is False', () => { it('0 lt 0 is False', () => {
expect($b(lt._(_n(0))._(_n(0)))).toBe(false); expect($b(lt(_n(0))(_n(0)))).toBe(false);
}); });
it('0 lt 1 is True', () => { it('0 lt 1 is True', () => {
expect($b(lt._(_n(0))._(_n(1)))).toBe(true); expect($b(lt(_n(0))(_n(1)))).toBe(true);
}); });
it('1 lt 0 is False', () => { it('1 lt 0 is False', () => {
expect($b(lt._(_n(1))._(_n(0)))).toBe(false); expect($b(lt(_n(1))(_n(0)))).toBe(false);
}); });
it('3 lt 3 is False', () => { it('3 lt 3 is False', () => {
expect($b(lt._(_n(3))._(_n(3)))).toBe(false); expect($b(lt(_n(3))(_n(3)))).toBe(false);
}); });
it('3 lt 7 is True', () => { it('3 lt 7 is True', () => {
expect($b(lt._(_n(3))._(_n(7)))).toBe(true); expect($b(lt(_n(3))(_n(7)))).toBe(true);
}); });
it('7 lt 3 is False', () => { it('7 lt 3 is False', () => {
expect($b(lt._(_n(7))._(_n(3)))).toBe(false); expect($b(lt(_n(7))(_n(3)))).toBe(false);
}); });
it('0 lt 255 is True', () => { it('0 lt 255 is True', () => {
expect($b(lt._(_n(0))._(_n(255)))).toBe(true); expect($b(lt(_n(0))(_n(255)))).toBe(true);
}); });
it('255 lt 0 is False', () => { it('255 lt 0 is False', () => {
expect($b(lt._(_n(255))._(_n(0)))).toBe(false); expect($b(lt(_n(255))(_n(0)))).toBe(false);
}); });
it('255 lt 255 is False', () => { it('255 lt 255 is False', () => {
expect($b(lt._(_n(255))._(_n(255)))).toBe(false); expect($b(lt(_n(255))(_n(255)))).toBe(false);
}); });
}); });
describe('le', () => { describe('le', () => {
it('0 le 0 is True', () => { it('0 le 0 is True', () => {
expect($b(le._(_n(0))._(_n(0)))).toBe(true); expect($b(le(_n(0))(_n(0)))).toBe(true);
}); });
it('0 le 1 is True', () => { it('0 le 1 is True', () => {
expect($b(le._(_n(0))._(_n(1)))).toBe(true); expect($b(le(_n(0))(_n(1)))).toBe(true);
}); });
it('1 le 0 is False', () => { it('1 le 0 is False', () => {
expect($b(le._(_n(1))._(_n(0)))).toBe(false); expect($b(le(_n(1))(_n(0)))).toBe(false);
}); });
it('3 le 3 is True', () => { it('3 le 3 is True', () => {
expect($b(le._(_n(3))._(_n(3)))).toBe(true); expect($b(le(_n(3))(_n(3)))).toBe(true);
}); });
it('3 le 7 is True', () => { it('3 le 7 is True', () => {
expect($b(le._(_n(3))._(_n(7)))).toBe(true); expect($b(le(_n(3))(_n(7)))).toBe(true);
}); });
it('7 le 3 is False', () => { it('7 le 3 is False', () => {
expect($b(le._(_n(7))._(_n(3)))).toBe(false); expect($b(le(_n(7))(_n(3)))).toBe(false);
}); });
it('0 le 255 is True', () => { it('0 le 255 is True', () => {
expect($b(le._(_n(0))._(_n(255)))).toBe(true); expect($b(le(_n(0))(_n(255)))).toBe(true);
}); });
it('255 le 0 is False', () => { it('255 le 0 is False', () => {
expect($b(le._(_n(255))._(_n(0)))).toBe(false); expect($b(le(_n(255))(_n(0)))).toBe(false);
}); });
it('255 le 255 is True', () => { it('255 le 255 is True', () => {
expect($b(le._(_n(255))._(_n(255)))).toBe(true); expect($b(le(_n(255))(_n(255)))).toBe(true);
}); });
it('0 le skips second argument', () => { it('0 le skips second argument', () => {
expect($b(le._(_n(0))._(undef))).toBe(true); expect($b(le(_n(0))(undef))).toBe(true);
}); });
}); });
describe('eq', () => { describe('eq', () => {
it('0 eq 0 is True', () => { it('0 eq 0 is True', () => {
expect($b(eq._(_n(0))._(_n(0)))).toBe(true); expect($b(eq(_n(0))(_n(0)))).toBe(true);
}); });
it('0 eq 1 is False', () => { it('0 eq 1 is False', () => {
expect($b(eq._(_n(0))._(_n(1)))).toBe(false); expect($b(eq(_n(0))(_n(1)))).toBe(false);
}); });
it('1 eq 0 is False', () => { it('1 eq 0 is False', () => {
expect($b(eq._(_n(1))._(_n(0)))).toBe(false); expect($b(eq(_n(1))(_n(0)))).toBe(false);
}); });
it('3 eq 3 is True', () => { it('3 eq 3 is True', () => {
expect($b(eq._(_n(3))._(_n(3)))).toBe(true); expect($b(eq(_n(3))(_n(3)))).toBe(true);
}); });
it('3 eq 7 is False', () => { it('3 eq 7 is False', () => {
expect($b(eq._(_n(3))._(_n(7)))).toBe(false); expect($b(eq(_n(3))(_n(7)))).toBe(false);
}); });
it('7 eq 3 is False', () => { it('7 eq 3 is False', () => {
expect($b(eq._(_n(7))._(_n(3)))).toBe(false); expect($b(eq(_n(7))(_n(3)))).toBe(false);
}); });
it('0 eq 255 is False', () => { it('0 eq 255 is False', () => {
expect($b(eq._(_n(0))._(_n(255)))).toBe(false); expect($b(eq(_n(0))(_n(255)))).toBe(false);
}); });
it('255 eq 0 is False', () => { it('255 eq 0 is False', () => {
expect($b(eq._(_n(255))._(_n(0)))).toBe(false); expect($b(eq(_n(255))(_n(0)))).toBe(false);
}); });
it('255 eq 255 is True', () => { it('255 eq 255 is True', () => {
expect($b(eq._(_n(255))._(_n(255)))).toBe(true); expect($b(eq(_n(255))(_n(255)))).toBe(true);
}); });
}); });
describe('ge', () => { describe('ge', () => {
it('0 ge 0 is True', () => { it('0 ge 0 is True', () => {
expect($b(ge._(_n(0))._(_n(0)))).toBe(true); expect($b(ge(_n(0))(_n(0)))).toBe(true);
}); });
it('0 ge 1 is False', () => { it('0 ge 1 is False', () => {
expect($b(ge._(_n(0))._(_n(1)))).toBe(false); expect($b(ge(_n(0))(_n(1)))).toBe(false);
}); });
it('1 ge 0 is True', () => { it('1 ge 0 is True', () => {
expect($b(ge._(_n(1))._(_n(0)))).toBe(true); expect($b(ge(_n(1))(_n(0)))).toBe(true);
}); });
it('3 ge 3 is True', () => { it('3 ge 3 is True', () => {
expect($b(ge._(_n(3))._(_n(3)))).toBe(true); expect($b(ge(_n(3))(_n(3)))).toBe(true);
}); });
it('3 ge 7 is False', () => { it('3 ge 7 is False', () => {
expect($b(ge._(_n(3))._(_n(7)))).toBe(false); expect($b(ge(_n(3))(_n(7)))).toBe(false);
}); });
it('7 ge 3 is True', () => { it('7 ge 3 is True', () => {
expect($b(ge._(_n(7))._(_n(3)))).toBe(true); expect($b(ge(_n(7))(_n(3)))).toBe(true);
}); });
it('0 ge 255 is False', () => { it('0 ge 255 is False', () => {
expect($b(ge._(_n(0))._(_n(255)))).toBe(false); expect($b(ge(_n(0))(_n(255)))).toBe(false);
}); });
it('255 ge 0 is True', () => { it('255 ge 0 is True', () => {
expect($b(ge._(_n(255))._(_n(0)))).toBe(true); expect($b(ge(_n(255))(_n(0)))).toBe(true);
}); });
it('255 ge 255 is True', () => { it('255 ge 255 is True', () => {
expect($b(ge._(_n(255))._(_n(255)))).toBe(true); expect($b(ge(_n(255))(_n(255)))).toBe(true);
}); });
it('ge 0 skips first argument', () => { it('ge 0 skips first argument', () => {
expect($b(ge._(undef)._(_n(0)))).toBe(true); expect($b(ge(undef)(_n(0)))).toBe(true);
}); });
}); });
describe('gt', () => { describe('gt', () => {
it('0 gt 0 is False', () => { it('0 gt 0 is False', () => {
expect($b(gt._(_n(0))._(_n(0)))).toBe(false); expect($b(gt(_n(0))(_n(0)))).toBe(false);
}); });
it('0 gt 1 is False', () => { it('0 gt 1 is False', () => {
expect($b(gt._(_n(0))._(_n(1)))).toBe(false); expect($b(gt(_n(0))(_n(1)))).toBe(false);
}); });
it('1 gt 0 is True', () => { it('1 gt 0 is True', () => {
expect($b(gt._(_n(1))._(_n(0)))).toBe(true); expect($b(gt(_n(1))(_n(0)))).toBe(true);
}); });
it('3 gt 3 is False', () => { it('3 gt 3 is False', () => {
expect($b(gt._(_n(3))._(_n(3)))).toBe(false); expect($b(gt(_n(3))(_n(3)))).toBe(false);
}); });
it('3 gt 7 is False', () => { it('3 gt 7 is False', () => {
expect($b(gt._(_n(3))._(_n(7)))).toBe(false); expect($b(gt(_n(3))(_n(7)))).toBe(false);
}); });
it('7 gt 3 is True', () => { it('7 gt 3 is True', () => {
expect($b(gt._(_n(7))._(_n(3)))).toBe(true); expect($b(gt(_n(7))(_n(3)))).toBe(true);
}); });
it('0 gt 255 is False', () => { it('0 gt 255 is False', () => {
expect($b(gt._(_n(0))._(_n(255)))).toBe(false); expect($b(gt(_n(0))(_n(255)))).toBe(false);
}); });
it('255 gt 0 is True', () => { it('255 gt 0 is True', () => {
expect($b(gt._(_n(255))._(_n(0)))).toBe(true); expect($b(gt(_n(255))(_n(0)))).toBe(true);
}); });
it('255 gt 255 is False', () => { it('255 gt 255 is False', () => {
expect($b(gt._(_n(255))._(_n(255)))).toBe(false); expect($b(gt(_n(255))(_n(255)))).toBe(false);
}); });
}); });
describe('sum', () => { describe('sum', () => {
it('0 sum 0 is 0', () => { it('0 sum 0 is 0', () => {
expect($n(sum._(_n(0))._(_n(0)))).toBe(0); expect($n(sum(_n(0))(_n(0)))).toBe(0);
}); });
it('0 sum 1 is 1', () => { it('0 sum 1 is 1', () => {
expect($n(sum._(_n(0))._(_n(1)))).toBe(1); expect($n(sum(_n(0))(_n(1)))).toBe(1);
}); });
it('1 sum 0 is 1', () => { it('1 sum 0 is 1', () => {
expect($n(sum._(_n(1))._(_n(0)))).toBe(1); expect($n(sum(_n(1))(_n(0)))).toBe(1);
}); });
it('3 sum 4 is 7', () => { it('3 sum 4 is 7', () => {
expect($n(sum._(_n(3))._(_n(4)))).toBe(7); expect($n(sum(_n(3))(_n(4)))).toBe(7);
}); });
it('200 sum 200 is 144', () => { it('200 sum 200 is 144', () => {
expect($n(sum._(_n(200))._(_n(200)))).toBe(144); expect($n(sum(_n(200))(_n(200)))).toBe(144);
}); });
}); });
describe('sub', () => { describe('sub', () => {
it('0 sub 0 is 0', () => { it('0 sub 0 is 0', () => {
expect($n(sub._(_n(0))._(_n(0)))).toBe(0); expect($n(sub(_n(0))(_n(0)))).toBe(0);
}); });
it('0 sub 1 is 255', () => { it('0 sub 1 is 255', () => {
expect($n(sub._(_n(0))._(_n(1)))).toBe(255); expect($n(sub(_n(0))(_n(1)))).toBe(255);
}); });
it('1 sub 0 is 1', () => { it('1 sub 0 is 1', () => {
expect($n(sub._(_n(1))._(_n(0)))).toBe(1); expect($n(sub(_n(1))(_n(0)))).toBe(1);
}); });
it('7 sub 4 is 3', () => { it('7 sub 4 is 3', () => {
expect($n(sub._(_n(7))._(_n(4)))).toBe(3); expect($n(sub(_n(7))(_n(4)))).toBe(3);
}); });
it('4 sub 7 is 253', () => { it('4 sub 7 is 253', () => {
expect($n(sub._(_n(4))._(_n(7)))).toBe(253); expect($n(sub(_n(4))(_n(7)))).toBe(253);
}); });
}); });
describe('mul', () => { describe('mul', () => {
it('0 mul 0 is 0', () => { it('0 mul 0 is 0', () => {
expect($n(mul._(_n(0))._(_n(0)))).toBe(0); expect($n(mul(_n(0))(_n(0)))).toBe(0);
}); });
it('0 mul 10 is 0', () => { it('0 mul 10 is 0', () => {
expect($n(mul._(_n(0))._(_n(10)))).toBe(0); expect($n(mul(_n(0))(_n(10)))).toBe(0);
}); });
it('10 mul 0 is 0', () => { it('10 mul 0 is 0', () => {
expect($n(mul._(_n(1))._(_n(0)))).toBe(0); expect($n(mul(_n(1))(_n(0)))).toBe(0);
}); });
it('1 mul 10 is 10', () => { it('1 mul 10 is 10', () => {
expect($n(mul._(_n(1))._(_n(10)))).toBe(10); expect($n(mul(_n(1))(_n(10)))).toBe(10);
}); });
it('10 mul 1 is 10', () => { it('10 mul 1 is 10', () => {
expect($n(mul._(_n(10))._(_n(1)))).toBe(10); expect($n(mul(_n(10))(_n(1)))).toBe(10);
}); });
it('3 mul 4 is 12', () => { it('3 mul 4 is 12', () => {
expect($n(mul._(_n(3))._(_n(4)))).toBe(12); expect($n(mul(_n(3))(_n(4)))).toBe(12);
}); });
it('100 mul 100 is 12', () => { it('100 mul 100 is 12', () => {
expect($n(mul._(_n(3))._(_n(4)))).toBe(12); expect($n(mul(_n(3))(_n(4)))).toBe(12);
}); });
it('0 mul ignores second argument', () => { it('0 mul ignores second argument', () => {
expect($n(mul._(_n(0))._(undef))).toBe(0); expect($n(mul(_n(0))(undef))).toBe(0);
}); });
}); });
describe('div', () => { describe('div', () => {
it('0 div 10 is 0', () => { it('0 div 10 is 0', () => {
expect($n(div._(_n(0))._(_n(10)))).toBe(0); expect($n(div(_n(0))(_n(10)))).toBe(0);
}); });
it('1 div 10 is 0', () => { it('1 div 10 is 0', () => {
expect($n(div._(_n(1))._(_n(10)))).toBe(0); expect($n(div(_n(1))(_n(10)))).toBe(0);
}); });
it('10 div 1 is 10', () => { it('10 div 1 is 10', () => {
expect($n(div._(_n(10))._(_n(1)))).toBe(10); expect($n(div(_n(10))(_n(1)))).toBe(10);
}); });
it('10 div 5 is 2', () => { it('10 div 5 is 2', () => {
expect($n(div._(_n(10))._(_n(5)))).toBe(2); expect($n(div(_n(10))(_n(5)))).toBe(2);
}); });
it('10 div 3 is 3', () => { it('10 div 3 is 3', () => {
expect($n(div._(_n(10))._(_n(3)))).toBe(3); expect($n(div(_n(10))(_n(3)))).toBe(3);
}); });
it.failing('0 div ignores second argument', () => { it.failing('0 div ignores second argument', () => {
expect($n(div._(_n(0))._(undef))).toBe(0); expect($n(div(_n(0))(undef))).toBe(0);
}); });
}); });
describe('mod', () => { describe('mod', () => {
it('0 mod 10 is 0', () => { it('0 mod 10 is 0', () => {
expect($n(mod._(_n(0))._(_n(10)))).toBe(0); expect($n(mod(_n(0))(_n(10)))).toBe(0);
}); });
it('1 mod 10 is 1', () => { it('1 mod 10 is 1', () => {
expect($n(mod._(_n(1))._(_n(10)))).toBe(1); expect($n(mod(_n(1))(_n(10)))).toBe(1);
}); });
it('10 mod 1 is 0', () => { it('10 mod 1 is 0', () => {
expect($n(mod._(_n(10))._(_n(1)))).toBe(0); expect($n(mod(_n(10))(_n(1)))).toBe(0);
}); });
it('10 mod 5 is 0', () => { it('10 mod 5 is 0', () => {
expect($n(mod._(_n(10))._(_n(5)))).toBe(0); expect($n(mod(_n(10))(_n(5)))).toBe(0);
}); });
it('10 mod 3 is 1', () => { it('10 mod 3 is 1', () => {
expect($n(mod._(_n(10))._(_n(3)))).toBe(1); expect($n(mod(_n(10))(_n(3)))).toBe(1);
}); });
it.failing('0 mod ignores second argument', () => { it.failing('0 mod ignores second argument', () => {
expect($n(mod._(_n(0))._(undef))).toBe(0); expect($n(mod(_n(0))(undef))).toBe(0);
}); });
}); });
describe('show', () => { describe('show', () => {
it('show 0 is "0"', () => { it('show 0 is "0"', () => {
expect($s(show._(_n(0)))).toBe('0'); expect($s(show(_n(0)))).toBe('0');
}); });
it('show 1 is "1"', () => { it('show 1 is "1"', () => {
expect($s(show._(_n(1)))).toBe('1'); expect($s(show(_n(1)))).toBe('1');
}); });
it('show 255 is "255"', () => { it('show 255 is "255"', () => {
expect($s(show._(_n(255)))).toBe('255'); expect($s(show(_n(255)))).toBe('255');
}); });
}); });
}); });

@ -44,171 +44,171 @@ describe('Char', () => {
describe('cmp', () => { describe('cmp', () => {
it('"0" cmp "0" is EQ', () => { it('"0" cmp "0" is EQ', () => {
expect($o(cmp._(_c('0'))._(_c('0')))).toBe(NOrd.EQ); expect($o(cmp(_c('0'))(_c('0')))).toBe(NOrd.EQ);
}); });
it('"0" cmp "a" is LT', () => { it('"0" cmp "a" is LT', () => {
expect($o(cmp._(_c('0'))._(_c('a')))).toBe(NOrd.LT); expect($o(cmp(_c('0'))(_c('a')))).toBe(NOrd.LT);
}); });
it('"a" cmp "0" is GT', () => { it('"a" cmp "0" is GT', () => {
expect($o(cmp._(_c('a'))._(_c('0')))).toBe(NOrd.GT); expect($o(cmp(_c('a'))(_c('0')))).toBe(NOrd.GT);
}); });
it('"z" cmp "z" is EQ', () => { it('"z" cmp "z" is EQ', () => {
expect($o(cmp._(_c('z'))._(_c('z')))).toBe(NOrd.EQ); expect($o(cmp(_c('z'))(_c('z')))).toBe(NOrd.EQ);
}); });
it('"z" cmp "-" is GT', () => { it('"z" cmp "-" is GT', () => {
expect($o(cmp._(_c('z'))._(_c('-')))).toBe(NOrd.GT); expect($o(cmp(_c('z'))(_c('-')))).toBe(NOrd.GT);
}); });
it('"-" cmp "z" is LT', () => { it('"-" cmp "z" is LT', () => {
expect($o(cmp._(_c('-'))._(_c('z')))).toBe(NOrd.LT); expect($o(cmp(_c('-'))(_c('z')))).toBe(NOrd.LT);
}); });
}); });
describe('lt', () => { describe('lt', () => {
it('"0" lt "0" is False', () => { it('"0" lt "0" is False', () => {
expect($b(lt._(_c('0'))._(_c('0')))).toBe(false); expect($b(lt(_c('0'))(_c('0')))).toBe(false);
}); });
it('"0" lt "a" is True', () => { it('"0" lt "a" is True', () => {
expect($b(lt._(_c('0'))._(_c('a')))).toBe(true); expect($b(lt(_c('0'))(_c('a')))).toBe(true);
}); });
it('"a" lt "0" is False', () => { it('"a" lt "0" is False', () => {
expect($b(lt._(_c('a'))._(_c('0')))).toBe(false); expect($b(lt(_c('a'))(_c('0')))).toBe(false);
}); });
it('"z" lt "z" is False', () => { it('"z" lt "z" is False', () => {
expect($b(lt._(_c('z'))._(_c('z')))).toBe(false); expect($b(lt(_c('z'))(_c('z')))).toBe(false);
}); });
it('"z" lt "-" is False', () => { it('"z" lt "-" is False', () => {
expect($b(lt._(_c('z'))._(_c('-')))).toBe(false); expect($b(lt(_c('z'))(_c('-')))).toBe(false);
}); });
it('"-" lt "z" is True', () => { it('"-" lt "z" is True', () => {
expect($b(lt._(_c('-'))._(_c('z')))).toBe(true); expect($b(lt(_c('-'))(_c('z')))).toBe(true);
}); });
}); });
describe('le', () => { describe('le', () => {
it('"0" le "0" is True', () => { it('"0" le "0" is True', () => {
expect($b(le._(_c('0'))._(_c('0')))).toBe(true); expect($b(le(_c('0'))(_c('0')))).toBe(true);
}); });
it('"0" le "a" is True', () => { it('"0" le "a" is True', () => {
expect($b(le._(_c('0'))._(_c('a')))).toBe(true); expect($b(le(_c('0'))(_c('a')))).toBe(true);
}); });
it('"a" le "0" is False', () => { it('"a" le "0" is False', () => {
expect($b(le._(_c('a'))._(_c('0')))).toBe(false); expect($b(le(_c('a'))(_c('0')))).toBe(false);
}); });
it('"z" le "z" is True', () => { it('"z" le "z" is True', () => {
expect($b(le._(_c('z'))._(_c('z')))).toBe(true); expect($b(le(_c('z'))(_c('z')))).toBe(true);
}); });
it('"z" le "-" is False', () => { it('"z" le "-" is False', () => {
expect($b(le._(_c('z'))._(_c('-')))).toBe(false); expect($b(le(_c('z'))(_c('-')))).toBe(false);
}); });
it('"-" le "z" is True', () => { it('"-" le "z" is True', () => {
expect($b(le._(_c('-'))._(_c('z')))).toBe(true); expect($b(le(_c('-'))(_c('z')))).toBe(true);
}); });
}); });
describe('eq', () => { describe('eq', () => {
it('"0" eq "0" is True', () => { it('"0" eq "0" is True', () => {
expect($b(eq._(_c('0'))._(_c('0')))).toBe(true); expect($b(eq(_c('0'))(_c('0')))).toBe(true);
}); });
it('"0" eq "a" is False', () => { it('"0" eq "a" is False', () => {
expect($b(eq._(_c('0'))._(_c('a')))).toBe(false); expect($b(eq(_c('0'))(_c('a')))).toBe(false);
}); });
it('"a" eq "0" is False', () => { it('"a" eq "0" is False', () => {
expect($b(eq._(_c('a'))._(_c('0')))).toBe(false); expect($b(eq(_c('a'))(_c('0')))).toBe(false);
}); });
it('"z" eq "z" is True', () => { it('"z" eq "z" is True', () => {
expect($b(eq._(_c('z'))._(_c('z')))).toBe(true); expect($b(eq(_c('z'))(_c('z')))).toBe(true);
}); });
it('"z" eq "-" is False', () => { it('"z" eq "-" is False', () => {
expect($b(eq._(_c('z'))._(_c('-')))).toBe(false); expect($b(eq(_c('z'))(_c('-')))).toBe(false);
}); });
it('"-" eq "z" is False', () => { it('"-" eq "z" is False', () => {
expect($b(eq._(_c('-'))._(_c('z')))).toBe(false); expect($b(eq(_c('-'))(_c('z')))).toBe(false);
}); });
}); });
describe('ge', () => { describe('ge', () => {
it('"0" ge "0" is True', () => { it('"0" ge "0" is True', () => {
expect($b(ge._(_c('0'))._(_c('0')))).toBe(true); expect($b(ge(_c('0'))(_c('0')))).toBe(true);
}); });
it('"0" ge "a" is False', () => { it('"0" ge "a" is False', () => {
expect($b(ge._(_c('0'))._(_c('a')))).toBe(false); expect($b(ge(_c('0'))(_c('a')))).toBe(false);
}); });
it('"a" ge "0" is True', () => { it('"a" ge "0" is True', () => {
expect($b(ge._(_c('a'))._(_c('0')))).toBe(true); expect($b(ge(_c('a'))(_c('0')))).toBe(true);
}); });
it('"z" ge "z" is True', () => { it('"z" ge "z" is True', () => {
expect($b(ge._(_c('z'))._(_c('z')))).toBe(true); expect($b(ge(_c('z'))(_c('z')))).toBe(true);
}); });
it('"z" ge "-" is True', () => { it('"z" ge "-" is True', () => {
expect($b(ge._(_c('z'))._(_c('-')))).toBe(true); expect($b(ge(_c('z'))(_c('-')))).toBe(true);
}); });
it('"-" ge "z" is False', () => { it('"-" ge "z" is False', () => {
expect($b(ge._(_c('-'))._(_c('z')))).toBe(false); expect($b(ge(_c('-'))(_c('z')))).toBe(false);
}); });
}); });
describe('gt', () => { describe('gt', () => {
it('"0" gt "0" is False', () => { it('"0" gt "0" is False', () => {
expect($b(gt._(_c('0'))._(_c('0')))).toBe(false); expect($b(gt(_c('0'))(_c('0')))).toBe(false);
}); });
it('"0" gt "a" is False', () => { it('"0" gt "a" is False', () => {
expect($b(gt._(_c('0'))._(_c('a')))).toBe(false); expect($b(gt(_c('0'))(_c('a')))).toBe(false);
}); });
it('"a" gt "0" is True', () => { it('"a" gt "0" is True', () => {
expect($b(gt._(_c('a'))._(_c('0')))).toBe(true); expect($b(gt(_c('a'))(_c('0')))).toBe(true);
}); });
it('"z" gt "z" is False', () => { it('"z" gt "z" is False', () => {
expect($b(gt._(_c('z'))._(_c('z')))).toBe(false); expect($b(gt(_c('z'))(_c('z')))).toBe(false);
}); });
it('"z" gt "-" is True', () => { it('"z" gt "-" is True', () => {
expect($b(gt._(_c('z'))._(_c('-')))).toBe(true); expect($b(gt(_c('z'))(_c('-')))).toBe(true);
}); });
it('"-" gt "z" is False', () => { it('"-" gt "z" is False', () => {
expect($b(gt._(_c('-'))._(_c('z')))).toBe(false); expect($b(gt(_c('-'))(_c('z')))).toBe(false);
}); });
}); });
describe('show', () => { describe('show', () => {
it('show "0" is "\'0\'"', () => { it('show "0" is "\'0\'"', () => {
expect($s(show._(_c('0')))).toBe('\'0\''); expect($s(show(_c('0')))).toBe('\'0\'');
}); });
it('show "a" is "\'a\'"', () => { it('show "a" is "\'a\'"', () => {
expect($s(show._(_c('a')))).toBe('\'a\''); expect($s(show(_c('a')))).toBe('\'a\'');
}); });
it('show "-" is "\'-\'"', () => { it('show "-" is "\'-\'"', () => {
expect($s(show._(_c('-')))).toBe('\'-\''); expect($s(show(_c('-')))).toBe('\'-\'');
}); });
}); });
}); });

@ -3,16 +3,16 @@ import { toNative as $$, _, fromNative as __, cnst, id, undef } from '../src/cor
describe('id', () => { describe('id', () => {
it('returns first argument', () => { it('returns first argument', () => {
expect($$(id._(__('first')))).toBe('first'); expect($$(id(__('first')))).toBe('first');
}); });
}); });
describe('cnst', () => { describe('cnst', () => {
it('returns first argument after receiving second', () => { it('returns first argument after receiving second', () => {
expect($$(cnst._(__('first'))._(__('second')))).toBe('first'); expect($$(cnst(__('first'))(__('second')))).toBe('first');
}); });
it('ignores second argument', () => { it('ignores second argument', () => {
expect($$(cnst._(__('first'))._(undef))).toBe('first'); expect($$(cnst(__('first'))(undef))).toBe('first');
}); });
}); });

@ -1,5 +1,5 @@
import { describe, expect, it } from '@jest/globals'; import { describe, expect, it } from '@jest/globals';
import { toNative as $$, L, _, fromNative as __, undef } from '../src/core'; import { toNative as $$, L, _, fromNative as __, ___, undef } from '../src/core';
import { toNOrd as $o, NOrd } from '../src/ord'; import { toNOrd as $o, NOrd } from '../src/ord';
import { toBoolean as $b, iif } from '../src/bool'; import { toBoolean as $b, iif } from '../src/bool';
import { toNumber as $n, toNumber as $nn, Num, Succ, Zero, fromNumber as _n, fromNumber as _nn, cmp as cmpn, eq as eqn, even, gt as ngt, show as nshow, odd, succ, sum } from '../src/num'; import { toNumber as $n, toNumber as $nn, Num, Succ, Zero, fromNumber as _n, fromNumber as _nn, cmp as cmpn, eq as eqn, even, gt as ngt, show as nshow, odd, succ, sum } from '../src/num';
@ -8,13 +8,13 @@ import { toArray as $a, Cons, List, Nil, fromArray as _a, all, any, append, cmp,
import { toString as $s } from '../src/string'; import { toString as $s } from '../src/string';
describe('List', () => { describe('List', () => {
const infinite: List<Num> = iterate._(Succ)._(Zero); const infinite: List<Num> = iterate(Succ)(Zero);
const _na: (xs: number[]) => List<Num> const _na: (xs: number[]) => List<Num>
= xs => xs.length === 0 ? Nil : Cons._(_nn(xs[0]))._(new L(() => _na(xs.slice(1)).value)); = xs => xs.length === 0 ? Nil : Cons(_nn(xs[0]))(___(() => _na(xs.slice(1)).run()));
const $na: (xs: List<Num>) => number[] const $na: (xs: List<Num>) => number[]
= xs => $$(xs._(__([]))._(_(x => _(xs => __([$nn(x), ...$na(xs)]))))); = xs => $$(xs(__([]))(_(x => _(xs => __([$nn(x), ...$na(xs)])))));
describe('toArray', () => { describe('toArray', () => {
it('converts []', () => { it('converts []', () => {
@ -22,11 +22,11 @@ describe('List', () => {
}); });
it('converts [0]', () => { it('converts [0]', () => {
expect($a(Cons._(_n(0))._(Nil)).map($n)).toEqual([0]); expect($a(Cons(_n(0))(Nil)).map($n)).toEqual([0]);
}); });
it('converts [0, 1]', () => { it('converts [0, 1]', () => {
expect($a(Cons._(_n(0))._(Cons._(_n(1))._(Nil))).map($n)).toEqual([0, 1]); expect($a(Cons(_n(0))(Cons(_n(1))(Nil))).map($n)).toEqual([0, 1]);
}); });
}); });
@ -46,669 +46,669 @@ describe('List', () => {
describe('cons', () => { describe('cons', () => {
it('0 cons Nil is [0]', () => { it('0 cons Nil is [0]', () => {
expect($na(cons._(_n(0))._(Nil))).toEqual([0]); expect($na(cons(_n(0))(Nil))).toEqual([0]);
}); });
it('0 cons [1] is [0, 1]', () => { it('0 cons [1] is [0, 1]', () => {
expect($na(cons._(_n(0))._(_na([1])))).toEqual([0, 1]); expect($na(cons(_n(0))(_na([1])))).toEqual([0, 1]);
}); });
it('0 cons [1, 2] is [0, 1, 2]', () => { it('0 cons [1, 2] is [0, 1, 2]', () => {
expect($na(cons._(_n(0))._(_na([1, 2])))).toEqual([0, 1, 2]); expect($na(cons(_n(0))(_na([1, 2])))).toEqual([0, 1, 2]);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n(cons._(_n(0))._(infinite)._(undef)._(_(x => _(_xs => x))))).toBe(0); expect($n(cons(_n(0))(infinite)(undef)(_(x => _(_xs => x))))).toBe(0);
}); });
}); });
describe('snoc', () => { describe('snoc', () => {
it('Nil snoc 0 is [0]', () => { it('Nil snoc 0 is [0]', () => {
expect($na(snoc._(Nil)._(_n(0)))).toEqual([0]); expect($na(snoc(Nil)(_n(0)))).toEqual([0]);
}); });
it('[1] snoc 0 is [1, 0]', () => { it('[1] snoc 0 is [1, 0]', () => {
expect($na(snoc._(_na([1]))._(_n(0)))).toEqual([1, 0]); expect($na(snoc(_na([1]))(_n(0)))).toEqual([1, 0]);
}); });
it('[1, 2] snoc 0 is [1, 2, 0]', () => { it('[1, 2] snoc 0 is [1, 2, 0]', () => {
expect($na(snoc._(_na([1, 2]))._(_n(0)))).toEqual([1, 2, 0]); expect($na(snoc(_na([1, 2]))(_n(0)))).toEqual([1, 2, 0]);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n(snoc._(infinite)._(_n(0))._(undef)._(_(x => _(_xs => x))))).toBe(0); expect($n(snoc(infinite)(_n(0))(undef)(_(x => _(_xs => x))))).toBe(0);
}); });
}); });
describe('nul', () => { describe('nul', () => {
it('nul Nil is True', () => { it('nul Nil is True', () => {
expect($b(nul._(_na([])))).toEqual(true); expect($b(nul(_na([])))).toEqual(true);
}); });
it('nul [1] is False', () => { it('nul [1] is False', () => {
expect($b(nul._(_na([1])))).toEqual(false); expect($b(nul(_na([1])))).toEqual(false);
}); });
it('nul [1, 2] is False', () => { it('nul [1, 2] is False', () => {
expect($b(nul._(_na([1, 2])))).toEqual(false); expect($b(nul(_na([1, 2])))).toEqual(false);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($b(nul._(infinite))).toEqual(false); expect($b(nul(infinite))).toEqual(false);
}); });
}); });
describe('len', () => { describe('len', () => {
it('len Nil is 0', () => { it('len Nil is 0', () => {
expect($n(len._(_na([])))).toEqual(0); expect($n(len(_na([])))).toEqual(0);
}); });
it('len [1] is 1', () => { it('len [1] is 1', () => {
expect($n(len._(_na([1])))).toEqual(1); expect($n(len(_na([1])))).toEqual(1);
}); });
it('len [1, 2] is 2', () => { it('len [1, 2] is 2', () => {
expect($n(len._(_na([1, 2])))).toEqual(2); expect($n(len(_na([1, 2])))).toEqual(2);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($b(ngt._(len._(infinite))._(Zero))).toEqual(true); expect($b(ngt(len(infinite))(Zero))).toEqual(true);
}); });
}); });
describe('append', () => { describe('append', () => {
it('Nil append Nil is Nil', () => { it('Nil append Nil is Nil', () => {
expect($na(append._(Nil)._(Nil))).toEqual([]); expect($na(append(Nil)(Nil))).toEqual([]);
}); });
it('[0] append [1] is [0, 1]', () => { it('[0] append [1] is [0, 1]', () => {
expect($na(append._(_na([0]))._(_na([1])))).toEqual([0, 1]); expect($na(append(_na([0]))(_na([1])))).toEqual([0, 1]);
}); });
it('[0, 1] append [2, 3] is [0, 1, 2, 3]', () => { it('[0, 1] append [2, 3] is [0, 1, 2, 3]', () => {
expect($na(append._(_na([0, 1]))._(_na([2, 3])))).toEqual([0, 1, 2, 3]); expect($na(append(_na([0, 1]))(_na([2, 3])))).toEqual([0, 1, 2, 3]);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n(append._(infinite)._(infinite)._(undef)._(_(x => _(_xs => x))))).toBe(0); expect($n(append(infinite)(infinite)(undef)(_(x => _(_xs => x))))).toBe(0);
}); });
}); });
describe('concat', () => { describe('concat', () => {
it('concat [Nil, Nil, Nil] is Nil', () => { it('concat [Nil, Nil, Nil] is Nil', () => {
expect($na(concat._(cons._(Nil)._(cons._(Nil)._(cons._(Nil)._(Nil)))))).toEqual([]); expect($na(concat(cons(Nil)(cons(Nil)(cons(Nil)(Nil)))))).toEqual([]);
}); });
it('concat [[0], [1], [2]] is [0, 1, 2]', () => { it('concat [[0], [1], [2]] is [0, 1, 2]', () => {
expect($na(concat._(cons._(_na([0]))._(cons._(_na([1]))._(cons._(_na([2]))._(Nil)))))).toEqual([0, 1, 2]); expect($na(concat(cons(_na([0]))(cons(_na([1]))(cons(_na([2]))(Nil)))))).toEqual([0, 1, 2]);
}); });
it('concat [[0, 1], [2, 3], [4, 5]] is [0, 1, 2, 3, 4, 5]', () => { it('concat [[0, 1], [2, 3], [4, 5]] is [0, 1, 2, 3, 4, 5]', () => {
expect($na(concat._(cons._(_na([0, 1]))._(cons._(_na([2, 3]))._(cons._(_na([4, 5]))._(Nil)))))).toEqual([0, 1, 2, 3, 4, 5]); expect($na(concat(cons(_na([0, 1]))(cons(_na([2, 3]))(cons(_na([4, 5]))(Nil)))))).toEqual([0, 1, 2, 3, 4, 5]);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
const dinfinite: List<Num> = cons._(infinite)._(new L(() => dinfinite.value)); const dinfinite: List<Num> = cons(infinite)(___(() => dinfinite.run()));
expect($n(concat._(dinfinite)._(undef)._(_(x => _(_xs => x))))).toBe(0); expect($n(concat(dinfinite)(undef)(_(x => _(_xs => x))))).toBe(0);
}); });
}); });
// describe('repeat', () => { // describe('repeat', () => {
// it('repeat 0 is [0, 0, 0, ...]', () => { // it('repeat 0 is [0, 0, 0, ...]', () => {
// expect($na( // expect($na(
// repeat._(_n(0))._<List<Num>>(_((x0: Num) => _((x1s: List<Num>) => // repeat(_n(0))<List<Num>>(_((x0: Num) => _((x1s: List<Num>) =>
// x1s._<List<Num>>(_((x1: Num) => _((x2s: List<Num>) => // x1s<List<Num>>(_((x1: Num) => _((x2s: List<Num>) =>
// x2s._<List<Num>>(_((x2: Num) => _((_xrs: List<Num>): List<Num> => cons._(x0)._(cons._(x1)._(cons._(x2)._(Nil)))))))))))))).toEqual([0, 0, 0]); // x2s<List<Num>>(_((x2: Num) => _((_xrs: List<Num>): List<Num> => cons(x0)(cons(x1)(cons(x2)(Nil)))))))))))))).toEqual([0, 0, 0]);
// }); // });
// }); // });
// describe('iterate', () => { // describe('iterate', () => {
// it('iterate succ 0 is [0, 1, 2, ...]', () => { // it('iterate succ 0 is [0, 1, 2, ...]', () => {
// expect($na( // expect($na(
// iterate._(_n(0))._<List<Num>>(_((x0: Num) => _((x1s: List<Num>) => // iterate(_n(0))<List<Num>>(_((x0: Num) => _((x1s: List<Num>) =>
// x1s._<List<Num>>(_((x1: Num) => _((x2s: List<Num>) => // x1s<List<Num>>(_((x1: Num) => _((x2s: List<Num>) =>
// x2s._<List<Num>>(_((x2: Num) => _((_xrs: List<Num>): List<Num> => cons._(x0)._(cons._(x1)._(cons._(x2)._(Nil)))))))))))))).toEqual([0, 1, 2]); // x2s<List<Num>>(_((x2: Num) => _((_xrs: List<Num>): List<Num> => cons(x0)(cons(x1)(cons(x2)(Nil)))))))))))))).toEqual([0, 1, 2]);
// }); // });
// }); // });
describe('head', () => { describe('head', () => {
it('returns nothing from Nil', () => { it('returns nothing from Nil', () => {
expect(() => $$(head._(Nil))).toThrow(); expect(() => $$(head(Nil))).toThrow();
}); });
it('returns only item', () => { it('returns only item', () => {
expect($n(head._(_na([0])))).toBe(0); expect($n(head(_na([0])))).toBe(0);
}); });
it('returns first item', () => { it('returns first item', () => {
expect($n(head._(_na([0, 1])))).toBe(0); expect($n(head(_na([0, 1])))).toBe(0);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n(head._(infinite))).toBe(0); expect($n(head(infinite))).toBe(0);
}); });
}); });
describe('tail', () => { describe('tail', () => {
it('drops nothing from Nil', () => { it('drops nothing from Nil', () => {
expect(() => $na(tail._(Nil))).toThrow(); expect(() => $na(tail(Nil))).toThrow();
}); });
it('drops only item', () => { it('drops only item', () => {
expect($na(tail._(_na([0])))).toEqual([]); expect($na(tail(_na([0])))).toEqual([]);
}); });
it('drops first item', () => { it('drops first item', () => {
expect($na(tail._(_na([0, 1])))).toEqual([1]); expect($na(tail(_na([0, 1])))).toEqual([1]);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n(head._(tail._(infinite)))).toBe(1); expect($n(head(tail(infinite)))).toBe(1);
}); });
}); });
describe('foldl', () => { describe('foldl', () => {
it('folds Nil', () => { it('folds Nil', () => {
expect($n(foldl._(sum)._(Zero)._(_na([])))).toBe(0); expect($n(foldl(sum)(Zero)(_na([])))).toBe(0);
}); });
it('folds single item', () => { it('folds single item', () => {
expect($n(foldl._(sum)._(Zero)._(_na([1])))).toBe(1); expect($n(foldl(sum)(Zero)(_na([1])))).toBe(1);
}); });
it('folds several items', () => { it('folds several items', () => {
expect($n(foldl._(sum)._(Zero)._(_na([1, 2])))).toBe(3); expect($n(foldl(sum)(Zero)(_na([1, 2])))).toBe(3);
}); });
}); });
describe('foldlz', () => { describe('foldlz', () => {
it('does not fold Nil', () => { it('does not fold Nil', () => {
expect(() => $n(foldlz._(sum)._(Nil))).toThrow(); expect(() => $n(foldlz(sum)(Nil))).toThrow();
}); });
it('folds single item', () => { it('folds single item', () => {
expect($n(foldlz._(sum)._(_na([1])))).toBe(1); expect($n(foldlz(sum)(_na([1])))).toBe(1);
}); });
it('folds several items', () => { it('folds several items', () => {
expect($n(foldlz._(sum)._(_na([1, 2])))).toBe(3); expect($n(foldlz(sum)(_na([1, 2])))).toBe(3);
}); });
}); });
describe('foldr', () => { describe('foldr', () => {
it('folds Nil', () => { it('folds Nil', () => {
expect($n(foldr._(sum)._(Zero)._(_na([])))).toBe(0); expect($n(foldr(sum)(Zero)(_na([])))).toBe(0);
}); });
it('folds single item', () => { it('folds single item', () => {
expect($n(foldr._(sum)._(Zero)._(_na([1])))).toBe(1); expect($n(foldr(sum)(Zero)(_na([1])))).toBe(1);
}); });
it('folds several items', () => { it('folds several items', () => {
expect($n(foldr._(sum)._(Zero)._(_na([1, 2])))).toBe(3); expect($n(foldr(sum)(Zero)(_na([1, 2])))).toBe(3);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n( expect($n(
foldr foldr
._(_(x => _(a => sum._(x)._(iif._(eqn._(_n(5))._(x))._(Zero)._(a))))) (_(x => _(a => sum(x)(iif(eqn(_n(5))(x))(Zero)(a)))))
._(Zero) (Zero)
._(infinite))) (infinite)))
.toBe(15); .toBe(15);
}); });
}); });
describe('foldrz', () => { describe('foldrz', () => {
it('does not fold Nil', () => { it('does not fold Nil', () => {
expect(() => $n(foldrz._(sum)._(Nil))).toThrow(); expect(() => $n(foldrz(sum)(Nil))).toThrow();
}); });
it.failing('folds single item', () => { it.failing('folds single item', () => {
expect($n(foldrz._(sum)._(_na([1])))).toBe(1); expect($n(foldrz(sum)(_na([1])))).toBe(1);
}); });
it.failing('folds several items', () => { it.failing('folds several items', () => {
expect($n(foldrz._(sum)._(_na([1, 2])))).toBe(3); expect($n(foldrz(sum)(_na([1, 2])))).toBe(3);
}); });
it.failing('handles infinite lists', () => { it.failing('handles infinite lists', () => {
expect($n( expect($n(
foldrz foldrz
._(_(x => _(a => sum._(x)._(iif._(eqn._(_n(5))._(x))._(Zero)._(a))))) (_(x => _(a => sum(x)(iif(eqn(_n(5))(x))(Zero)(a)))))
._(infinite))) (infinite)))
.toBe(15); .toBe(15);
}); });
}); });
describe('cmp', () => { describe('cmp', () => {
it('Nil cmp Nil is EQ', () => { it('Nil cmp Nil is EQ', () => {
expect($o(cmp._(cmpn)._(_na([]))._(_na([])))).toEqual(NOrd.EQ); expect($o(cmp(cmpn)(_na([]))(_na([])))).toEqual(NOrd.EQ);
}); });
it('Nil cmp [0, 1, 2] is LT', () => { it('Nil cmp [0, 1, 2] is LT', () => {
expect($o(cmp._(cmpn)._(_na([]))._(_na([0, 1, 2])))).toEqual(NOrd.LT); expect($o(cmp(cmpn)(_na([]))(_na([0, 1, 2])))).toEqual(NOrd.LT);
}); });
it('[0, 1, 2] cmp Nil is GT', () => { it('[0, 1, 2] cmp Nil is GT', () => {
expect($o(cmp._(cmpn)._(_na([0, 1, 2]))._(_na([])))).toEqual(NOrd.GT); expect($o(cmp(cmpn)(_na([0, 1, 2]))(_na([])))).toEqual(NOrd.GT);
}); });
it('[0] cmp [0, 1, 2] is LT', () => { it('[0] cmp [0, 1, 2] is LT', () => {
expect($o(cmp._(cmpn)._(_na([0]))._(_na([0, 1, 2])))).toEqual(NOrd.LT); expect($o(cmp(cmpn)(_na([0]))(_na([0, 1, 2])))).toEqual(NOrd.LT);
}); });
it('[0, 1, 2] cmp [0] is GT', () => { it('[0, 1, 2] cmp [0] is GT', () => {
expect($o(cmp._(cmpn)._(_na([0, 1, 2]))._(_na([0])))).toEqual(NOrd.GT); expect($o(cmp(cmpn)(_na([0, 1, 2]))(_na([0])))).toEqual(NOrd.GT);
}); });
it('[1, 2, 0] cmp [0, 1, 2] is GT', () => { it('[1, 2, 0] cmp [0, 1, 2] is GT', () => {
expect($o(cmp._(cmpn)._(_na([1, 2, 0]))._(_na([0, 1, 2])))).toEqual(NOrd.GT); expect($o(cmp(cmpn)(_na([1, 2, 0]))(_na([0, 1, 2])))).toEqual(NOrd.GT);
}); });
it('[0, 1, 2] cmp [1, 2, 0] is LT', () => { it('[0, 1, 2] cmp [1, 2, 0] is LT', () => {
expect($o(cmp._(cmpn)._(_na([0, 1, 2]))._(_na([1, 2, 0])))).toEqual(NOrd.LT); expect($o(cmp(cmpn)(_na([0, 1, 2]))(_na([1, 2, 0])))).toEqual(NOrd.LT);
}); });
it('[0, 1, 2] cmp [0, 1, 2] is EQ', () => { it('[0, 1, 2] cmp [0, 1, 2] is EQ', () => {
expect($o(cmp._(cmpn)._(_na([0, 1, 2]))._(_na([0, 1, 2])))).toEqual(NOrd.EQ); expect($o(cmp(cmpn)(_na([0, 1, 2]))(_na([0, 1, 2])))).toEqual(NOrd.EQ);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($o(cmp._(cmpn)._(_na([0, 1, 2]))._(infinite))).toEqual(NOrd.LT); expect($o(cmp(cmpn)(_na([0, 1, 2]))(infinite))).toEqual(NOrd.LT);
expect($o(cmp._(cmpn)._(infinite)._(_na([0, 1, 2])))).toEqual(NOrd.GT); expect($o(cmp(cmpn)(infinite)(_na([0, 1, 2])))).toEqual(NOrd.GT);
}); });
}); });
describe('lt', () => { describe('lt', () => {
it('Nil lt Nil is False', () => { it('Nil lt Nil is False', () => {
expect($b(lt._(cmpn)._(_na([]))._(_na([])))).toEqual(false); expect($b(lt(cmpn)(_na([]))(_na([])))).toEqual(false);
}); });
it('Nil lt [0, 1, 2] is True', () => { it('Nil lt [0, 1, 2] is True', () => {
expect($b(lt._(cmpn)._(_na([]))._(_na([0, 1, 2])))).toEqual(true); expect($b(lt(cmpn)(_na([]))(_na([0, 1, 2])))).toEqual(true);
}); });
it('[0, 1, 2] lt Nil is False', () => { it('[0, 1, 2] lt Nil is False', () => {
expect($b(lt._(cmpn)._(_na([0, 1, 2]))._(_na([])))).toEqual(false); expect($b(lt(cmpn)(_na([0, 1, 2]))(_na([])))).toEqual(false);
}); });
it('[0] lt [0, 1, 2] is True', () => { it('[0] lt [0, 1, 2] is True', () => {
expect($b(lt._(cmpn)._(_na([0]))._(_na([0, 1, 2])))).toEqual(true); expect($b(lt(cmpn)(_na([0]))(_na([0, 1, 2])))).toEqual(true);
}); });
it('[0, 1, 2] lt [0] is False', () => { it('[0, 1, 2] lt [0] is False', () => {
expect($b(lt._(cmpn)._(_na([0, 1, 2]))._(_na([0])))).toEqual(false); expect($b(lt(cmpn)(_na([0, 1, 2]))(_na([0])))).toEqual(false);
}); });
it('[1, 2, 0] lt [0, 1, 2] is False', () => { it('[1, 2, 0] lt [0, 1, 2] is False', () => {
expect($b(lt._(cmpn)._(_na([1, 2, 0]))._(_na([0, 1, 2])))).toEqual(false); expect($b(lt(cmpn)(_na([1, 2, 0]))(_na([0, 1, 2])))).toEqual(false);
}); });
it('[0, 1, 2] lt [1, 2, 0] is True', () => { it('[0, 1, 2] lt [1, 2, 0] is True', () => {
expect($b(lt._(cmpn)._(_na([0, 1, 2]))._(_na([1, 2, 0])))).toEqual(true); expect($b(lt(cmpn)(_na([0, 1, 2]))(_na([1, 2, 0])))).toEqual(true);
}); });
it('[0, 1, 2] lt [0, 1, 2] is False', () => { it('[0, 1, 2] lt [0, 1, 2] is False', () => {
expect($b(lt._(cmpn)._(_na([0, 1, 2]))._(_na([0, 1, 2])))).toEqual(false); expect($b(lt(cmpn)(_na([0, 1, 2]))(_na([0, 1, 2])))).toEqual(false);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($b(lt._(cmpn)._(_na([0, 1, 2]))._(infinite))).toEqual(true); expect($b(lt(cmpn)(_na([0, 1, 2]))(infinite))).toEqual(true);
expect($b(lt._(cmpn)._(infinite)._(_na([0, 1, 2])))).toEqual(false); expect($b(lt(cmpn)(infinite)(_na([0, 1, 2])))).toEqual(false);
}); });
}); });
describe('le', () => { describe('le', () => {
it('Nil le Nil is True', () => { it('Nil le Nil is True', () => {
expect($b(le._(cmpn)._(_na([]))._(_na([])))).toEqual(true); expect($b(le(cmpn)(_na([]))(_na([])))).toEqual(true);
}); });
it('Nil le [0, 1, 2] is True', () => { it('Nil le [0, 1, 2] is True', () => {
expect($b(le._(cmpn)._(_na([]))._(_na([0, 1, 2])))).toEqual(true); expect($b(le(cmpn)(_na([]))(_na([0, 1, 2])))).toEqual(true);
}); });
it('[0, 1, 2] le Nil is False', () => { it('[0, 1, 2] le Nil is False', () => {
expect($b(le._(cmpn)._(_na([0, 1, 2]))._(_na([])))).toEqual(false); expect($b(le(cmpn)(_na([0, 1, 2]))(_na([])))).toEqual(false);
}); });
it('[0] le [0, 1, 2] is True', () => { it('[0] le [0, 1, 2] is True', () => {
expect($b(le._(cmpn)._(_na([0]))._(_na([0, 1, 2])))).toEqual(true); expect($b(le(cmpn)(_na([0]))(_na([0, 1, 2])))).toEqual(true);
}); });
it('[0, 1, 2] le [0] is False', () => { it('[0, 1, 2] le [0] is False', () => {
expect($b(le._(cmpn)._(_na([0, 1, 2]))._(_na([0])))).toEqual(false); expect($b(le(cmpn)(_na([0, 1, 2]))(_na([0])))).toEqual(false);
}); });
it('[1, 2, 0] le [0, 1, 2] is False', () => { it('[1, 2, 0] le [0, 1, 2] is False', () => {
expect($b(le._(cmpn)._(_na([1, 2, 0]))._(_na([0, 1, 2])))).toEqual(false); expect($b(le(cmpn)(_na([1, 2, 0]))(_na([0, 1, 2])))).toEqual(false);
}); });
it('[0, 1, 2] le [1, 2, 0] is True', () => { it('[0, 1, 2] le [1, 2, 0] is True', () => {
expect($b(le._(cmpn)._(_na([0, 1, 2]))._(_na([1, 2, 0])))).toEqual(true); expect($b(le(cmpn)(_na([0, 1, 2]))(_na([1, 2, 0])))).toEqual(true);
}); });
it('[0, 1, 2] le [0, 1, 2] is True', () => { it('[0, 1, 2] le [0, 1, 2] is True', () => {
expect($b(le._(cmpn)._(_na([0, 1, 2]))._(_na([0, 1, 2])))).toEqual(true); expect($b(le(cmpn)(_na([0, 1, 2]))(_na([0, 1, 2])))).toEqual(true);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($b(le._(cmpn)._(_na([0, 1, 2]))._(infinite))).toEqual(true); expect($b(le(cmpn)(_na([0, 1, 2]))(infinite))).toEqual(true);
expect($b(le._(cmpn)._(infinite)._(_na([0, 1, 2])))).toEqual(false); expect($b(le(cmpn)(infinite)(_na([0, 1, 2])))).toEqual(false);
}); });
}); });
describe('eq', () => { describe('eq', () => {
it('Nil eq Nil is True', () => { it('Nil eq Nil is True', () => {
expect($b(eq._(eqn)._(_na([]))._(_na([])))).toEqual(true); expect($b(eq(eqn)(_na([]))(_na([])))).toEqual(true);
}); });
it('Nil eq [0, 1, 2] is False', () => { it('Nil eq [0, 1, 2] is False', () => {
expect($b(eq._(eqn)._(_na([]))._(_na([0, 1, 2])))).toEqual(false); expect($b(eq(eqn)(_na([]))(_na([0, 1, 2])))).toEqual(false);
}); });
it('[0, 1, 2] eq Nil is False', () => { it('[0, 1, 2] eq Nil is False', () => {
expect($b(eq._(eqn)._(_na([0, 1, 2]))._(_na([])))).toEqual(false); expect($b(eq(eqn)(_na([0, 1, 2]))(_na([])))).toEqual(false);
}); });
it('[0] eq [0, 1, 2] is False', () => { it('[0] eq [0, 1, 2] is False', () => {
expect($b(eq._(eqn)._(_na([0]))._(_na([0, 1, 2])))).toEqual(false); expect($b(eq(eqn)(_na([0]))(_na([0, 1, 2])))).toEqual(false);
}); });
it('[0, 1, 2] eq [0] is False', () => { it('[0, 1, 2] eq [0] is False', () => {
expect($b(eq._(eqn)._(_na([0, 1, 2]))._(_na([0])))).toEqual(false); expect($b(eq(eqn)(_na([0, 1, 2]))(_na([0])))).toEqual(false);
}); });
it('[1, 2, 0] eq [0, 1, 2] is False', () => { it('[1, 2, 0] eq [0, 1, 2] is False', () => {
expect($b(eq._(eqn)._(_na([1, 2, 0]))._(_na([0, 1, 2])))).toEqual(false); expect($b(eq(eqn)(_na([1, 2, 0]))(_na([0, 1, 2])))).toEqual(false);
}); });
it('[0, 1, 2] eq [1, 2, 0] is False', () => { it('[0, 1, 2] eq [1, 2, 0] is False', () => {
expect($b(eq._(eqn)._(_na([0, 1, 2]))._(_na([1, 2, 0])))).toEqual(false); expect($b(eq(eqn)(_na([0, 1, 2]))(_na([1, 2, 0])))).toEqual(false);
}); });
it('[0, 1, 2] eq [0, 1, 2] is True', () => { it('[0, 1, 2] eq [0, 1, 2] is True', () => {
expect($b(eq._(eqn)._(_na([0, 1, 2]))._(_na([0, 1, 2])))).toEqual(true); expect($b(eq(eqn)(_na([0, 1, 2]))(_na([0, 1, 2])))).toEqual(true);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($b(eq._(eqn)._(_na([0, 1, 2]))._(infinite))).toEqual(false); expect($b(eq(eqn)(_na([0, 1, 2]))(infinite))).toEqual(false);
expect($b(eq._(eqn)._(infinite)._(_na([0, 1, 2])))).toEqual(false); expect($b(eq(eqn)(infinite)(_na([0, 1, 2])))).toEqual(false);
}); });
}); });
describe('ge', () => { describe('ge', () => {
it('Nil ge Nil is True', () => { it('Nil ge Nil is True', () => {
expect($b(ge._(cmpn)._(_na([]))._(_na([])))).toEqual(true); expect($b(ge(cmpn)(_na([]))(_na([])))).toEqual(true);
}); });
it('Nil ge [0, 1, 2] is False', () => { it('Nil ge [0, 1, 2] is False', () => {
expect($b(ge._(cmpn)._(_na([]))._(_na([0, 1, 2])))).toEqual(false); expect($b(ge(cmpn)(_na([]))(_na([0, 1, 2])))).toEqual(false);
}); });
it('[0, 1, 2] ge Nil is True', () => { it('[0, 1, 2] ge Nil is True', () => {
expect($b(ge._(cmpn)._(_na([0, 1, 2]))._(_na([])))).toEqual(true); expect($b(ge(cmpn)(_na([0, 1, 2]))(_na([])))).toEqual(true);
}); });
it('[0] ge [0, 1, 2] is False', () => { it('[0] ge [0, 1, 2] is False', () => {
expect($b(ge._(cmpn)._(_na([0]))._(_na([0, 1, 2])))).toEqual(false); expect($b(ge(cmpn)(_na([0]))(_na([0, 1, 2])))).toEqual(false);
}); });
it('[0, 1, 2] ge [0] is True', () => { it('[0, 1, 2] ge [0] is True', () => {
expect($b(ge._(cmpn)._(_na([0, 1, 2]))._(_na([0])))).toEqual(true); expect($b(ge(cmpn)(_na([0, 1, 2]))(_na([0])))).toEqual(true);
}); });
it('[1, 2, 0] ge [0, 1, 2] is True', () => { it('[1, 2, 0] ge [0, 1, 2] is True', () => {
expect($b(ge._(cmpn)._(_na([1, 2, 0]))._(_na([0, 1, 2])))).toEqual(true); expect($b(ge(cmpn)(_na([1, 2, 0]))(_na([0, 1, 2])))).toEqual(true);
}); });
it('[0, 1, 2] ge [1, 2, 0] is False', () => { it('[0, 1, 2] ge [1, 2, 0] is False', () => {
expect($b(ge._(cmpn)._(_na([0, 1, 2]))._(_na([1, 2, 0])))).toEqual(false); expect($b(ge(cmpn)(_na([0, 1, 2]))(_na([1, 2, 0])))).toEqual(false);
}); });
it('[0, 1, 2] ge [0, 1, 2] is True', () => { it('[0, 1, 2] ge [0, 1, 2] is True', () => {
expect($b(ge._(cmpn)._(_na([0, 1, 2]))._(_na([0, 1, 2])))).toEqual(true); expect($b(ge(cmpn)(_na([0, 1, 2]))(_na([0, 1, 2])))).toEqual(true);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($b(ge._(cmpn)._(_na([0, 1, 2]))._(infinite))).toEqual(false); expect($b(ge(cmpn)(_na([0, 1, 2]))(infinite))).toEqual(false);
expect($b(ge._(cmpn)._(infinite)._(_na([0, 1, 2])))).toEqual(true); expect($b(ge(cmpn)(infinite)(_na([0, 1, 2])))).toEqual(true);
}); });
}); });
describe('gt', () => { describe('gt', () => {
it('Nil gt Nil is False', () => { it('Nil gt Nil is False', () => {
expect($b(gt._(cmpn)._(_na([]))._(_na([])))).toEqual(false); expect($b(gt(cmpn)(_na([]))(_na([])))).toEqual(false);
}); });
it('Nil gt [0, 1, 2] is False', () => { it('Nil gt [0, 1, 2] is False', () => {
expect($b(gt._(cmpn)._(_na([]))._(_na([0, 1, 2])))).toEqual(false); expect($b(gt(cmpn)(_na([]))(_na([0, 1, 2])))).toEqual(false);
}); });
it('[0, 1, 2] gt Nil is True', () => { it('[0, 1, 2] gt Nil is True', () => {
expect($b(gt._(cmpn)._(_na([0, 1, 2]))._(_na([])))).toEqual(true); expect($b(gt(cmpn)(_na([0, 1, 2]))(_na([])))).toEqual(true);
}); });
it('[0] gt [0, 1, 2] is False', () => { it('[0] gt [0, 1, 2] is False', () => {
expect($b(gt._(cmpn)._(_na([0]))._(_na([0, 1, 2])))).toEqual(false); expect($b(gt(cmpn)(_na([0]))(_na([0, 1, 2])))).toEqual(false);
}); });
it('[0, 1, 2] gt [0] is True', () => { it('[0, 1, 2] gt [0] is True', () => {
expect($b(gt._(cmpn)._(_na([0, 1, 2]))._(_na([0])))).toEqual(true); expect($b(gt(cmpn)(_na([0, 1, 2]))(_na([0])))).toEqual(true);
}); });
it('[1, 2, 0] gt [0, 1, 2] is True', () => { it('[1, 2, 0] gt [0, 1, 2] is True', () => {
expect($b(gt._(cmpn)._(_na([1, 2, 0]))._(_na([0, 1, 2])))).toEqual(true); expect($b(gt(cmpn)(_na([1, 2, 0]))(_na([0, 1, 2])))).toEqual(true);
}); });
it('[0, 1, 2] gt [1, 2, 0] is False', () => { it('[0, 1, 2] gt [1, 2, 0] is False', () => {
expect($b(gt._(cmpn)._(_na([0, 1, 2]))._(_na([1, 2, 0])))).toEqual(false); expect($b(gt(cmpn)(_na([0, 1, 2]))(_na([1, 2, 0])))).toEqual(false);
}); });
it('[0, 1, 2] gt [0, 1, 2] is False', () => { it('[0, 1, 2] gt [0, 1, 2] is False', () => {
expect($b(gt._(cmpn)._(_na([0, 1, 2]))._(_na([0, 1, 2])))).toEqual(false); expect($b(gt(cmpn)(_na([0, 1, 2]))(_na([0, 1, 2])))).toEqual(false);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($b(gt._(cmpn)._(_na([0, 1, 2]))._(infinite))).toEqual(false); expect($b(gt(cmpn)(_na([0, 1, 2]))(infinite))).toEqual(false);
expect($b(gt._(cmpn)._(infinite)._(_na([0, 1, 2])))).toEqual(true); expect($b(gt(cmpn)(infinite)(_na([0, 1, 2])))).toEqual(true);
}); });
}); });
describe('map', () => { describe('map', () => {
it('maps Nil', () => { it('maps Nil', () => {
expect($na(map._(succ)._(_na([])))).toEqual([]); expect($na(map(succ)(_na([])))).toEqual([]);
}); });
it('maps only item', () => { it('maps only item', () => {
expect($na(map._(succ)._(_na([0])))).toEqual([1]); expect($na(map(succ)(_na([0])))).toEqual([1]);
}); });
it('maps several items', () => { it('maps several items', () => {
expect($na(map._(succ)._(_na([0, 1])))).toEqual([1, 2]); expect($na(map(succ)(_na([0, 1])))).toEqual([1, 2]);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n(head._(map._(succ)._(infinite)))).toBe(1); expect($n(head(map(succ)(infinite)))).toBe(1);
}); });
}); });
describe('filter', () => { describe('filter', () => {
it('filter Nil', () => { it('filter Nil', () => {
expect($na(filter._(odd)._(_na([])))).toEqual([]); expect($na(filter(odd)(_na([])))).toEqual([]);
}); });
it('filters only item', () => { it('filters only item', () => {
expect($na(filter._(odd)._(_na([])))).toEqual([]); expect($na(filter(odd)(_na([])))).toEqual([]);
}); });
it('filters several items', () => { it('filters several items', () => {
expect($na(filter._(odd)._(_na([0, 1])))).toEqual([1]); expect($na(filter(odd)(_na([0, 1])))).toEqual([1]);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n(head._(filter._(odd)._(infinite)))).toBe(1); expect($n(head(filter(odd)(infinite)))).toBe(1);
}); });
}); });
describe('any', () => { describe('any', () => {
it('any Nil is False', () => { it('any Nil is False', () => {
expect($b(any._(odd)._(_na([])))).toEqual(false); expect($b(any(odd)(_na([])))).toEqual(false);
}); });
it('any for no matching item is False', () => { it('any for no matching item is False', () => {
expect($b(any._(odd)._(_na([0, 2])))).toEqual(false); expect($b(any(odd)(_na([0, 2])))).toEqual(false);
}); });
it('any for matching item is True', () => { it('any for matching item is True', () => {
expect($b(any._(odd)._(_na([0, 1, 2])))).toEqual(true); expect($b(any(odd)(_na([0, 1, 2])))).toEqual(true);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($b(any._(odd)._(infinite))).toEqual(true); expect($b(any(odd)(infinite))).toEqual(true);
}); });
}); });
describe('all', () => { describe('all', () => {
it('all Nil is True', () => { it('all Nil is True', () => {
expect($b(all._(even)._(_na([])))).toEqual(true); expect($b(all(even)(_na([])))).toEqual(true);
}); });
it('all for non-matching item is False', () => { it('all for non-matching item is False', () => {
expect($b(all._(even)._(_na([0, 1, 2])))).toEqual(false); expect($b(all(even)(_na([0, 1, 2])))).toEqual(false);
}); });
it('all for no non-matching item is True', () => { it('all for no non-matching item is True', () => {
expect($b(all._(even)._(_na([0, 2])))).toEqual(true); expect($b(all(even)(_na([0, 2])))).toEqual(true);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($b(all._(even)._(infinite))).toEqual(false); expect($b(all(even)(infinite))).toEqual(false);
}); });
}); });
describe('get', () => { describe('get', () => {
it('returns nothing from Nil', () => { it('returns nothing from Nil', () => {
expect(() => $n(get._(_n(0))._(Nil))).toThrow(); expect(() => $n(get(_n(0))(Nil))).toThrow();
}); });
it('returns nothing with out of bounds index', () => { it('returns nothing with out of bounds index', () => {
expect(() => $n(get._(_n(100))._(_na([0, 1, 2, 3])))).toThrow(); expect(() => $n(get(_n(100))(_na([0, 1, 2, 3])))).toThrow();
}); });
it('[0, 1, 2, 3][0] is 0', () => { it('[0, 1, 2, 3][0] is 0', () => {
expect($n(get._(_n(0))._(_na([0, 1, 2, 3])))).toBe(0); expect($n(get(_n(0))(_na([0, 1, 2, 3])))).toBe(0);
}); });
it('[0, 1, 2, 3][1] is 1', () => { it('[0, 1, 2, 3][1] is 1', () => {
expect($n(get._(_n(1))._(_na([0, 1, 2, 3])))).toBe(1); expect($n(get(_n(1))(_na([0, 1, 2, 3])))).toBe(1);
}); });
it('[0, 1, 2, 3][2] is 2', () => { it('[0, 1, 2, 3][2] is 2', () => {
expect($n(get._(_n(2))._(_na([0, 1, 2, 3])))).toBe(2); expect($n(get(_n(2))(_na([0, 1, 2, 3])))).toBe(2);
}); });
it('[0, 1, 2, 3][3] get 3 is 3', () => { it('[0, 1, 2, 3][3] get 3 is 3', () => {
expect($n(get._(_n(3))._(_na([0, 1, 2, 3])))).toBe(3); expect($n(get(_n(3))(_na([0, 1, 2, 3])))).toBe(3);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n(get._(_n(4))._(infinite))).toBe(4); expect($n(get(_n(4))(infinite))).toBe(4);
}); });
}); });
describe('set', () => { describe('set', () => {
it('can not update Nil', () => { it('can not update Nil', () => {
expect(() => $na(set._(_n(10))._(_n(0))._(Nil))).toThrow(); expect(() => $na(set(_n(10))(_n(0))(Nil))).toThrow();
}); });
it('can not update out of bounds index', () => { it('can not update out of bounds index', () => {
expect(() => $na(set._(_n(10))._(_n(100))._(_na([0, 1, 2, 3])))).toThrow(); expect(() => $na(set(_n(10))(_n(100))(_na([0, 1, 2, 3])))).toThrow();
}); });
it('[0, 1, 2, 3][0] = 10 is [10, 1, 2, 3]', () => { it('[0, 1, 2, 3][0] = 10 is [10, 1, 2, 3]', () => {
expect($na(set._(_n(10))._(_n(0))._(_na([0, 1, 2, 3])))).toEqual([10, 1, 2, 3]); expect($na(set(_n(10))(_n(0))(_na([0, 1, 2, 3])))).toEqual([10, 1, 2, 3]);
}); });
it('[0, 1, 2, 3][1] = 10 is [0, 10, 2, 3]', () => { it('[0, 1, 2, 3][1] = 10 is [0, 10, 2, 3]', () => {
expect($na(set._(_n(10))._(_n(1))._(_na([0, 1, 2, 3])))).toEqual([0, 10, 2, 3]); expect($na(set(_n(10))(_n(1))(_na([0, 1, 2, 3])))).toEqual([0, 10, 2, 3]);
}); });
it('[0, 1, 2, 3][2] = 10 is [0, 1, 10, 3]', () => { it('[0, 1, 2, 3][2] = 10 is [0, 1, 10, 3]', () => {
expect($na(set._(_n(10))._(_n(2))._(_na([0, 1, 2, 3])))).toEqual([0, 1, 10, 3]); expect($na(set(_n(10))(_n(2))(_na([0, 1, 2, 3])))).toEqual([0, 1, 10, 3]);
}); });
it('[0, 1, 2, 3][3] = 10 is [0, 1, 2, 10]', () => { it('[0, 1, 2, 3][3] = 10 is [0, 1, 2, 10]', () => {
expect($na(set._(_n(10))._(_n(3))._(_na([0, 1, 2, 3])))).toEqual([0, 1, 2, 10]); expect($na(set(_n(10))(_n(3))(_na([0, 1, 2, 3])))).toEqual([0, 1, 2, 10]);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n(get._(_n(4))._(set._(_n(10))._(_n(4))._(infinite)))).toBe(10); expect($n(get(_n(4))(set(_n(10))(_n(4))(infinite)))).toBe(10);
}); });
}); });
describe('update', () => { describe('update', () => {
it('can not update Nil', () => { it('can not update Nil', () => {
expect(() => $na(update._(succ)._(_n(0))._(Nil))).toThrow(); expect(() => $na(update(succ)(_n(0))(Nil))).toThrow();
}); });
it('can not update out of bounds index', () => { it('can not update out of bounds index', () => {
expect(() => $na(update._(succ)._(_n(100))._(_na([0, 1, 2, 3])))).toThrow(); expect(() => $na(update(succ)(_n(100))(_na([0, 1, 2, 3])))).toThrow();
}); });
it('[0, 1, 2, 3][0]++ is [10, 1, 2, 3]', () => { it('[0, 1, 2, 3][0]++ is [10, 1, 2, 3]', () => {
expect($na(update._(succ)._(_n(0))._(_na([0, 1, 2, 3])))).toEqual([1, 1, 2, 3]); expect($na(update(succ)(_n(0))(_na([0, 1, 2, 3])))).toEqual([1, 1, 2, 3]);
}); });
it('[0, 1, 2, 3][1]++ is [0, 10, 2, 3]', () => { it('[0, 1, 2, 3][1]++ is [0, 10, 2, 3]', () => {
expect($na(update._(succ)._(_n(1))._(_na([0, 1, 2, 3])))).toEqual([0, 2, 2, 3]); expect($na(update(succ)(_n(1))(_na([0, 1, 2, 3])))).toEqual([0, 2, 2, 3]);
}); });
it('[0, 1, 2, 3][2]++ is [0, 1, 10, 3]', () => { it('[0, 1, 2, 3][2]++ is [0, 1, 10, 3]', () => {
expect($na(update._(succ)._(_n(2))._(_na([0, 1, 2, 3])))).toEqual([0, 1, 3, 3]); expect($na(update(succ)(_n(2))(_na([0, 1, 2, 3])))).toEqual([0, 1, 3, 3]);
}); });
it('[0, 1, 2, 3][3]++ is [0, 1, 2, 10]', () => { it('[0, 1, 2, 3][3]++ is [0, 1, 2, 10]', () => {
expect($na(update._(succ)._(_n(3))._(_na([0, 1, 2, 3])))).toEqual([0, 1, 2, 4]); expect($na(update(succ)(_n(3))(_na([0, 1, 2, 3])))).toEqual([0, 1, 2, 4]);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n(get._(_n(4))._(update._(succ)._(_n(4))._(infinite)))).toBe(5); expect($n(get(_n(4))(update(succ)(_n(4))(infinite)))).toBe(5);
}); });
}); });
describe('intersperse', () => { describe('intersperse', () => {
it('0 intersperse Nil is Nil', () => { it('0 intersperse Nil is Nil', () => {
expect($na(intersperse._(_n(0))._(Nil))).toEqual([]); expect($na(intersperse(_n(0))(Nil))).toEqual([]);
}); });
it('0 intersperse [1] is [1]', () => { it('0 intersperse [1] is [1]', () => {
expect($na(intersperse._(_n(0))._(_na([1])))).toEqual([1]); expect($na(intersperse(_n(0))(_na([1])))).toEqual([1]);
}); });
it('0 intersperse [1, 2, 3] is [1, 0, 2, 0, 3]', () => { it('0 intersperse [1, 2, 3] is [1, 0, 2, 0, 3]', () => {
expect($na(intersperse._(_n(0))._(_na([1, 2, 3])))).toEqual([1, 0, 2, 0, 3]); expect($na(intersperse(_n(0))(_na([1, 2, 3])))).toEqual([1, 0, 2, 0, 3]);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($n(head._(intersperse._(_n(0))._(infinite)))).toBe(0); expect($n(head(intersperse(_n(0))(infinite)))).toBe(0);
}); });
}); });
describe('show', () => { describe('show', () => {
it('show Nil is "[]"', () => { it('show Nil is "[]"', () => {
expect($s(show._(nshow)._(_na([])))).toBe('[]'); expect($s(show(nshow)(_na([])))).toBe('[]');
}); });
it('show [0] is "[0]"', () => { it('show [0] is "[0]"', () => {
expect($s(show._(nshow)._(_na([0])))).toBe('[0]'); expect($s(show(nshow)(_na([0])))).toBe('[0]');
}); });
it('show [0, 1, 2] is "[0, 1, 2]"', () => { it('show [0, 1, 2] is "[0, 1, 2]"', () => {
expect($s(show._(nshow)._(_na([0, 1, 2])))).toBe('[0, 1, 2]'); expect($s(show(nshow)(_na([0, 1, 2])))).toBe('[0, 1, 2]');
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($c(head._(show._(nshow)._(infinite)))).toBe('['); expect($c(head(show(nshow)(infinite)))).toBe('[');
}); });
}); });
}); });

@ -1,12 +1,12 @@
import { describe, expect, it } from '@jest/globals'; import { describe, expect, it } from '@jest/globals';
import { L, undef } from '../src/core'; import { ___, L, undef } from '../src/core';
import { toNOrd as $o, NOrd } from '../src/ord'; import { toNOrd as $o, NOrd } from '../src/ord';
import { toBoolean as $b, fromBoolean as _b } from '../src/bool'; import { toBoolean as $b, fromBoolean as _b } from '../src/bool';
import { toNumber as $n, Num, Succ, Zero, fromNumber as _n, cmp, div, eq, ge, gt, ifz, le, lt, mod, mul, pred, show, sub, succ, sum } from '../src/num'; import { toNumber as $n, Num, Succ, Zero, fromNumber as _n, cmp, div, eq, ge, gt, ifz, le, lt, mod, mul, pred, show, sub, succ, sum } from '../src/num';
import { toString as $s } from '../src/string'; import { toString as $s } from '../src/string';
describe('Num', () => { describe('Num', () => {
const infinity: Num = new L(() => Succ._(infinity).value); const infinity: Num = ___(() => Succ(infinity).run());
describe('toNumber', () => { describe('toNumber', () => {
it('converts 0', () => { it('converts 0', () => {
@ -14,11 +14,11 @@ describe('Num', () => {
}); });
it('converts 1', () => { it('converts 1', () => {
expect($n(Succ._(Zero))).toBe(1); expect($n(Succ(Zero))).toBe(1);
}); });
it('converts 2', () => { it('converts 2', () => {
expect($n(Succ._(Succ._(Zero)))).toBe(2); expect($n(Succ(Succ(Zero)))).toBe(2);
}); });
}); });
@ -38,369 +38,369 @@ describe('Num', () => {
describe('ifz', () => { describe('ifz', () => {
it('returns zero branch', () => { it('returns zero branch', () => {
expect($b(ifz._(_n(0))._(_b(true))._(_b(false)))).toBe(true); expect($b(ifz(_n(0))(_b(true))(_b(false)))).toBe(true);
}); });
it('returns non-zero branch', () => { it('returns non-zero branch', () => {
expect($b(ifz._(_n(1))._(_b(true))._(_b(false)))).toBe(false); expect($b(ifz(_n(1))(_b(true))(_b(false)))).toBe(false);
}); });
it('returns non-zero branch', () => { it('returns non-zero branch', () => {
expect($b(ifz._(_n(10))._(_b(true))._(_b(false)))).toBe(false); expect($b(ifz(_n(10))(_b(true))(_b(false)))).toBe(false);
}); });
it('handles infinity', () => { it('handles infinity', () => {
expect($b(ifz._(infinity)._(_b(true))._(_b(false)))).toBe(false); expect($b(ifz(infinity)(_b(true))(_b(false)))).toBe(false);
}); });
}); });
describe('succ', () => { describe('succ', () => {
it('succ 0 is 1', () => { it('succ 0 is 1', () => {
expect($n(succ._(_n(0)))).toBe(1); expect($n(succ(_n(0)))).toBe(1);
}); });
it('succ 1 is 2', () => { it('succ 1 is 2', () => {
expect($n(succ._(_n(1)))).toBe(2); expect($n(succ(_n(1)))).toBe(2);
}); });
it('succ 10 is 11', () => { it('succ 10 is 11', () => {
expect($n(succ._(_n(10)))).toBe(11); expect($n(succ(_n(10)))).toBe(11);
}); });
}); });
describe('pred', () => { describe('pred', () => {
it('pred 0 is 0', () => { it('pred 0 is 0', () => {
expect($n(pred._(_n(0)))).toBe(0); expect($n(pred(_n(0)))).toBe(0);
}); });
it('pred 1 is 0', () => { it('pred 1 is 0', () => {
expect($n(pred._(_n(1)))).toBe(0); expect($n(pred(_n(1)))).toBe(0);
}); });
it('pred 10 is 9', () => { it('pred 10 is 9', () => {
expect($n(pred._(_n(10)))).toBe(9); expect($n(pred(_n(10)))).toBe(9);
}); });
}); });
describe('cmp', () => { describe('cmp', () => {
it('0 cmp 0 is EQ', () => { it('0 cmp 0 is EQ', () => {
expect($o(cmp._(_n(0))._(_n(0)))).toBe(NOrd.EQ); expect($o(cmp(_n(0))(_n(0)))).toBe(NOrd.EQ);
}); });
it('0 cmp 1 is LT', () => { it('0 cmp 1 is LT', () => {
expect($o(cmp._(_n(0))._(_n(1)))).toBe(NOrd.LT); expect($o(cmp(_n(0))(_n(1)))).toBe(NOrd.LT);
}); });
it('1 cmp 0 is GT', () => { it('1 cmp 0 is GT', () => {
expect($o(cmp._(_n(1))._(_n(0)))).toBe(NOrd.GT); expect($o(cmp(_n(1))(_n(0)))).toBe(NOrd.GT);
}); });
it('3 cmp 3 is EQ', () => { it('3 cmp 3 is EQ', () => {
expect($o(cmp._(_n(3))._(_n(3)))).toBe(NOrd.EQ); expect($o(cmp(_n(3))(_n(3)))).toBe(NOrd.EQ);
}); });
it('3 cmp 7 is LT', () => { it('3 cmp 7 is LT', () => {
expect($o(cmp._(_n(3))._(_n(7)))).toBe(NOrd.LT); expect($o(cmp(_n(3))(_n(7)))).toBe(NOrd.LT);
}); });
it('7 cmp 3 is GT', () => { it('7 cmp 3 is GT', () => {
expect($o(cmp._(_n(7))._(_n(3)))).toBe(NOrd.GT); expect($o(cmp(_n(7))(_n(3)))).toBe(NOrd.GT);
}); });
it('handles infinity', () => { it('handles infinity', () => {
expect($o(cmp._(_n(7))._(infinity))).toBe(NOrd.LT); expect($o(cmp(_n(7))(infinity))).toBe(NOrd.LT);
expect($o(cmp._(infinity)._(_n(7)))).toBe(NOrd.GT); expect($o(cmp(infinity)(_n(7)))).toBe(NOrd.GT);
}); });
}); });
describe('lt', () => { describe('lt', () => {
it('0 lt 0 is False', () => { it('0 lt 0 is False', () => {
expect($b(lt._(_n(0))._(_n(0)))).toBe(false); expect($b(lt(_n(0))(_n(0)))).toBe(false);
}); });
it('0 lt 1 is True', () => { it('0 lt 1 is True', () => {
expect($b(lt._(_n(0))._(_n(1)))).toBe(true); expect($b(lt(_n(0))(_n(1)))).toBe(true);
}); });
it('1 lt 0 is False', () => { it('1 lt 0 is False', () => {
expect($b(lt._(_n(1))._(_n(0)))).toBe(false); expect($b(lt(_n(1))(_n(0)))).toBe(false);
}); });
it('3 lt 3 is False', () => { it('3 lt 3 is False', () => {
expect($b(lt._(_n(3))._(_n(3)))).toBe(false); expect($b(lt(_n(3))(_n(3)))).toBe(false);
}); });
it('3 lt 7 is True', () => { it('3 lt 7 is True', () => {
expect($b(lt._(_n(3))._(_n(7)))).toBe(true); expect($b(lt(_n(3))(_n(7)))).toBe(true);
}); });
it('7 lt 3 is False', () => { it('7 lt 3 is False', () => {
expect($b(lt._(_n(7))._(_n(3)))).toBe(false); expect($b(lt(_n(7))(_n(3)))).toBe(false);
}); });
it('handles infinity', () => { it('handles infinity', () => {
expect($b(lt._(_n(7))._(infinity))).toBe(true); expect($b(lt(_n(7))(infinity))).toBe(true);
expect($b(lt._(infinity)._(_n(7)))).toBe(false); expect($b(lt(infinity)(_n(7)))).toBe(false);
}); });
}); });
describe('le', () => { describe('le', () => {
it('0 le 0 is True', () => { it('0 le 0 is True', () => {
expect($b(le._(_n(0))._(_n(0)))).toBe(true); expect($b(le(_n(0))(_n(0)))).toBe(true);
}); });
it('0 le 1 is True', () => { it('0 le 1 is True', () => {
expect($b(le._(_n(0))._(_n(1)))).toBe(true); expect($b(le(_n(0))(_n(1)))).toBe(true);
}); });
it('1 le 0 is False', () => { it('1 le 0 is False', () => {
expect($b(le._(_n(1))._(_n(0)))).toBe(false); expect($b(le(_n(1))(_n(0)))).toBe(false);
}); });
it('3 le 3 is True', () => { it('3 le 3 is True', () => {
expect($b(le._(_n(3))._(_n(3)))).toBe(true); expect($b(le(_n(3))(_n(3)))).toBe(true);
}); });
it('3 le 7 is True', () => { it('3 le 7 is True', () => {
expect($b(le._(_n(3))._(_n(7)))).toBe(true); expect($b(le(_n(3))(_n(7)))).toBe(true);
}); });
it('7 le 3 is False', () => { it('7 le 3 is False', () => {
expect($b(le._(_n(7))._(_n(3)))).toBe(false); expect($b(le(_n(7))(_n(3)))).toBe(false);
}); });
it('handles infinity', () => { it('handles infinity', () => {
expect($b(le._(_n(7))._(infinity))).toBe(true); expect($b(le(_n(7))(infinity))).toBe(true);
expect($b(le._(infinity)._(_n(7)))).toBe(false); expect($b(le(infinity)(_n(7)))).toBe(false);
}); });
}); });
describe('eq', () => { describe('eq', () => {
it('0 eq 0 is True', () => { it('0 eq 0 is True', () => {
expect($b(eq._(_n(0))._(_n(0)))).toBe(true); expect($b(eq(_n(0))(_n(0)))).toBe(true);
}); });
it('0 eq 1 is False', () => { it('0 eq 1 is False', () => {
expect($b(eq._(_n(0))._(_n(1)))).toBe(false); expect($b(eq(_n(0))(_n(1)))).toBe(false);
}); });
it('1 eq 0 is False', () => { it('1 eq 0 is False', () => {
expect($b(eq._(_n(1))._(_n(0)))).toBe(false); expect($b(eq(_n(1))(_n(0)))).toBe(false);
}); });
it('3 eq 3 is True', () => { it('3 eq 3 is True', () => {
expect($b(eq._(_n(3))._(_n(3)))).toBe(true); expect($b(eq(_n(3))(_n(3)))).toBe(true);
}); });
it('3 eq 7 is False', () => { it('3 eq 7 is False', () => {
expect($b(eq._(_n(3))._(_n(7)))).toBe(false); expect($b(eq(_n(3))(_n(7)))).toBe(false);
}); });
it('7 eq 3 is False', () => { it('7 eq 3 is False', () => {
expect($b(eq._(_n(7))._(_n(3)))).toBe(false); expect($b(eq(_n(7))(_n(3)))).toBe(false);
}); });
it('handles infinity', () => { it('handles infinity', () => {
expect($b(eq._(_n(7))._(infinity))).toBe(false); expect($b(eq(_n(7))(infinity))).toBe(false);
expect($b(eq._(infinity)._(_n(7)))).toBe(false); expect($b(eq(infinity)(_n(7)))).toBe(false);
}); });
}); });
describe('ge', () => { describe('ge', () => {
it('0 ge 0 is True', () => { it('0 ge 0 is True', () => {
expect($b(ge._(_n(0))._(_n(0)))).toBe(true); expect($b(ge(_n(0))(_n(0)))).toBe(true);
}); });
it('0 ge 1 is False', () => { it('0 ge 1 is False', () => {
expect($b(ge._(_n(0))._(_n(1)))).toBe(false); expect($b(ge(_n(0))(_n(1)))).toBe(false);
}); });
it('1 ge 0 is True', () => { it('1 ge 0 is True', () => {
expect($b(ge._(_n(1))._(_n(0)))).toBe(true); expect($b(ge(_n(1))(_n(0)))).toBe(true);
}); });
it('3 ge 3 is True', () => { it('3 ge 3 is True', () => {
expect($b(ge._(_n(3))._(_n(3)))).toBe(true); expect($b(ge(_n(3))(_n(3)))).toBe(true);
}); });
it('3 ge 7 is False', () => { it('3 ge 7 is False', () => {
expect($b(ge._(_n(3))._(_n(7)))).toBe(false); expect($b(ge(_n(3))(_n(7)))).toBe(false);
}); });
it('7 ge 3 is True', () => { it('7 ge 3 is True', () => {
expect($b(ge._(_n(7))._(_n(3)))).toBe(true); expect($b(ge(_n(7))(_n(3)))).toBe(true);
}); });
it('handles infinity', () => { it('handles infinity', () => {
expect($b(ge._(_n(7))._(infinity))).toBe(false); expect($b(ge(_n(7))(infinity))).toBe(false);
expect($b(ge._(infinity)._(_n(7)))).toBe(true); expect($b(ge(infinity)(_n(7)))).toBe(true);
}); });
}); });
describe('gt', () => { describe('gt', () => {
it('0 gt 0 is False', () => { it('0 gt 0 is False', () => {
expect($b(gt._(_n(0))._(_n(0)))).toBe(false); expect($b(gt(_n(0))(_n(0)))).toBe(false);
}); });
it('0 gt 1 is False', () => { it('0 gt 1 is False', () => {
expect($b(gt._(_n(0))._(_n(1)))).toBe(false); expect($b(gt(_n(0))(_n(1)))).toBe(false);
}); });
it('1 gt 0 is True', () => { it('1 gt 0 is True', () => {
expect($b(gt._(_n(1))._(_n(0)))).toBe(true); expect($b(gt(_n(1))(_n(0)))).toBe(true);
}); });
it('3 gt 3 is False', () => { it('3 gt 3 is False', () => {
expect($b(gt._(_n(3))._(_n(3)))).toBe(false); expect($b(gt(_n(3))(_n(3)))).toBe(false);
}); });
it('3 gt 7 is False', () => { it('3 gt 7 is False', () => {
expect($b(gt._(_n(3))._(_n(7)))).toBe(false); expect($b(gt(_n(3))(_n(7)))).toBe(false);
}); });
it('7 gt 3 is True', () => { it('7 gt 3 is True', () => {
expect($b(gt._(_n(7))._(_n(3)))).toBe(true); expect($b(gt(_n(7))(_n(3)))).toBe(true);
}); });
it('handles infinity', () => { it('handles infinity', () => {
expect($b(gt._(_n(7))._(infinity))).toBe(false); expect($b(gt(_n(7))(infinity))).toBe(false);
expect($b(gt._(infinity)._(_n(7)))).toBe(true); expect($b(gt(infinity)(_n(7)))).toBe(true);
}); });
}); });
describe('sum', () => { describe('sum', () => {
it('0 sum 0 is 0', () => { it('0 sum 0 is 0', () => {
expect($n(sum._(_n(0))._(_n(0)))).toBe(0); expect($n(sum(_n(0))(_n(0)))).toBe(0);
}); });
it('0 sum 1 is 1', () => { it('0 sum 1 is 1', () => {
expect($n(sum._(_n(0))._(_n(1)))).toBe(1); expect($n(sum(_n(0))(_n(1)))).toBe(1);
}); });
it('1 sum 0 is 1', () => { it('1 sum 0 is 1', () => {
expect($n(sum._(_n(1))._(_n(0)))).toBe(1); expect($n(sum(_n(1))(_n(0)))).toBe(1);
}); });
it('3 sum 4 is 7', () => { it('3 sum 4 is 7', () => {
expect($n(sum._(_n(3))._(_n(4)))).toBe(7); expect($n(sum(_n(3))(_n(4)))).toBe(7);
}); });
}); });
describe('sub', () => { describe('sub', () => {
it('0 sub 0 is 0', () => { it('0 sub 0 is 0', () => {
expect($n(sub._(_n(0))._(_n(0)))).toBe(0); expect($n(sub(_n(0))(_n(0)))).toBe(0);
}); });
it('0 sub 1 is 0', () => { it('0 sub 1 is 0', () => {
expect($n(sub._(_n(0))._(_n(1)))).toBe(0); expect($n(sub(_n(0))(_n(1)))).toBe(0);
}); });
it('1 sub 0 is 1', () => { it('1 sub 0 is 1', () => {
expect($n(sub._(_n(1))._(_n(0)))).toBe(1); expect($n(sub(_n(1))(_n(0)))).toBe(1);
}); });
it('7 sub 4 is 3', () => { it('7 sub 4 is 3', () => {
expect($n(sub._(_n(7))._(_n(4)))).toBe(3); expect($n(sub(_n(7))(_n(4)))).toBe(3);
}); });
}); });
describe('mul', () => { describe('mul', () => {
it('0 mul 0 is 0', () => { it('0 mul 0 is 0', () => {
expect($n(mul._(_n(0))._(_n(0)))).toBe(0); expect($n(mul(_n(0))(_n(0)))).toBe(0);
}); });
it('0 mul 10 is 0', () => { it('0 mul 10 is 0', () => {
expect($n(mul._(_n(0))._(_n(10)))).toBe(0); expect($n(mul(_n(0))(_n(10)))).toBe(0);
}); });
it('10 mul 0 is 0', () => { it('10 mul 0 is 0', () => {
expect($n(mul._(_n(1))._(_n(0)))).toBe(0); expect($n(mul(_n(1))(_n(0)))).toBe(0);
}); });
it('1 mul 10 is 10', () => { it('1 mul 10 is 10', () => {
expect($n(mul._(_n(1))._(_n(10)))).toBe(10); expect($n(mul(_n(1))(_n(10)))).toBe(10);
}); });
it('10 mul 1 is 10', () => { it('10 mul 1 is 10', () => {
expect($n(mul._(_n(10))._(_n(1)))).toBe(10); expect($n(mul(_n(10))(_n(1)))).toBe(10);
}); });
it('3 mul 4 is 12', () => { it('3 mul 4 is 12', () => {
expect($n(mul._(_n(3))._(_n(4)))).toBe(12); expect($n(mul(_n(3))(_n(4)))).toBe(12);
}); });
it('0 mul ignores second argument', () => { it('0 mul ignores second argument', () => {
expect($n(mul._(_n(0))._(undef))).toBe(0); expect($n(mul(_n(0))(undef))).toBe(0);
}); });
}); });
describe('div', () => { describe('div', () => {
it('0 div 10 is 0', () => { it('0 div 10 is 0', () => {
expect($n(div._(_n(0))._(_n(10)))).toBe(0); expect($n(div(_n(0))(_n(10)))).toBe(0);
}); });
it('1 div 10 is 0', () => { it('1 div 10 is 0', () => {
expect($n(div._(_n(1))._(_n(10)))).toBe(0); expect($n(div(_n(1))(_n(10)))).toBe(0);
}); });
it('10 div 1 is 10', () => { it('10 div 1 is 10', () => {
expect($n(div._(_n(10))._(_n(1)))).toBe(10); expect($n(div(_n(10))(_n(1)))).toBe(10);
}); });
it('10 div 5 is 2', () => { it('10 div 5 is 2', () => {
expect($n(div._(_n(10))._(_n(5)))).toBe(2); expect($n(div(_n(10))(_n(5)))).toBe(2);
}); });
it('10 div 3 is 3', () => { it('10 div 3 is 3', () => {
expect($n(div._(_n(10))._(_n(3)))).toBe(3); expect($n(div(_n(10))(_n(3)))).toBe(3);
}); });
it.failing('0 div ignores second argument', () => { it.failing('0 div ignores second argument', () => {
expect($n(div._(_n(0))._(undef))).toBe(0); expect($n(div(_n(0))(undef))).toBe(0);
}); });
}); });
describe('mod', () => { describe('mod', () => {
it('0 mod 10 is 0', () => { it('0 mod 10 is 0', () => {
expect($n(mod._(_n(0))._(_n(10)))).toBe(0); expect($n(mod(_n(0))(_n(10)))).toBe(0);
}); });
it('1 mod 10 is 1', () => { it('1 mod 10 is 1', () => {
expect($n(mod._(_n(1))._(_n(10)))).toBe(1); expect($n(mod(_n(1))(_n(10)))).toBe(1);
}); });
it('10 mod 1 is 0', () => { it('10 mod 1 is 0', () => {
expect($n(mod._(_n(10))._(_n(1)))).toBe(0); expect($n(mod(_n(10))(_n(1)))).toBe(0);
}); });
it('10 mod 5 is 0', () => { it('10 mod 5 is 0', () => {
expect($n(mod._(_n(10))._(_n(5)))).toBe(0); expect($n(mod(_n(10))(_n(5)))).toBe(0);
}); });
it('10 mod 3 is 1', () => { it('10 mod 3 is 1', () => {
expect($n(mod._(_n(10))._(_n(3)))).toBe(1); expect($n(mod(_n(10))(_n(3)))).toBe(1);
}); });
it.failing('0 mod ignores second argument', () => { it.failing('0 mod ignores second argument', () => {
expect($n(mod._(_n(0))._(undef))).toBe(0); expect($n(mod(_n(0))(undef))).toBe(0);
}); });
}); });
describe('show', () => { describe('show', () => {
it('show 0 is "0"', () => { it('show 0 is "0"', () => {
expect($s(show._(_n(0)))).toBe('0'); expect($s(show(_n(0)))).toBe('0');
}); });
it('show 1 is "1"', () => { it('show 1 is "1"', () => {
expect($s(show._(_n(1)))).toBe('1'); expect($s(show(_n(1)))).toBe('1');
}); });
it('show 255 is "255"', () => { it('show 255 is "255"', () => {
expect($s(show._(_n(255)))).toBe('255'); expect($s(show(_n(255)))).toBe('255');
}); });
it('show 1000 is "1000"', () => { it('show 1000 is "1000"', () => {
expect($s(show._(_n(1000)))).toBe('1000'); expect($s(show(_n(1000)))).toBe('1000');
}); });
}); });
}); });

@ -9,222 +9,222 @@ import { toString as $s } from '../src/string';
describe('Pair', () => { describe('Pair', () => {
describe('fst', () => { describe('fst', () => {
it('returns first', () => { it('returns first', () => {
expect($b(fst._(Pair._(_b(false))._(_n(0))))).toBe(false); expect($b(fst(Pair(_b(false))(_n(0))))).toBe(false);
}); });
it('ignores second', () => { it('ignores second', () => {
expect($b(fst._(Pair._(_b(false))._(undef)))).toBe(false); expect($b(fst(Pair(_b(false))(undef)))).toBe(false);
}); });
}); });
describe('snd', () => { describe('snd', () => {
it('returns second', () => { it('returns second', () => {
expect($n(snd._(Pair._(_b(false))._(_n(0))))).toBe(0); expect($n(snd(Pair(_b(false))(_n(0))))).toBe(0);
}); });
it('ignores first', () => { it('ignores first', () => {
expect($n(snd._(Pair._(undef)._(_n(0))))).toBe(0); expect($n(snd(Pair(undef)(_n(0))))).toBe(0);
}); });
}); });
describe('first', () => { describe('first', () => {
it('updates first', () => { it('updates first', () => {
expect($b(fst._(first._(not)._(Pair._(_b(false))._(_n(0)))))).toBe(true); expect($b(fst(first(not)(Pair(_b(false))(_n(0)))))).toBe(true);
}); });
it('ignores second', () => { it('ignores second', () => {
expect($b(fst._(first._(not)._(Pair._(_b(false))._(undef))))).toBe(true); expect($b(fst(first(not)(Pair(_b(false))(undef))))).toBe(true);
}); });
}); });
describe('second', () => { describe('second', () => {
it('updates second', () => { it('updates second', () => {
expect($n(snd._(second._(succ)._(Pair._(_b(false))._(_n(0)))))).toBe(1); expect($n(snd(second(succ)(Pair(_b(false))(_n(0)))))).toBe(1);
}); });
it('ignores first', () => { it('ignores first', () => {
expect($n(snd._(second._(succ)._(Pair._(undef)._(_n(0)))))).toBe(1); expect($n(snd(second(succ)(Pair(undef)(_n(0)))))).toBe(1);
}); });
}); });
describe('both', () => { describe('both', () => {
it('updates both', () => { it('updates both', () => {
expect($b(fst._(both._(not)._(succ)._(Pair._(_b(false))._(_n(0)))))).toBe(true); expect($b(fst(both(not)(succ)(Pair(_b(false))(_n(0)))))).toBe(true);
expect($n(snd._(both._(not)._(succ)._(Pair._(_b(false))._(_n(0)))))).toBe(1); expect($n(snd(both(not)(succ)(Pair(_b(false))(_n(0)))))).toBe(1);
}); });
}); });
describe('cmp', () => { describe('cmp', () => {
it('(False, 0) cmp (False, 0) is EQ', () => { it('(False, 0) cmp (False, 0) is EQ', () => {
expect($o(cmp._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(NOrd.EQ); expect($o(cmp(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(NOrd.EQ);
}); });
it('(False, 0) cmp (False, 1) is LT', () => { it('(False, 0) cmp (False, 1) is LT', () => {
expect($o(cmp._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(1))))).toBe(NOrd.LT); expect($o(cmp(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(1))))).toBe(NOrd.LT);
}); });
it('(False, 1) cmp (False, 0) is GT', () => { it('(False, 1) cmp (False, 0) is GT', () => {
expect($o(cmp._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(1)))._(Pair._(_b(false))._(_n(0))))).toBe(NOrd.GT); expect($o(cmp(bcmp)(ncmp)(Pair(_b(false))(_n(1)))(Pair(_b(false))(_n(0))))).toBe(NOrd.GT);
}); });
it('(False, 0) cmp (True, 0) is LT', () => { it('(False, 0) cmp (True, 0) is LT', () => {
expect($o(cmp._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(true))._(_n(0))))).toBe(NOrd.LT); expect($o(cmp(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(true))(_n(0))))).toBe(NOrd.LT);
}); });
it('(True, 0) cmp (False, 0) is GT', () => { it('(True, 0) cmp (False, 0) is GT', () => {
expect($o(cmp._(bcmp)._(ncmp)._(Pair._(_b(true))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(NOrd.GT); expect($o(cmp(bcmp)(ncmp)(Pair(_b(true))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(NOrd.GT);
}); });
it('ignores second if first not equal', () => { it('ignores second if first not equal', () => {
expect($o(cmp._(bcmp)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(NOrd.LT); expect($o(cmp(bcmp)(undef)(Pair(_b(false))(undef))(Pair(_b(true))(undef)))).toBe(NOrd.LT);
}); });
}); });
describe('lt', () => { describe('lt', () => {
it('(False, 0) lt (False, 0) is False', () => { it('(False, 0) lt (False, 0) is False', () => {
expect($b(lt._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(false); expect($b(lt(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(false);
}); });
it('(False, 0) lt (False, 1) is True', () => { it('(False, 0) lt (False, 1) is True', () => {
expect($b(lt._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(1))))).toBe(true); expect($b(lt(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(1))))).toBe(true);
}); });
it('(False, 1) lt (False, 0) is False', () => { it('(False, 1) lt (False, 0) is False', () => {
expect($b(lt._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(1)))._(Pair._(_b(false))._(_n(0))))).toBe(false); expect($b(lt(bcmp)(ncmp)(Pair(_b(false))(_n(1)))(Pair(_b(false))(_n(0))))).toBe(false);
}); });
it('(False, 0) lt (True, 0) is True', () => { it('(False, 0) lt (True, 0) is True', () => {
expect($b(lt._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(true))._(_n(0))))).toBe(true); expect($b(lt(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(true))(_n(0))))).toBe(true);
}); });
it('(True, 0) lt (False, 0) is False', () => { it('(True, 0) lt (False, 0) is False', () => {
expect($b(lt._(bcmp)._(ncmp)._(Pair._(_b(true))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(false); expect($b(lt(bcmp)(ncmp)(Pair(_b(true))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(false);
}); });
it('ignores second if first not equal', () => { it('ignores second if first not equal', () => {
expect($b(lt._(bcmp)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(true); expect($b(lt(bcmp)(undef)(Pair(_b(false))(undef))(Pair(_b(true))(undef)))).toBe(true);
}); });
}); });
describe('le', () => { describe('le', () => {
it('(False, 0) le (False, 0) is True', () => { it('(False, 0) le (False, 0) is True', () => {
expect($b(le._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(true); expect($b(le(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(true);
}); });
it('(False, 0) le (False, 1) is True', () => { it('(False, 0) le (False, 1) is True', () => {
expect($b(le._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(1))))).toBe(true); expect($b(le(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(1))))).toBe(true);
}); });
it('(False, 1) le (False, 0) is False', () => { it('(False, 1) le (False, 0) is False', () => {
expect($b(le._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(1)))._(Pair._(_b(false))._(_n(0))))).toBe(false); expect($b(le(bcmp)(ncmp)(Pair(_b(false))(_n(1)))(Pair(_b(false))(_n(0))))).toBe(false);
}); });
it('(False, 0) le (True, 0) is True', () => { it('(False, 0) le (True, 0) is True', () => {
expect($b(le._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(true))._(_n(0))))).toBe(true); expect($b(le(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(true))(_n(0))))).toBe(true);
}); });
it('(True, 0) le (False, 0) is False', () => { it('(True, 0) le (False, 0) is False', () => {
expect($b(le._(bcmp)._(ncmp)._(Pair._(_b(true))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(false); expect($b(le(bcmp)(ncmp)(Pair(_b(true))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(false);
}); });
it('ignores second if first not equal', () => { it('ignores second if first not equal', () => {
expect($b(le._(bcmp)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(true); expect($b(le(bcmp)(undef)(Pair(_b(false))(undef))(Pair(_b(true))(undef)))).toBe(true);
}); });
}); });
describe('eq', () => { describe('eq', () => {
it('(False, 0) eq (False, 0) is True', () => { it('(False, 0) eq (False, 0) is True', () => {
expect($b(eq._(beq)._(neq)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(true); expect($b(eq(beq)(neq)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(true);
}); });
it('(False, 0) eq (False, 1) is False', () => { it('(False, 0) eq (False, 1) is False', () => {
expect($b(eq._(beq)._(neq)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(1))))).toBe(false); expect($b(eq(beq)(neq)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(1))))).toBe(false);
}); });
it('(False, 1) eq (False, 0) is False', () => { it('(False, 1) eq (False, 0) is False', () => {
expect($b(eq._(beq)._(neq)._(Pair._(_b(false))._(_n(1)))._(Pair._(_b(false))._(_n(0))))).toBe(false); expect($b(eq(beq)(neq)(Pair(_b(false))(_n(1)))(Pair(_b(false))(_n(0))))).toBe(false);
}); });
it('(False, 0) eq (True, 0) is True', () => { it('(False, 0) eq (True, 0) is True', () => {
expect($b(eq._(beq)._(neq)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(true))._(_n(0))))).toBe(false); expect($b(eq(beq)(neq)(Pair(_b(false))(_n(0)))(Pair(_b(true))(_n(0))))).toBe(false);
}); });
it('(True, 0) eq (False, 0) is True', () => { it('(True, 0) eq (False, 0) is True', () => {
expect($b(eq._(beq)._(neq)._(Pair._(_b(true))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(false); expect($b(eq(beq)(neq)(Pair(_b(true))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(false);
}); });
it('ignores second if first not equal', () => { it('ignores second if first not equal', () => {
expect($b(eq._(beq)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(false); expect($b(eq(beq)(undef)(Pair(_b(false))(undef))(Pair(_b(true))(undef)))).toBe(false);
}); });
}); });
describe('ge', () => { describe('ge', () => {
it('(False, 0) ge (False, 0) is True', () => { it('(False, 0) ge (False, 0) is True', () => {
expect($b(ge._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(true); expect($b(ge(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(true);
}); });
it('(False, 0) ge (False, 1) is False', () => { it('(False, 0) ge (False, 1) is False', () => {
expect($b(ge._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(1))))).toBe(false); expect($b(ge(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(1))))).toBe(false);
}); });
it('(False, 1) ge (False, 0) is True', () => { it('(False, 1) ge (False, 0) is True', () => {
expect($b(ge._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(1)))._(Pair._(_b(false))._(_n(0))))).toBe(true); expect($b(ge(bcmp)(ncmp)(Pair(_b(false))(_n(1)))(Pair(_b(false))(_n(0))))).toBe(true);
}); });
it('(False, 0) ge (True, 0) is False', () => { it('(False, 0) ge (True, 0) is False', () => {
expect($b(ge._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(true))._(_n(0))))).toBe(false); expect($b(ge(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(true))(_n(0))))).toBe(false);
}); });
it('(True, 0) ge (False, 0) is True', () => { it('(True, 0) ge (False, 0) is True', () => {
expect($b(ge._(bcmp)._(ncmp)._(Pair._(_b(true))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(true); expect($b(ge(bcmp)(ncmp)(Pair(_b(true))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(true);
}); });
it('ignores second if first not equal', () => { it('ignores second if first not equal', () => {
expect($b(ge._(bcmp)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(false); expect($b(ge(bcmp)(undef)(Pair(_b(false))(undef))(Pair(_b(true))(undef)))).toBe(false);
}); });
}); });
describe('gt', () => { describe('gt', () => {
it('(False, 0) gt (False, 0) is False', () => { it('(False, 0) gt (False, 0) is False', () => {
expect($b(gt._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(false); expect($b(gt(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(false);
}); });
it('(False, 0) gt (False, 1) is False', () => { it('(False, 0) gt (False, 1) is False', () => {
expect($b(gt._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(false))._(_n(1))))).toBe(false); expect($b(gt(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(false))(_n(1))))).toBe(false);
}); });
it('(False, 1) gt (False, 0) is True', () => { it('(False, 1) gt (False, 0) is True', () => {
expect($b(gt._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(1)))._(Pair._(_b(false))._(_n(0))))).toBe(true); expect($b(gt(bcmp)(ncmp)(Pair(_b(false))(_n(1)))(Pair(_b(false))(_n(0))))).toBe(true);
}); });
it('(False, 0) gt (True, 0) is False', () => { it('(False, 0) gt (True, 0) is False', () => {
expect($b(gt._(bcmp)._(ncmp)._(Pair._(_b(false))._(_n(0)))._(Pair._(_b(true))._(_n(0))))).toBe(false); expect($b(gt(bcmp)(ncmp)(Pair(_b(false))(_n(0)))(Pair(_b(true))(_n(0))))).toBe(false);
}); });
it('(True, 0) gt (False, 0) is True', () => { it('(True, 0) gt (False, 0) is True', () => {
expect($b(gt._(bcmp)._(ncmp)._(Pair._(_b(true))._(_n(0)))._(Pair._(_b(false))._(_n(0))))).toBe(true); expect($b(gt(bcmp)(ncmp)(Pair(_b(true))(_n(0)))(Pair(_b(false))(_n(0))))).toBe(true);
}); });
it('ignores second if first not equal', () => { it('ignores second if first not equal', () => {
expect($b(gt._(bcmp)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(false); expect($b(gt(bcmp)(undef)(Pair(_b(false))(undef))(Pair(_b(true))(undef)))).toBe(false);
}); });
}); });
describe('show', () => { describe('show', () => {
it('show (False, 0) is "(False, 0)"', () => { it('show (False, 0) is "(False, 0)"', () => {
expect($s(show._(bshow)._(nshow)._(Pair._(_b(false))._(_n(0))))).toBe('(False, 0)'); expect($s(show(bshow)(nshow)(Pair(_b(false))(_n(0))))).toBe('(False, 0)');
}); });
it('show (False, 1) is "(False, 1)"', () => { it('show (False, 1) is "(False, 1)"', () => {
expect($s(show._(bshow)._(nshow)._(Pair._(_b(false))._(_n(1))))).toBe('(False, 1)'); expect($s(show(bshow)(nshow)(Pair(_b(false))(_n(1))))).toBe('(False, 1)');
}); });
it('show (True, 0) is "(True, 0)"', () => { it('show (True, 0) is "(True, 0)"', () => {
expect($s(show._(bshow)._(nshow)._(Pair._(_b(true))._(_n(0))))).toBe('(True, 0)'); expect($s(show(bshow)(nshow)(Pair(_b(true))(_n(0))))).toBe('(True, 0)');
}); });
it('show (True, 1) is "(True, 1)"', () => { it('show (True, 1) is "(True, 1)"', () => {
expect($s(show._(bshow)._(nshow)._(Pair._(_b(true))._(_n(1))))).toBe('(True, 1)'); expect($s(show(bshow)(nshow)(Pair(_b(true))(_n(1))))).toBe('(True, 1)');
}); });
}); });
}); });

@ -1,13 +1,13 @@
import { describe, expect, it } from '@jest/globals'; import { describe, expect, it } from '@jest/globals';
import { L, _, undef } from '../src/core'; import { L, _, ___, undef } from '../src/core';
import { NOrd, toNOrd } from '../src/ord'; import { NOrd, toNOrd } from '../src/ord';
import { toBoolean as $b } from '../src/bool'; import { toBoolean as $b } from '../src/bool';
import { toNumber as $n, Zero, gt as ngt } from '../src/num'; import { toNumber as $n, Zero, gt as ngt } from '../src/num';
import { toChar as $c, fromChar as _c } from '../src/char'; import { toChar as $c, fromChar as _c } from '../src/char';
import { toString as $s, Cons, Empty, String, fromString as _s, append, cmp, empty, eq, ge, gt, le, len, lt, show } from '../src/string'; import { toString as $s, Cons, Empty, String, fromString as _s, append, cmp, empty, eq, ge, gt, le, len, lt, show, wrap } from '../src/string';
describe('String', () => { describe('String', () => {
const infinite: String = Cons._(_c('a'))._(new L(() => infinite.value)); const infinite: String = Cons(_c('a'))(___(() => infinite.run()));
describe('toString', () => { describe('toString', () => {
it('converts ""', () => { it('converts ""', () => {
@ -15,11 +15,11 @@ describe('String', () => {
}); });
it('converts "a"', () => { it('converts "a"', () => {
expect($s(Cons._(_c('a'))._(Empty))).toBe('a'); expect($s(Cons(_c('a'))(Empty))).toBe('a');
}); });
it('converts "abc"', () => { it('converts "abc"', () => {
expect($s(Cons._(_c('a'))._(Cons._(_c('b'))._(Cons._(_c('c'))._(Empty))))).toBe('abc'); expect($s(Cons(_c('a'))(Cons(_c('b'))(Cons(_c('c'))(Empty))))).toBe('abc');
}); });
}); });
@ -40,321 +40,335 @@ describe('String', () => {
// describe('repeat', () => { // describe('repeat', () => {
// it('repeat "a" is "aaa..."', () => { // it('repeat "a" is "aaa..."', () => {
// expect($na( // expect($na(
// repeat._(_s('a'))._<String>(_((x0: Char) => _((x1s: String) => // repeat(_s('a'))<String>(_((x0: Char) => _((x1s: String) =>
// x1s._<String>(_((x1: Char) => _((x2s: String) => // x1s<String>(_((x1: Char) => _((x2s: String) =>
// x2s._<String>(_((x2: Char) => _((_xrs: String): String => cons._(x0)._(cons._(x1)._(cons._(x2)._(Nil)))))))))))))).toEqual('aaa'); // x2s<String>(_((x2: Char) => _((_xrs: String): String => cons(x0)(cons(x1)(cons(x2)(Nil)))))))))))))).toEqual('aaa');
// }); // });
// }); // });
// describe('iterate', () => { // describe('iterate', () => {
// it('iterate succ "a" is "abc..."', () => { // it('iterate succ "a" is "abc..."', () => {
// expect($na( // expect($na(
// iterate._(_s('a'))._<String>(_((x0: Char) => _((x1s: String) => // iterate(_s('a'))<String>(_((x0: Char) => _((x1s: String) =>
// x1s._<String>(_((x1: Char) => _((x2s: String) => // x1s<String>(_((x1: Char) => _((x2s: String) =>
// x2s._<String>(_((x2: Char) => _((_xrs: String): String => cons._(x0)._(cons._(x1)._(cons._(x2)._(Nil)))))))))))))).toEqual('abc'); // x2s<String>(_((x2: Char) => _((_xrs: String): String => cons(x0)(cons(x1)(cons(x2)(Nil)))))))))))))).toEqual('abc');
// }); // });
// }); // });
describe('empty', () => { describe('empty', () => {
it('empty "" is True', () => { it('empty "" is True', () => {
expect($b(empty._(_s('')))).toEqual(true); expect($b(empty(_s('')))).toEqual(true);
}); });
it('empty "a" is False', () => { it('empty "a" is False', () => {
expect($b(empty._(_s('a')))).toEqual(false); expect($b(empty(_s('a')))).toEqual(false);
}); });
it('empty "ab" is False', () => { it('empty "ab" is False', () => {
expect($b(empty._(_s('ab')))).toEqual(false); expect($b(empty(_s('ab')))).toEqual(false);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($b(empty._(infinite))).toEqual(false); expect($b(empty(infinite))).toEqual(false);
}); });
}); });
describe('len', () => { describe('len', () => {
it('len "" is 0', () => { it('len "" is 0', () => {
expect($n(len._(_s('')))).toEqual(0); expect($n(len(_s('')))).toEqual(0);
}); });
it('len "a" is 1', () => { it('len "a" is 1', () => {
expect($n(len._(_s('a')))).toEqual(1); expect($n(len(_s('a')))).toEqual(1);
}); });
it('len "ab" is 2', () => { it('len "ab" is 2', () => {
expect($n(len._(_s('ab')))).toEqual(2); expect($n(len(_s('ab')))).toEqual(2);
}); });
it('handles infinite lists', () => { it('handles infinite lists', () => {
expect($b(ngt._(len._(infinite))._(Zero))).toEqual(true); expect($b(ngt(len(infinite))(Zero))).toEqual(true);
}); });
}); });
describe('append', () => { describe('append', () => {
it('"" append "" is ""', () => { it('"" append "" is ""', () => {
expect($s(append._(Empty)._(Empty))).toBe(''); expect($s(append(Empty)(Empty))).toBe('');
}); });
it('"a" append "b" is "ab"', () => { it('"a" append "b" is "ab"', () => {
expect($s(append._(_s('a'))._(_s('b')))).toBe('ab'); expect($s(append(_s('a'))(_s('b')))).toBe('ab');
}); });
it('"abc" append "def" is "abcdef"', () => { it('"abc" append "def" is "abcdef"', () => {
expect($s(append._(_s('abc'))._(_s('def')))).toBe('abcdef'); expect($s(append(_s('abc'))(_s('def')))).toBe('abcdef');
}); });
it('handles infinite strings', () => { it('handles infinite strings', () => {
expect($c(append._(infinite)._(infinite)._(undef)._(_(x => _(_xs => x))))).toBe('a'); expect($c(append(infinite)(infinite)(undef)(_(x => _(_xs => x))))).toBe('a');
});
});
describe('wrap', () => {
it('"" wrap "" is ""', () => {
expect($s(wrap(Empty)(Empty))).toBe('');
});
it('"a" wrap "b" is "aba"', () => {
expect($s(wrap(_s('a'))(_s('b')))).toBe('aba');
});
it('handles infinite strings', () => {
expect($c(wrap(infinite)(infinite)(undef)(_(x => _(_xs => x))))).toBe('a');
}); });
}); });
describe('cmp', () => { describe('cmp', () => {
it('"" cmp "" is EQ', () => { it('"" cmp "" is EQ', () => {
expect(toNOrd(cmp._(_s(''))._(_s('')))).toEqual(NOrd.EQ); expect(toNOrd(cmp(_s(''))(_s('')))).toEqual(NOrd.EQ);
}); });
it('"" cmp "abc" is LT', () => { it('"" cmp "abc" is LT', () => {
expect(toNOrd(cmp._(_s(''))._(_s('abc')))).toEqual(NOrd.LT); expect(toNOrd(cmp(_s(''))(_s('abc')))).toEqual(NOrd.LT);
}); });
it('"abc" cmp "" is GT', () => { it('"abc" cmp "" is GT', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('')))).toEqual(NOrd.GT); expect(toNOrd(cmp(_s('abc'))(_s('')))).toEqual(NOrd.GT);
}); });
it('"a" cmp "abc" is LT', () => { it('"a" cmp "abc" is LT', () => {
expect(toNOrd(cmp._(_s('a'))._(_s('abc')))).toEqual(NOrd.LT); expect(toNOrd(cmp(_s('a'))(_s('abc')))).toEqual(NOrd.LT);
}); });
it('"abc" cmp "a" is GT', () => { it('"abc" cmp "a" is GT', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('a')))).toEqual(NOrd.GT); expect(toNOrd(cmp(_s('abc'))(_s('a')))).toEqual(NOrd.GT);
}); });
it('"bca" cmp "abc" is GT', () => { it('"bca" cmp "abc" is GT', () => {
expect(toNOrd(cmp._(_s('bca'))._(_s('abc')))).toEqual(NOrd.GT); expect(toNOrd(cmp(_s('bca'))(_s('abc')))).toEqual(NOrd.GT);
}); });
it('"abc" cmp "bca" is LT', () => { it('"abc" cmp "bca" is LT', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('bca')))).toEqual(NOrd.LT); expect(toNOrd(cmp(_s('abc'))(_s('bca')))).toEqual(NOrd.LT);
}); });
it('"abc" cmp "abc" is EQ', () => { it('"abc" cmp "abc" is EQ', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('abc')))).toEqual(NOrd.EQ); expect(toNOrd(cmp(_s('abc'))(_s('abc')))).toEqual(NOrd.EQ);
}); });
it('handles infinite strings', () => { it('handles infinite strings', () => {
expect(toNOrd(cmp._(_s('abc'))._(infinite))).toEqual(NOrd.GT); expect(toNOrd(cmp(_s('abc'))(infinite))).toEqual(NOrd.GT);
expect(toNOrd(cmp._(infinite)._(_s('abc')))).toEqual(NOrd.LT); expect(toNOrd(cmp(infinite)(_s('abc')))).toEqual(NOrd.LT);
}); });
}); });
describe('lt', () => { describe('lt', () => {
it('"" lt "" is False', () => { it('"" lt "" is False', () => {
expect($b(lt._(_s(''))._(_s('')))).toEqual(false); expect($b(lt(_s(''))(_s('')))).toEqual(false);
}); });
it('"" lt "abc" is True', () => { it('"" lt "abc" is True', () => {
expect($b(lt._(_s(''))._(_s('abc')))).toEqual(true); expect($b(lt(_s(''))(_s('abc')))).toEqual(true);
}); });
it('"abc" lt "" is False', () => { it('"abc" lt "" is False', () => {
expect($b(lt._(_s('abc'))._(_s('')))).toEqual(false); expect($b(lt(_s('abc'))(_s('')))).toEqual(false);
}); });
it('"a" lt "abc" is True', () => { it('"a" lt "abc" is True', () => {
expect($b(lt._(_s('a'))._(_s('abc')))).toEqual(true); expect($b(lt(_s('a'))(_s('abc')))).toEqual(true);
}); });
it('"abc" lt "a" is False', () => { it('"abc" lt "a" is False', () => {
expect($b(lt._(_s('abc'))._(_s('a')))).toEqual(false); expect($b(lt(_s('abc'))(_s('a')))).toEqual(false);
}); });
it('"bca" lt "abc" is False', () => { it('"bca" lt "abc" is False', () => {
expect($b(lt._(_s('bca'))._(_s('abc')))).toEqual(false); expect($b(lt(_s('bca'))(_s('abc')))).toEqual(false);
}); });
it('"abc" lt "bca" is True', () => { it('"abc" lt "bca" is True', () => {
expect($b(lt._(_s('abc'))._(_s('bca')))).toEqual(true); expect($b(lt(_s('abc'))(_s('bca')))).toEqual(true);
}); });
it('"abc" lt "abc" is False', () => { it('"abc" lt "abc" is False', () => {
expect($b(lt._(_s('abc'))._(_s('abc')))).toEqual(false); expect($b(lt(_s('abc'))(_s('abc')))).toEqual(false);
}); });
it('handles infinite strings', () => { it('handles infinite strings', () => {
expect($b(lt._(_s('abc'))._(infinite))).toEqual(false); expect($b(lt(_s('abc'))(infinite))).toEqual(false);
expect($b(lt._(infinite)._(_s('abc')))).toEqual(true); expect($b(lt(infinite)(_s('abc')))).toEqual(true);
}); });
}); });
describe('le', () => { describe('le', () => {
it('"" le "" is True', () => { it('"" le "" is True', () => {
expect($b(le._(_s(''))._(_s('')))).toEqual(true); expect($b(le(_s(''))(_s('')))).toEqual(true);
}); });
it('"" le "abc" is True', () => { it('"" le "abc" is True', () => {
expect($b(le._(_s(''))._(_s('abc')))).toEqual(true); expect($b(le(_s(''))(_s('abc')))).toEqual(true);
}); });
it('"abc" le "" is False', () => { it('"abc" le "" is False', () => {
expect($b(le._(_s('abc'))._(_s('')))).toEqual(false); expect($b(le(_s('abc'))(_s('')))).toEqual(false);
}); });
it('"a" le "abc" is True', () => { it('"a" le "abc" is True', () => {
expect($b(le._(_s('a'))._(_s('abc')))).toEqual(true); expect($b(le(_s('a'))(_s('abc')))).toEqual(true);
}); });
it('"abc" le "a" is False', () => { it('"abc" le "a" is False', () => {
expect($b(le._(_s('abc'))._(_s('a')))).toEqual(false); expect($b(le(_s('abc'))(_s('a')))).toEqual(false);
}); });
it('"bca" le "abc" is False', () => { it('"bca" le "abc" is False', () => {
expect($b(le._(_s('bca'))._(_s('abc')))).toEqual(false); expect($b(le(_s('bca'))(_s('abc')))).toEqual(false);
}); });
it('"abc" le "bca" is True', () => { it('"abc" le "bca" is True', () => {
expect($b(le._(_s('abc'))._(_s('bca')))).toEqual(true); expect($b(le(_s('abc'))(_s('bca')))).toEqual(true);
}); });
it('"abc" le "abc" is True', () => { it('"abc" le "abc" is True', () => {
expect($b(le._(_s('abc'))._(_s('abc')))).toEqual(true); expect($b(le(_s('abc'))(_s('abc')))).toEqual(true);
}); });
it('handles infinite strings', () => { it('handles infinite strings', () => {
expect($b(le._(_s('abc'))._(infinite))).toEqual(false); expect($b(le(_s('abc'))(infinite))).toEqual(false);
expect($b(le._(infinite)._(_s('abc')))).toEqual(true); expect($b(le(infinite)(_s('abc')))).toEqual(true);
}); });
}); });
describe('eq', () => { describe('eq', () => {
it('"" eq "" is True', () => { it('"" eq "" is True', () => {
expect($b(eq._(_s(''))._(_s('')))).toEqual(true); expect($b(eq(_s(''))(_s('')))).toEqual(true);
}); });
it('"" eq "abc" is False', () => { it('"" eq "abc" is False', () => {
expect($b(eq._(_s(''))._(_s('abc')))).toEqual(false); expect($b(eq(_s(''))(_s('abc')))).toEqual(false);
}); });
it('"abc" eq "" is False', () => { it('"abc" eq "" is False', () => {
expect($b(eq._(_s('abc'))._(_s('')))).toEqual(false); expect($b(eq(_s('abc'))(_s('')))).toEqual(false);
}); });
it('"a" eq "abc" is False', () => { it('"a" eq "abc" is False', () => {
expect($b(eq._(_s('a'))._(_s('abc')))).toEqual(false); expect($b(eq(_s('a'))(_s('abc')))).toEqual(false);
}); });
it('"abc" eq "a" is False', () => { it('"abc" eq "a" is False', () => {
expect($b(eq._(_s('abc'))._(_s('a')))).toEqual(false); expect($b(eq(_s('abc'))(_s('a')))).toEqual(false);
}); });
it('"bca" eq "abc" is False', () => { it('"bca" eq "abc" is False', () => {
expect($b(eq._(_s('bca'))._(_s('abc')))).toEqual(false); expect($b(eq(_s('bca'))(_s('abc')))).toEqual(false);
}); });
it('"abc" eq "bca" is False', () => { it('"abc" eq "bca" is False', () => {
expect($b(eq._(_s('abc'))._(_s('bca')))).toEqual(false); expect($b(eq(_s('abc'))(_s('bca')))).toEqual(false);
}); });
it('"abc" eq "abc" is True', () => { it('"abc" eq "abc" is True', () => {
expect($b(eq._(_s('abc'))._(_s('abc')))).toEqual(true); expect($b(eq(_s('abc'))(_s('abc')))).toEqual(true);
}); });
it('handles infinite strings', () => { it('handles infinite strings', () => {
expect($b(eq._(_s('abc'))._(infinite))).toEqual(false); expect($b(eq(_s('abc'))(infinite))).toEqual(false);
expect($b(eq._(infinite)._(_s('abc')))).toEqual(false); expect($b(eq(infinite)(_s('abc')))).toEqual(false);
}); });
}); });
describe('ge', () => { describe('ge', () => {
it('"" ge "" is True', () => { it('"" ge "" is True', () => {
expect($b(ge._(_s(''))._(_s('')))).toEqual(true); expect($b(ge(_s(''))(_s('')))).toEqual(true);
}); });
it('"" ge "abc" is False', () => { it('"" ge "abc" is False', () => {
expect($b(ge._(_s(''))._(_s('abc')))).toEqual(false); expect($b(ge(_s(''))(_s('abc')))).toEqual(false);
}); });
it('"abc" ge "" is True', () => { it('"abc" ge "" is True', () => {
expect($b(ge._(_s('abc'))._(_s('')))).toEqual(true); expect($b(ge(_s('abc'))(_s('')))).toEqual(true);
}); });
it('"a" ge "abc" is False', () => { it('"a" ge "abc" is False', () => {
expect($b(ge._(_s('a'))._(_s('abc')))).toEqual(false); expect($b(ge(_s('a'))(_s('abc')))).toEqual(false);
}); });
it('"abc" ge "a" is True', () => { it('"abc" ge "a" is True', () => {
expect($b(ge._(_s('abc'))._(_s('a')))).toEqual(true); expect($b(ge(_s('abc'))(_s('a')))).toEqual(true);
}); });
it('"bca" ge "abc" is True', () => { it('"bca" ge "abc" is True', () => {
expect($b(ge._(_s('bca'))._(_s('abc')))).toEqual(true); expect($b(ge(_s('bca'))(_s('abc')))).toEqual(true);
}); });
it('"abc" ge "bca" is False', () => { it('"abc" ge "bca" is False', () => {
expect($b(ge._(_s('abc'))._(_s('bca')))).toEqual(false); expect($b(ge(_s('abc'))(_s('bca')))).toEqual(false);
}); });
it('"abc" ge "abc" is True', () => { it('"abc" ge "abc" is True', () => {
expect($b(ge._(_s('abc'))._(_s('abc')))).toEqual(true); expect($b(ge(_s('abc'))(_s('abc')))).toEqual(true);
}); });
it('handles infinite strings', () => { it('handles infinite strings', () => {
expect($b(ge._(_s('abc'))._(infinite))).toEqual(true); expect($b(ge(_s('abc'))(infinite))).toEqual(true);
expect($b(ge._(infinite)._(_s('abc')))).toEqual(false); expect($b(ge(infinite)(_s('abc')))).toEqual(false);
}); });
}); });
describe('gt', () => { describe('gt', () => {
it('"" gt "" is False', () => { it('"" gt "" is False', () => {
expect($b(gt._(_s(''))._(_s('')))).toEqual(false); expect($b(gt(_s(''))(_s('')))).toEqual(false);
}); });
it('"" gt "abc" is False', () => { it('"" gt "abc" is False', () => {
expect($b(gt._(_s(''))._(_s('abc')))).toEqual(false); expect($b(gt(_s(''))(_s('abc')))).toEqual(false);
}); });
it('"abc" gt "" is True', () => { it('"abc" gt "" is True', () => {
expect($b(gt._(_s('abc'))._(_s('')))).toEqual(true); expect($b(gt(_s('abc'))(_s('')))).toEqual(true);
}); });
it('"a" gt "abc" is False', () => { it('"a" gt "abc" is False', () => {
expect($b(gt._(_s('a'))._(_s('abc')))).toEqual(false); expect($b(gt(_s('a'))(_s('abc')))).toEqual(false);
}); });
it('"abc" gt "a" is True', () => { it('"abc" gt "a" is True', () => {
expect($b(gt._(_s('abc'))._(_s('a')))).toEqual(true); expect($b(gt(_s('abc'))(_s('a')))).toEqual(true);
}); });
it('"bca" gt "abc" is True', () => { it('"bca" gt "abc" is True', () => {
expect($b(gt._(_s('bca'))._(_s('abc')))).toEqual(true); expect($b(gt(_s('bca'))(_s('abc')))).toEqual(true);
}); });
it('"abc" gt "bca" is False', () => { it('"abc" gt "bca" is False', () => {
expect($b(gt._(_s('abc'))._(_s('bca')))).toEqual(false); expect($b(gt(_s('abc'))(_s('bca')))).toEqual(false);
}); });
it('"abc" gt "abc" is False', () => { it('"abc" gt "abc" is False', () => {
expect($b(gt._(_s('abc'))._(_s('abc')))).toEqual(false); expect($b(gt(_s('abc'))(_s('abc')))).toEqual(false);
}); });
it('handles infinite strings', () => { it('handles infinite strings', () => {
expect($b(gt._(_s('abc'))._(infinite))).toEqual(true); expect($b(gt(_s('abc'))(infinite))).toEqual(true);
expect($b(gt._(infinite)._(_s('abc')))).toEqual(false); expect($b(gt(infinite)(_s('abc')))).toEqual(false);
}); });
}); });
describe('show', () => { describe('show', () => {
it('show "" is """"', () => { it('show "" is """"', () => {
expect($s(show._(_s('')))).toBe('""'); expect($s(show(_s('')))).toBe('""');
}); });
it('show "a" is ""a""', () => { it('show "a" is ""a""', () => {
expect($s(show._(_s('a')))).toBe('"a"'); expect($s(show(_s('a')))).toBe('"a"');
}); });
it('show "abc" is ""abc""', () => { it('show "abc" is ""abc""', () => {
expect($s(show._(_s('abc')))).toBe('"abc"'); expect($s(show(_s('abc')))).toBe('"abc"');
}); });
}); });
}); });

Loading…
Cancel
Save