Comparison functions

master
Freywar Ulvnaudgari 2 years ago
parent 881f3af710
commit bbaa58a0b8
  1. 24
      src/bool.ts
  2. 18
      src/char.ts
  3. 52
      src/list.ts
  4. 24
      src/num.ts
  5. 31
      src/ord.ts
  6. 48
      src/pair.ts
  7. 24
      src/string.ts
  8. 119
      test/bool.spec.ts
  9. 149
      test/char.spec.ts
  10. 8
      test/core.spec.ts
  11. 211
      test/list.spec.ts
  12. 159
      test/num.spec.ts
  13. 163
      test/pair.spec.ts
  14. 217
      test/string.spec.ts

@ -1,4 +1,5 @@
import { toNative as $n, L, P, _, fromNative as _n } from './core';
import { toNative as $$, L, P, _, fromNative as __ } from './core';
import { EQ, GT, LT, Ord } from './ord';
export type Bool = L<<T extends P>(t: T) => L<(f: T) => T>>;
@ -11,11 +12,26 @@ export const False: Bool
export const iif: L<<T extends P>(b: Bool) => L<(t: T) => L<(f: T) => T>>>
= _(b => _(t => _(f => b._(t)._(f))));
export const not: L<(b: Bool) => Bool>
= _(b => b._(False)._(True));
export const cmp: L<(l: Bool) => L<(r: Bool) => Ord>>
= _(l => _(r => l._(r._(EQ)._(GT))._(r._(LT)._(EQ))));
export const lt: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(False)._(r)));
export const le: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(r)._(True)));
export const eq: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(r)._(not._(r))));
export const not: L<(b: Bool) => Bool>
= _(b => b._(False)._(True));
export const ge: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(True)._(not._(r))));
export const gt: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(not._(r))._(False)));
export const and: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(r)._(False)));
@ -30,4 +46,4 @@ export const fromBoolean: (b: boolean) => Bool
= b => b ? True : False;
export const toBoolean: (b: Bool) => boolean
= b => $n(b._(_n(true))._(_n(false)));
= b => $$(b._(__(true))._(__(false)));

@ -1,15 +1,31 @@
import { L, _ } from './core';
import { Bool } from './bool';
import { toNumber as $n, Num, Zero, fromNumber as _n, eq as eqn } from './num';
import { toNumber as $n, Num, Zero, fromNumber as _n, cmp as cmpn, eq as eqn, ge as gen, gt as gtn, le as len, lt as ltn } from './num';
import { Ord } from 'src/ord';
export type Char = Num;
export const Null: Char
= Zero;
export const cmp: L<(l: Char) => L<(r: Char) => Ord>>
= cmpn;
export const lt: L<(l: Char) => L<(r: Char) => Bool>>
= ltn;
export const le: L<(l: Char) => L<(r: Char) => Bool>>
= len;
export const eq: L<(l: Char) => L<(r: Char) => Bool>>
= eqn;
export const ge: L<(l: Char) => L<(r: Char) => Bool>>
= gen;
export const gt: L<(l: Char) => L<(r: Char) => Bool>>
= gtn;
export const fromChar: (c: string) => Char
= c => _n(c.charCodeAt(0));

@ -1,6 +1,6 @@
import { toNative as $n, L, P, _, fromNative as _n, undef } from './core';
import { toNative as $$, L, P, _, fromNative as __, undef } from './core';
import { EQ, GT, LT, Ord, eq as eqc } from './ord';
import { Bool, False, True, and, iif, or } from './bool';
import { toNumber as $nn, Num, fromNumber as _nn } from './num';
export type List<T extends P> = L<<R extends P>(z: R) => L<(f: L<(x: T) => L<(xs: List<T>) => R>>) => R>>;
@ -42,12 +42,46 @@ export const foldr: L<<T extends P, R extends P>(f: L<(x: T) => L<(a: R) => R>>)
export const foldrz: L<<T extends P>(f: L<(x: T) => L<(a: T) => T>>) => L<(xs: List<T>) => T>>
= _(_f => _(_z => undef));
export const eq: L<<T extends P>(e: L<(l: T) => L <(r: T) => Bool>>) => L<(l: List<T>) => L<(r: List<T>) => Bool>>>
= _(<T extends P>(e: L<(l: T) => L<(r: T) => Bool>>) =>
export const cmp: L<<T extends P>(ecmp: L<(l: T) => L <(r: T) => Ord>>) => L<(l: List<T>) => L<(r: List<T>) => Ord>>>
= _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
_((l: List<T>) =>
_((r: List<T>) => l
._(r._(EQ)._(_(_x => _(_xs => LT))))
._(_(lx => _(lxs => r._(GT)._(_(rx => _(rxs => iif
._(eqc._(EQ)._(ecmp._(lx)._(rx)))
._(cmp._(ecmp)._(lxs)._(rxs))
._(ecmp._(lx)._(rx)))))))))));
export const lt: L<<T extends P>(ecmp: L<(l: T) => L <(r: T) => Ord>>) => L<(l: List<T>) => L<(r: List<T>) => Bool>>>
= _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
_((l: List<T>) =>
_((r: List<T>) =>
r._(False)._(_(rx => _(rxs => l._(True)._(_(lx => _(lxs => ecmp._(lx)._(rx)._(True)._(lt._(ecmp)._(lxs)._(rxs))._(False))))))))));
export const le: L<<T extends P>(ecmp: L<(l: T) => L <(r: T) => Ord>>) => L<(l: List<T>) => L<(r: List<T>) => Bool>>>
= _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
_((l: List<T>) =>
_((r: List<T>) =>
l._(True)._(_(lx => _(lxs => r._(False)._(_(rx => _(rxs => ecmp._(lx)._(rx)._(True)._(le._(ecmp)._(lxs)._(rxs))._(False))))))))));
export const eq: L<<T extends P>(eeq: L<(l: T) => L <(r: T) => Bool>>) => L<(l: List<T>) => L<(r: List<T>) => Bool>>>
= _(<T extends P>(eeq: L<(l: T) => L<(r: T) => Bool>>) =>
_((l: List<T>) =>
_((r: List<T>) => l
._(r._(True)._(_(_x => _(_xs => False))))
._(_(lx => _(lxs => r._(False)._(_(rx => _(rxs => and._(e._(lx)._(rx))._(eq._(e)._(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>>>
= _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
_((l: List<T>) =>
_((r: List<T>) =>
r._(True)._(_(rx => _(rxs => l._(False)._(_(lx => _(lxs => ecmp._(lx)._(rx)._(False)._(ge._(ecmp)._(lxs)._(rxs))._(True))))))))));
export const gt: L<<T extends P>(ecmp: L<(l: T) => L <(r: T) => Ord>>) => L<(l: List<T>) => L<(r: List<T>) => Bool>>>
= _(<T extends P>(ecmp: L<(l: T) => L<(r: T) => Ord>>) =>
_((l: List<T>) =>
_((r: List<T>) =>
l._(False)._(_(lx => _(lxs => r._(True)._(_(rx => _(rxs => ecmp._(lx)._(rx)._(False)._(gt._(ecmp)._(lxs)._(rxs))._(True))))))))));
export const map: L<<T extends P, R extends P>(f: L<(x: T) => R>) => L<(xs: List<T>) => List<R>>>
= _(<T extends P, R extends P>(f: L<(x: T) => R>) =>
@ -68,11 +102,5 @@ export const all: L<<T extends P>(f: L<(x: T) => Bool>) => L<(xs: List<T>) => Bo
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));
export const fromNumberArray: (xs: number[]) => List<Num>
= xs => xs.length === 0 ? Nil : Cons._(_nn(xs[0]))._(new L(() => fromNumberArray(xs.slice(1)).value));
export const toArray: <T extends P>(xs: List<T>) => P[]
= xs => $n(xs._(_n([]))._(_(x => _(xs => _n([x, ...toArray(xs)])))));
export const toNumberArray: (xs: List<Num>) => number[]
= xs => $n(xs._(_n([]))._(_(x => _(xs => _n([$nn(x), ...toNumberArray(xs)])))));
= xs => $$(xs._(__([]))._(_(x => _(xs => __([x, ...toArray(xs)])))));

@ -1,4 +1,5 @@
import { toNative as $n, L, P, _, fromNative as _n, id } from './core';
import { toNative as $$, L, P, _, fromNative as __, id } from './core';
import { EQ, GT, LT, Ord } from './ord';
import { Bool, False, True } from './bool';
export type Num = L<<T extends P>(z: T) => L<(n: L<(p: Num) => T>) => T>>;
@ -18,10 +19,23 @@ export const succ: L<(n: Num) => Num>
export const pred: L<(n: Num) => Num>
= _(n => n._(Zero)._(id));
export const cmp: L<(l: Num) => L<(r: Num) => Ord>>
= _(l => _(r => l._(r._(EQ)._(_(_ => LT)))._(_(pl => r._(GT)._(_(pr => cmp._(pl)._(pr)))))));
export const lt: L<(l: Num) => L<(r: Num) => Bool>>
= _(l => _(r => r._(False)._(_(pr => l._(True)._(_(pl => lt._(pl)._(pr)))))));
export const le: L<(l: Num) => L<(r: Num) => Bool>>
= _(l => _(r => l._(True)._(_(pl => r._(False)._(_(pr => le._(pl)._(pr)))))));
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)._(_(_ => False)))._(_(pl => r._(False)._(_(pr => eq._(pl)._(pr)))))));
export const ge: L<(l: Num) => L<(r: Num) => Bool>>
= _(l => _(r => r._(True)._(_(pr => l._(False)._(_(pl => ge._(pl)._(pr)))))));
export const gt: L<(l: Num) => L<(r: Num) => Bool>>
= _(l => _(r => l._(False)._(_(pl => r._(True)._(_(pr => gt._(pl)._(pr)))))));
export const even: L<(n: Num) => Bool>
= _(n => n._(True)._(odd));
@ -42,4 +56,4 @@ export const fromNumber: (n: number) => Num
= n => !n ? Zero : Succ._(new L(() => fromNumber(n - 1).value));
export const toNumber: (n: Num) => number
= n => $n(n._(_n(0))._(_(p => _n(1 + toNumber(p)))));
= n => $$(n._(__(0))._(_(p => __(1 + toNumber(p)))));

@ -0,0 +1,31 @@
import { toNative as $$, L, P, _, fromNative as __ } from './core';
import { Bool, False, True } from './bool';
export type Ord = L<<T extends P>(lt: T) => L<(eq: T) => L<(gt: T) => T>>>;
export const enum NOrd {
LT,
EQ,
GT,
};
export const LT: Ord
= _(lt => _(_eq => _(_gt => lt))) as Ord;
export const EQ: Ord
= _(_lt => _(eq => _(_gt => eq)));
export const GT: Ord
= _(_lt => _(_eq => _(gt => gt)));
export const eq: L<(l: Ord) => L<(r: Ord) => Bool>>
= _(l => _(r => l
._(r._(True)._(False)._(False))
._(r._(False)._(True)._(False))
._(r._(False)._(False)._(True))));
export const fromNOrd: (b: NOrd) => Ord
= o => o === NOrd.LT ? LT : o === NOrd.EQ ? EQ : GT;
export const toNOrd: (b: Ord) => NOrd
= o => $$(o._(__(NOrd.LT))._(__(NOrd.EQ))._(__(NOrd.GT)));

@ -1,4 +1,6 @@
import { L, P, _ } from './core';
import { GT, LT, Ord } from './ord';
import { Bool, False, True, and } from './bool';
export type Pair<F extends P, S extends P> = L<<R extends P>(f: L<(f: F) => L<(s: S) => R>>) => R>;
@ -25,3 +27,49 @@ export const both: L<<F extends P, FR extends P, S extends P, SR extends P>(tf:
= _(<F extends P, FR extends P>(tf: L<(f: F) => FR>) =>
_(<S extends P, SR extends P>(ts: L<(s: S) => SR>) =>
_((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>>
= _(<F extends P, S extends P, R extends P>(t: L<(f: F) => L<(s: S) => R>>) =>
_((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>>>>
= _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) =>
_((scmp: L<(l: S) => L<(r: S) => Ord>>) =>
_((l: Pair<F, S>) =>
_((r: Pair<F, S>) =>
fcmp._(fst._(l))._(fst._(r))._(LT)._(scmp._(snd._(l))._(snd._(r)))._(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>>>>
= _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) =>
_((scmp: L<(l: S) => L<(r: S) => Ord>>) =>
_((l: Pair<F, S>) =>
_((r: Pair<F, S>) =>
fcmp._(fst._(l))._(fst._(r))._(True)._(scmp._(snd._(l))._(snd._(r))._(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>>>>
= _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) =>
_((scmp: L<(l: S) => L<(r: S) => Ord>>) =>
_((l: Pair<F, S>) =>
_((r: Pair<F, S>) =>
fcmp._(fst._(l))._(fst._(r))._(True)._(scmp._(snd._(l))._(snd._(r))._(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>>>>
= _(<F extends P, S extends P>(feq: L<(l: F) => L<(r: F) => Bool>>) =>
_((seq: L<(l: S) => L<(r: S) => Bool>>) =>
_((l: Pair<F, S>) =>
_((r: Pair<F, S>) =>
and._(feq._(fst._(l))._(fst._(r)))._(seq._(snd._(l))._(snd._(r)))))));
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>>) =>
_((scmp: L<(l: S) => L<(r: S) => Ord>>) =>
_((l: Pair<F, S>) =>
_((r: Pair<F, S>) =>
fcmp._(fst._(l))._(fst._(r))._(False)._(scmp._(snd._(l))._(snd._(r))._(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>>>>
= _(<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>>) =>
_((scmp: L<(l: S) => L<(r: S) => Ord>>) =>
_((l: Pair<F, S>) =>
_((r: Pair<F, S>) =>
fcmp._(fst._(l))._(fst._(r))._(False)._(scmp._(snd._(l))._(snd._(r))._(False)._(False)._(True))._(True)))));

@ -1,8 +1,9 @@
import { toNative as $n, L, _, fromNative as _n } from './core';
import { toNative as $$, L, _, fromNative as __ } from './core';
import { Ord } from './ord';
import { Bool } from './bool';
import { fromNumber as _nn } from './num';
import { toChar as $c, Char, fromChar as _c, eq as eqc } from './char';
import { Cons as ConsL, List, Nil, concat as concatl, eq as eql } from './list';
import { toChar as $c, Char, fromChar as _c, cmp as cmpc, eq as eqc } from './char';
import { Cons as ConsL, List, Nil, cmp as cmpl, concat as concatl, eq as eql, ge as gel, gt as gtl, le as lel, lt as ltl } from './list';
export type String = List<Char>;
@ -18,11 +19,26 @@ export const cons: L<(c: Char) => L<(s: String) => String>>
export const concat: L<(l: String) => L<(r: String) => String>>
= concatl;
export const cmp: L<(l: String) => L<(r: String) => Ord>>
= cmpl._(cmpc);
export const lt: L<(l: String) => L<(r: String) => Bool>>
= ltl._(cmpc);
export const le: L<(l: String) => L<(r: String) => Bool>>
= lel._(cmpc);
export const eq: L<(l: String) => L<(r: String) => Bool>>
= eql._(eqc);
export const ge: L<(l: String) => L<(r: String) => Bool>>
= gel._(cmpc);
export const gt: L<(l: String) => L<(r: String) => Bool>>
= gtl._(cmpc);
export const fromString: (xs: string) => String
= xs => xs.length === 0 ? Nil : Cons._(_c(xs[0]))._(new L(() => fromString(xs.slice(1)).value));
export const toString: (xs: String) => string
= xs => $n(xs._(_n(''))._(_(x => _(xs => _n($c(x) + toString(xs))))));
= xs => $$(xs._(__(''))._(_(x => _(xs => __($c(x) + toString(xs))))));

@ -1,6 +1,7 @@
import { describe, expect, it } from '@jest/globals';
import { undef } from '../src/core';
import { toBoolean as $, False, True, fromBoolean as _, and, eq, iif, not, or, xor } from '../src/bool';
import { toNOrd as $o, NOrd } from '../src/ord';
import { toBoolean as $, False, True, fromBoolean as _, and, cmp, eq, ge, gt, iif, le, lt, not, or, xor } from '../src/bool';
describe('Bool', () => {
describe('toBoolean', () => {
@ -38,6 +39,60 @@ describe('Bool', () => {
});
});
describe('not', () => {
it('not False is True', () => {
expect($(not._(False))).toBe(true);
});
it('not True is False', () => {
expect($(not._(True))).toBe(false);
});
});
describe('lt', () => {
it('False lt False is False', () => {
expect($(lt._(False)._(False))).toBe(false);
});
it('False lt True is True', () => {
expect($(lt._(False)._(True))).toBe(true);
});
it('True lt False is False', () => {
expect($(lt._(True)._(False))).toBe(false);
});
it('True lt True is False', () => {
expect($(lt._(True)._(True))).toBe(false);
});
it('True lt ignores second argument', () => {
expect($(lt._(True)._(undef))).toBe(false);
});
});
describe('le', () => {
it('False le False is True', () => {
expect($(le._(False)._(False))).toBe(true);
});
it('False le True is True', () => {
expect($(le._(False)._(True))).toBe(true);
});
it('True le False is False', () => {
expect($(le._(True)._(False))).toBe(false);
});
it('True le True is True', () => {
expect($(le._(True)._(True))).toBe(true);
});
it('False le ignores second argument', () => {
expect($(le._(False)._(undef))).toBe(true);
});
});
describe('eq', () => {
it('False eq False is True', () => {
expect($(eq._(False)._(False))).toBe(true);
@ -56,13 +111,65 @@ describe('Bool', () => {
});
});
describe('not', () => {
it('not False is True', () => {
expect($(not._(False))).toBe(true);
describe('ge', () => {
it('False ge False is True', () => {
expect($(ge._(False)._(False))).toBe(true);
});
it('not True is False', () => {
expect($(not._(True))).toBe(false);
it('False ge True is False', () => {
expect($(ge._(False)._(True))).toBe(false);
});
it('True ge False is True', () => {
expect($(ge._(True)._(False))).toBe(true);
});
it('True ge True is True', () => {
expect($(ge._(True)._(True))).toBe(true);
});
it('True ge ignores second argument', () => {
expect($(ge._(True)._(undef))).toBe(true);
});
});
describe('gt', () => {
it('False gt False is False', () => {
expect($(gt._(False)._(False))).toBe(false);
});
it('False gt True is False', () => {
expect($(gt._(False)._(True))).toBe(false);
});
it('True gt False is True', () => {
expect($(gt._(True)._(False))).toBe(true);
});
it('True gt True is False', () => {
expect($(gt._(True)._(True))).toBe(false);
});
it('False gt ignores second argument', () => {
expect($(gt._(False)._(undef))).toBe(false);
});
});
describe('cmp', () => {
it('False cmp False is EQ', () => {
expect($o(cmp._(False)._(False))).toBe(NOrd.EQ);
});
it('False cmp True is LT', () => {
expect($o(cmp._(False)._(True))).toBe(NOrd.LT);
});
it('True cmp False is GT', () => {
expect($o(cmp._(True)._(False))).toBe(NOrd.GT);
});
it('True cmp True is EQ', () => {
expect($o(cmp._(True)._(True))).toBe(NOrd.EQ);
});
});

@ -1,7 +1,8 @@
import { describe, expect, it } from '@jest/globals';
import { toNOrd as $o, NOrd } from '../src/ord';
import { toBoolean as $b, fromBoolean as _b } from '../src/bool';
import { fromNumber as _n } from '../src/num';
import { toChar as $, fromChar as _, eq } from '../src/char';
import { toChar as $, fromChar as _, cmp, eq, ge, gt, le, lt } from '../src/char';
describe('Char', () => {
describe('toChar', () => {
@ -40,6 +41,84 @@ describe('Char', () => {
});
});
describe('cmp', () => {
it('"0" cmp "0" is EQ', () => {
expect($o(cmp._(_('0'))._(_('0')))).toBe(NOrd.EQ);
});
it('"0" cmp "a" is LT', () => {
expect($o(cmp._(_('0'))._(_('a')))).toBe(NOrd.LT);
});
it('"a" cmp "0" is GT', () => {
expect($o(cmp._(_('a'))._(_('0')))).toBe(NOrd.GT);
});
it('"z" cmp "z" is EQ', () => {
expect($o(cmp._(_('z'))._(_('z')))).toBe(NOrd.EQ);
});
it('"z" cmp "-" is GT', () => {
expect($o(cmp._(_('z'))._(_('-')))).toBe(NOrd.GT);
});
it('"-" cmp "z" is LT', () => {
expect($o(cmp._(_('-'))._(_('z')))).toBe(NOrd.LT);
});
});
describe('lt', () => {
it('"0" lt "0" is False', () => {
expect($b(lt._(_('0'))._(_('0')))).toBe(false);
});
it('"0" lt "a" is True', () => {
expect($b(lt._(_('0'))._(_('a')))).toBe(true);
});
it('"a" lt "0" is False', () => {
expect($b(lt._(_('a'))._(_('0')))).toBe(false);
});
it('"z" lt "z" is False', () => {
expect($b(lt._(_('z'))._(_('z')))).toBe(false);
});
it('"z" lt "-" is False', () => {
expect($b(lt._(_('z'))._(_('-')))).toBe(false);
});
it('"-" lt "z" is True', () => {
expect($b(lt._(_('-'))._(_('z')))).toBe(true);
});
});
describe('le', () => {
it('"0" le "0" is True', () => {
expect($b(le._(_('0'))._(_('0')))).toBe(true);
});
it('"0" le "a" is True', () => {
expect($b(le._(_('0'))._(_('a')))).toBe(true);
});
it('"a" le "0" is False', () => {
expect($b(le._(_('a'))._(_('0')))).toBe(false);
});
it('"z" le "z" is True', () => {
expect($b(le._(_('z'))._(_('z')))).toBe(true);
});
it('"z" le "-" is False', () => {
expect($b(le._(_('z'))._(_('-')))).toBe(false);
});
it('"-" le "z" is True', () => {
expect($b(le._(_('-'))._(_('z')))).toBe(true);
});
});
describe('eq', () => {
it('"0" eq "0" is True', () => {
expect($b(eq._(_('0'))._(_('0')))).toBe(true);
@ -49,12 +128,72 @@ describe('Char', () => {
expect($b(eq._(_('0'))._(_('a')))).toBe(false);
});
it('"a" eq "a" is True', () => {
expect($b(eq._(_('a'))._(_('a')))).toBe(true);
it('"a" eq "0" is False', () => {
expect($b(eq._(_('a'))._(_('0')))).toBe(false);
});
it('"z" eq "z" is True', () => {
expect($b(eq._(_('z'))._(_('z')))).toBe(true);
});
it('"z" eq "-" is False', () => {
expect($b(eq._(_('z'))._(_('-')))).toBe(false);
});
it('"-" eq "z" is False', () => {
expect($b(eq._(_('-'))._(_('z')))).toBe(false);
});
});
describe('ge', () => {
it('"0" ge "0" is True', () => {
expect($b(ge._(_('0'))._(_('0')))).toBe(true);
});
it('"0" ge "a" is False', () => {
expect($b(ge._(_('0'))._(_('a')))).toBe(false);
});
it('"a" ge "0" is True', () => {
expect($b(ge._(_('a'))._(_('0')))).toBe(true);
});
it('"z" ge "z" is True', () => {
expect($b(ge._(_('z'))._(_('z')))).toBe(true);
});
it('"z" ge "-" is True', () => {
expect($b(ge._(_('z'))._(_('-')))).toBe(true);
});
it('"-" ge "z" is False', () => {
expect($b(ge._(_('-'))._(_('z')))).toBe(false);
});
});
describe('gt', () => {
it('"0" gt "0" is False', () => {
expect($b(gt._(_('0'))._(_('0')))).toBe(false);
});
it('"0" gt "a" is False', () => {
expect($b(gt._(_('0'))._(_('a')))).toBe(false);
});
it('"a" gt "0" is True', () => {
expect($b(gt._(_('a'))._(_('0')))).toBe(true);
});
it('"z" gt "z" is False', () => {
expect($b(gt._(_('z'))._(_('z')))).toBe(false);
});
it('"z" gt "-" is True', () => {
expect($b(gt._(_('z'))._(_('-')))).toBe(true);
});
it('"a" eq "z" is True', () => {
expect($b(eq._(_('a'))._(_('z')))).toBe(false);
it('"-" gt "z" is False', () => {
expect($b(gt._(_('-'))._(_('z')))).toBe(false);
});
});
});

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

@ -1,13 +1,20 @@
import { describe, expect, it } from '@jest/globals';
import { L, _, toNative, undef } from '../src/core';
import { fromNative as $$, L, _, toNative as __, undef } from '../src/core';
import { toNOrd as $o, NOrd } from '../src/ord';
import { toBoolean as $b, iif } from '../src/bool';
import { toNumber as $n, Num, Succ, Zero, fromNumber as _n, eq as eqn, even, odd, succ, sum } from '../src/num';
import { toArray as $a, toNumberArray as $na, Cons, List, Nil, fromArray as _a, fromNumberArray as _na, all, any, concat, cons, eq, filter, foldl, foldlz, foldr, foldrz, head, map, tail } from '../src/list';
import { toNumber as $n, toNumber as $nn, Num, Succ, Zero, fromNumber as _n, fromNumber as _nn, cmp as cmpn, eq as eqn, even, odd, succ, sum } from '../src/num';
import { toArray as $a, Cons, List, Nil, fromArray as _a, all, any, cmp, concat, cons, eq, filter, foldl, foldlz, foldr, foldrz, ge, gt, head, le, lt, map, tail } from '../src/list';
describe('List', () => {
const iterate: (n: Num) => List<Num> = n => new L(() => Cons._(n)._(iterate(Succ._(n))).value);
const infinite: List<Num> = iterate(Zero);
const _na: (xs: number[]) => List<Num>
= xs => xs.length === 0 ? Nil : Cons._(_nn(xs[0]))._(new L(() => _na(xs.slice(1)).value));
const $na: (xs: List<Num>) => number[]
= xs => __(xs._($$([]))._(_(x => _(xs => $$([$nn(x), ...$na(xs)])))));
describe('toArray', () => {
it('converts []', () => {
expect($a(Nil)).toEqual([]);
@ -74,7 +81,7 @@ describe('List', () => {
describe('head', () => {
it('returns nothing from Nil', () => {
expect(() => toNative(head._(Nil))).toThrow();
expect(() => __(head._(Nil))).toThrow();
});
it('returns only item', () => {
@ -181,6 +188,123 @@ describe('List', () => {
});
});
describe('cmp', () => {
it('Nil cmp Nil is EQ', () => {
expect($o(cmp._(cmpn)._(_na([]))._(_na([])))).toEqual(NOrd.EQ);
});
it('Nil cmp [0, 1, 2] is LT', () => {
expect($o(cmp._(cmpn)._(_na([]))._(_na([0, 1, 2])))).toEqual(NOrd.LT);
});
it('[0, 1, 2] cmp Nil is GT', () => {
expect($o(cmp._(cmpn)._(_na([0, 1, 2]))._(_na([])))).toEqual(NOrd.GT);
});
it('[0] cmp [0, 1, 2] is LT', () => {
expect($o(cmp._(cmpn)._(_na([0]))._(_na([0, 1, 2])))).toEqual(NOrd.LT);
});
it('[0, 1, 2] cmp [0] is GT', () => {
expect($o(cmp._(cmpn)._(_na([0, 1, 2]))._(_na([0])))).toEqual(NOrd.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);
});
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);
});
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);
});
it('handles infinite lists', () => {
expect($o(cmp._(cmpn)._(_na([0, 1, 2]))._(infinite))).toEqual(NOrd.LT);
expect($o(cmp._(cmpn)._(infinite)._(_na([0, 1, 2])))).toEqual(NOrd.GT);
});
});
describe('lt', () => {
it('Nil lt Nil is False', () => {
expect($b(lt._(cmpn)._(_na([]))._(_na([])))).toEqual(false);
});
it('Nil lt [0, 1, 2] is True', () => {
expect($b(lt._(cmpn)._(_na([]))._(_na([0, 1, 2])))).toEqual(true);
});
it('[0, 1, 2] lt Nil is False', () => {
expect($b(lt._(cmpn)._(_na([0, 1, 2]))._(_na([])))).toEqual(false);
});
it('[0] lt [0, 1, 2] is True', () => {
expect($b(lt._(cmpn)._(_na([0]))._(_na([0, 1, 2])))).toEqual(true);
});
it('[0, 1, 2] lt [0] is False', () => {
expect($b(lt._(cmpn)._(_na([0, 1, 2]))._(_na([0])))).toEqual(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);
});
it('[0, 1, 2] lt [1, 2, 0] is 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', () => {
expect($b(lt._(cmpn)._(_na([0, 1, 2]))._(_na([0, 1, 2])))).toEqual(false);
});
it('handles infinite lists', () => {
expect($b(lt._(cmpn)._(_na([0, 1, 2]))._(infinite))).toEqual(true);
expect($b(lt._(cmpn)._(infinite)._(_na([0, 1, 2])))).toEqual(false);
});
});
describe('le', () => {
it('Nil le Nil is True', () => {
expect($b(le._(cmpn)._(_na([]))._(_na([])))).toEqual(true);
});
it('Nil le [0, 1, 2] is True', () => {
expect($b(le._(cmpn)._(_na([]))._(_na([0, 1, 2])))).toEqual(true);
});
it('[0, 1, 2] le Nil is False', () => {
expect($b(le._(cmpn)._(_na([0, 1, 2]))._(_na([])))).toEqual(false);
});
it('[0] le [0, 1, 2] is True', () => {
expect($b(le._(cmpn)._(_na([0]))._(_na([0, 1, 2])))).toEqual(true);
});
it('[0, 1, 2] le [0] is False', () => {
expect($b(le._(cmpn)._(_na([0, 1, 2]))._(_na([0])))).toEqual(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);
});
it('[0, 1, 2] le [1, 2, 0] is 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', () => {
expect($b(le._(cmpn)._(_na([0, 1, 2]))._(_na([0, 1, 2])))).toEqual(true);
});
it('handles infinite lists', () => {
expect($b(le._(cmpn)._(_na([0, 1, 2]))._(infinite))).toEqual(true);
expect($b(le._(cmpn)._(infinite)._(_na([0, 1, 2])))).toEqual(false);
});
});
describe('eq', () => {
it('Nil eq Nil is True', () => {
expect($b(eq._(eqn)._(_na([]))._(_na([])))).toEqual(true);
@ -216,6 +340,85 @@ describe('List', () => {
it('handles infinite lists', () => {
expect($b(eq._(eqn)._(_na([0, 1, 2]))._(infinite))).toEqual(false);
expect($b(eq._(eqn)._(infinite)._(_na([0, 1, 2])))).toEqual(false);
});
});
describe('ge', () => {
it('Nil ge Nil is True', () => {
expect($b(ge._(cmpn)._(_na([]))._(_na([])))).toEqual(true);
});
it('Nil ge [0, 1, 2] is False', () => {
expect($b(ge._(cmpn)._(_na([]))._(_na([0, 1, 2])))).toEqual(false);
});
it('[0, 1, 2] ge Nil is True', () => {
expect($b(ge._(cmpn)._(_na([0, 1, 2]))._(_na([])))).toEqual(true);
});
it('[0] ge [0, 1, 2] is False', () => {
expect($b(ge._(cmpn)._(_na([0]))._(_na([0, 1, 2])))).toEqual(false);
});
it('[0, 1, 2] ge [0] is True', () => {
expect($b(ge._(cmpn)._(_na([0, 1, 2]))._(_na([0])))).toEqual(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);
});
it('[0, 1, 2] ge [1, 2, 0] is 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', () => {
expect($b(ge._(cmpn)._(_na([0, 1, 2]))._(_na([0, 1, 2])))).toEqual(true);
});
it('handles infinite lists', () => {
expect($b(ge._(cmpn)._(_na([0, 1, 2]))._(infinite))).toEqual(false);
expect($b(ge._(cmpn)._(infinite)._(_na([0, 1, 2])))).toEqual(true);
});
});
describe('gt', () => {
it('Nil gt Nil is False', () => {
expect($b(gt._(cmpn)._(_na([]))._(_na([])))).toEqual(false);
});
it('Nil gt [0, 1, 2] is False', () => {
expect($b(gt._(cmpn)._(_na([]))._(_na([0, 1, 2])))).toEqual(false);
});
it('[0, 1, 2] gt Nil is True', () => {
expect($b(gt._(cmpn)._(_na([0, 1, 2]))._(_na([])))).toEqual(true);
});
it('[0] gt [0, 1, 2] is False', () => {
expect($b(gt._(cmpn)._(_na([0]))._(_na([0, 1, 2])))).toEqual(false);
});
it('[0, 1, 2] gt [0] is True', () => {
expect($b(gt._(cmpn)._(_na([0, 1, 2]))._(_na([0])))).toEqual(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);
});
it('[0, 1, 2] gt [1, 2, 0] is 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', () => {
expect($b(gt._(cmpn)._(_na([0, 1, 2]))._(_na([0, 1, 2])))).toEqual(false);
});
it('handles infinite lists', () => {
expect($b(gt._(cmpn)._(_na([0, 1, 2]))._(infinite))).toEqual(false);
expect($b(gt._(cmpn)._(infinite)._(_na([0, 1, 2])))).toEqual(true);
});
});

@ -1,7 +1,8 @@
import { describe, expect, it } from '@jest/globals';
import { L, undef } from '../src/core';
import { toNOrd as $o, NOrd } from '../src/ord';
import { toBoolean as $b, fromBoolean as _b } from '../src/bool';
import { toNumber as $, Num, Succ, Zero, fromNumber as _, eq, ifz, mul, pred, sub, succ, sum } from '../src/num';
import { toNumber as $, Num, Succ, Zero, fromNumber as _, cmp, eq, ge, gt, ifz, le, lt, mul, pred, sub, succ, sum } from '../src/num';
describe('Num', () => {
const infinity: Num = new L(() => Succ._(infinity).value);
@ -80,6 +81,99 @@ describe('Num', () => {
});
});
describe('cmp', () => {
it('0 cmp 0 is EQ', () => {
expect($o(cmp._(_(0))._(_(0)))).toBe(NOrd.EQ);
});
it('0 cmp 1 is LT', () => {
expect($o(cmp._(_(0))._(_(1)))).toBe(NOrd.LT);
});
it('1 cmp 0 is GT', () => {
expect($o(cmp._(_(1))._(_(0)))).toBe(NOrd.GT);
});
it('3 cmp 3 is EQ', () => {
expect($o(cmp._(_(3))._(_(3)))).toBe(NOrd.EQ);
});
it('3 cmp 7 is LT', () => {
expect($o(cmp._(_(3))._(_(7)))).toBe(NOrd.LT);
});
it('7 cmp 3 is GT', () => {
expect($o(cmp._(_(7))._(_(3)))).toBe(NOrd.GT);
});
it('handles infinity', () => {
expect($o(cmp._(_(7))._(infinity))).toBe(NOrd.LT);
expect($o(cmp._(infinity)._(_(7)))).toBe(NOrd.GT);
});
});
describe('lt', () => {
it('0 lt 0 is False', () => {
expect($b(lt._(_(0))._(_(0)))).toBe(false);
});
it('0 lt 1 is True', () => {
expect($b(lt._(_(0))._(_(1)))).toBe(true);
});
it('1 lt 0 is False', () => {
expect($b(lt._(_(1))._(_(0)))).toBe(false);
});
it('3 lt 3 is False', () => {
expect($b(lt._(_(3))._(_(3)))).toBe(false);
});
it('3 lt 7 is True', () => {
expect($b(lt._(_(3))._(_(7)))).toBe(true);
});
it('7 lt 3 is False', () => {
expect($b(lt._(_(7))._(_(3)))).toBe(false);
});
it('handles infinity', () => {
expect($b(lt._(_(7))._(infinity))).toBe(true);
expect($b(lt._(infinity)._(_(7)))).toBe(false);
});
});
describe('le', () => {
it('0 le 0 is True', () => {
expect($b(le._(_(0))._(_(0)))).toBe(true);
});
it('0 le 1 is True', () => {
expect($b(le._(_(0))._(_(1)))).toBe(true);
});
it('1 le 0 is False', () => {
expect($b(le._(_(1))._(_(0)))).toBe(false);
});
it('3 le 3 is True', () => {
expect($b(le._(_(3))._(_(3)))).toBe(true);
});
it('3 le 7 is True', () => {
expect($b(le._(_(3))._(_(7)))).toBe(true);
});
it('7 le 3 is False', () => {
expect($b(le._(_(7))._(_(3)))).toBe(false);
});
it('handles infinity', () => {
expect($b(le._(_(7))._(infinity))).toBe(true);
expect($b(le._(infinity)._(_(7)))).toBe(false);
});
});
describe('eq', () => {
it('0 eq 0 is True', () => {
expect($b(eq._(_(0))._(_(0)))).toBe(true);
@ -107,6 +201,69 @@ describe('Num', () => {
it('handles infinity', () => {
expect($b(eq._(_(7))._(infinity))).toBe(false);
expect($b(eq._(infinity)._(_(7)))).toBe(false);
});
});
describe('ge', () => {
it('0 ge 0 is True', () => {
expect($b(ge._(_(0))._(_(0)))).toBe(true);
});
it('0 ge 1 is False', () => {
expect($b(ge._(_(0))._(_(1)))).toBe(false);
});
it('1 ge 0 is True', () => {
expect($b(ge._(_(1))._(_(0)))).toBe(true);
});
it('3 ge 3 is True', () => {
expect($b(ge._(_(3))._(_(3)))).toBe(true);
});
it('3 ge 7 is False', () => {
expect($b(ge._(_(3))._(_(7)))).toBe(false);
});
it('7 ge 3 is True', () => {
expect($b(ge._(_(7))._(_(3)))).toBe(true);
});
it('handles infinity', () => {
expect($b(ge._(_(7))._(infinity))).toBe(false);
expect($b(ge._(infinity)._(_(7)))).toBe(true);
});
});
describe('gt', () => {
it('0 gt 0 is False', () => {
expect($b(gt._(_(0))._(_(0)))).toBe(false);
});
it('0 gt 1 is False', () => {
expect($b(gt._(_(0))._(_(1)))).toBe(false);
});
it('1 gt 0 is True', () => {
expect($b(gt._(_(1))._(_(0)))).toBe(true);
});
it('3 gt 3 is False', () => {
expect($b(gt._(_(3))._(_(3)))).toBe(false);
});
it('3 gt 7 is False', () => {
expect($b(gt._(_(3))._(_(7)))).toBe(false);
});
it('7 gt 3 is True', () => {
expect($b(gt._(_(7))._(_(3)))).toBe(true);
});
it('handles infinity', () => {
expect($b(gt._(_(7))._(infinity))).toBe(false);
expect($b(gt._(infinity)._(_(7)))).toBe(true);
});
});

@ -1,8 +1,9 @@
import { describe, expect, it } from '@jest/globals';
import { undef } from '../src/core';
import { toBoolean as $b, fromBoolean as _b, not } from '../src/bool';
import { toNumber as $n, fromNumber as _n, succ } from '../src/num';
import { Pair, both, first, fst, second, snd } from '../src/pair';
import { toNOrd as $o, NOrd } from '../src/ord';
import { toBoolean as $b, fromBoolean as _b, cmp as bcmp, eq as beq, not } from '../src/bool';
import { toNumber as $n, fromNumber as _n, cmp as ncmp, eq as neq, succ } from '../src/num';
import { Pair, both, cmp, eq, first, fst, ge, gt, le, lt, second, snd } from '../src/pair';
describe('Pair', () => {
describe('fst', () => {
@ -51,4 +52,160 @@ describe('Pair', () => {
expect($n(snd._(both._(not)._(succ)._(Pair._(_b(false))._(_n(0)))))).toBe(1);
});
});
describe('cmp', () => {
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);
});
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);
});
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);
});
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);
});
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);
});
it('ignores second if first not equal', () => {
expect($o(cmp._(bcmp)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(NOrd.LT);
});
});
describe('lt', () => {
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);
});
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);
});
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);
});
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);
});
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);
});
it('ignores second if first not equal', () => {
expect($b(lt._(bcmp)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(true);
});
});
describe('le', () => {
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);
});
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);
});
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);
});
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);
});
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);
});
it('ignores second if first not equal', () => {
expect($b(le._(bcmp)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(true);
});
});
describe('eq', () => {
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);
});
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);
});
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);
});
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);
});
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);
});
it('ignores second if first not equal', () => {
expect($b(eq._(beq)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(false);
});
});
describe('ge', () => {
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);
});
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);
});
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);
});
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);
});
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);
});
it('ignores second if first not equal', () => {
expect($b(ge._(bcmp)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(false);
});
});
describe('gt', () => {
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);
});
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);
});
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);
});
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);
});
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);
});
it('ignores second if first not equal', () => {
expect($b(gt._(bcmp)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(false);
});
});
});

@ -1,8 +1,9 @@
import { describe, expect, it } from '@jest/globals';
import { L, _, undef } from '../src/core';
import { NOrd, toNOrd } from '../src/ord';
import { toBoolean as $b } from '../src/bool';
import { toChar as $c, fromChar as _c } from '../src/char';
import { toString as $s, Cons, Empty, String, fromString as _s, concat, eq } from '../src/string';
import { toString as $s, Cons, Empty, String, fromString as _s, cmp, concat, eq, ge, gt, le, lt } from '../src/string';
describe('String', () => {
const infinite: String = new L(() => Cons._(_c('a'))._(infinite).value); ;
@ -53,41 +54,237 @@ describe('String', () => {
});
});
describe('cmp', () => {
it('"" cmp "" is EQ', () => {
expect(toNOrd(cmp._(_s(''))._(_s('')))).toEqual(NOrd.EQ);
});
it('"" cmp "abc" is LT', () => {
expect(toNOrd(cmp._(_s(''))._(_s('abc')))).toEqual(NOrd.LT);
});
it('"abc" cmp "" is GT', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('')))).toEqual(NOrd.GT);
});
it('"a" cmp "abc" is LT', () => {
expect(toNOrd(cmp._(_s('a'))._(_s('abc')))).toEqual(NOrd.LT);
});
it('"abc" cmp "a" is GT', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('a')))).toEqual(NOrd.GT);
});
it('"bca" cmp "abc" is GT', () => {
expect(toNOrd(cmp._(_s('bca'))._(_s('abc')))).toEqual(NOrd.GT);
});
it('"abc" cmp "bca" is LT', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('bca')))).toEqual(NOrd.LT);
});
it('"abc" cmp "abc" is EQ', () => {
expect(toNOrd(cmp._(_s('abc'))._(_s('abc')))).toEqual(NOrd.EQ);
});
it('handles infinite strings', () => {
expect(toNOrd(cmp._(_s('abc'))._(infinite))).toEqual(NOrd.GT);
expect(toNOrd(cmp._(infinite)._(_s('abc')))).toEqual(NOrd.LT);
});
});
describe('lt', () => {
it('"" lt "" is False', () => {
expect($b(lt._(_s(''))._(_s('')))).toEqual(false);
});
it('"" lt "abc" is True', () => {
expect($b(lt._(_s(''))._(_s('abc')))).toEqual(true);
});
it('"abc" lt "" is False', () => {
expect($b(lt._(_s('abc'))._(_s('')))).toEqual(false);
});
it('"a" lt "abc" is True', () => {
expect($b(lt._(_s('a'))._(_s('abc')))).toEqual(true);
});
it('"abc" lt "a" is False', () => {
expect($b(lt._(_s('abc'))._(_s('a')))).toEqual(false);
});
it('"bca" lt "abc" is False', () => {
expect($b(lt._(_s('bca'))._(_s('abc')))).toEqual(false);
});
it('"abc" lt "bca" is True', () => {
expect($b(lt._(_s('abc'))._(_s('bca')))).toEqual(true);
});
it('"abc" lt "abc" is False', () => {
expect($b(lt._(_s('abc'))._(_s('abc')))).toEqual(false);
});
it('handles infinite strings', () => {
expect($b(lt._(_s('abc'))._(infinite))).toEqual(false);
expect($b(lt._(infinite)._(_s('abc')))).toEqual(true);
});
});
describe('le', () => {
it('"" le "" is True', () => {
expect($b(le._(_s(''))._(_s('')))).toEqual(true);
});
it('"" le "abc" is True', () => {
expect($b(le._(_s(''))._(_s('abc')))).toEqual(true);
});
it('"abc" le "" is False', () => {
expect($b(le._(_s('abc'))._(_s('')))).toEqual(false);
});
it('"a" le "abc" is True', () => {
expect($b(le._(_s('a'))._(_s('abc')))).toEqual(true);
});
it('"abc" le "a" is False', () => {
expect($b(le._(_s('abc'))._(_s('a')))).toEqual(false);
});
it('"bca" le "abc" is False', () => {
expect($b(le._(_s('bca'))._(_s('abc')))).toEqual(false);
});
it('"abc" le "bca" is True', () => {
expect($b(le._(_s('abc'))._(_s('bca')))).toEqual(true);
});
it('"abc" le "abc" is True', () => {
expect($b(le._(_s('abc'))._(_s('abc')))).toEqual(true);
});
it('handles infinite strings', () => {
expect($b(le._(_s('abc'))._(infinite))).toEqual(false);
expect($b(le._(infinite)._(_s('abc')))).toEqual(true);
});
});
describe('eq', () => {
it('"" eq "" is True', () => {
expect($b(eq._(_s(''))._(_s('')))).toBe(true);
expect($b(eq._(_s(''))._(_s('')))).toEqual(true);
});
it('"" eq "abc" is False', () => {
expect($b(eq._(_s(''))._(_s('abc')))).toBe(false);
expect($b(eq._(_s(''))._(_s('abc')))).toEqual(false);
});
it('"abc" eq "" is False', () => {
expect($b(eq._(_s('abc'))._(_s('')))).toBe(false);
expect($b(eq._(_s('abc'))._(_s('')))).toEqual(false);
});
it('"a" eq "abc" is False', () => {
expect($b(eq._(_s('a'))._(_s('abc')))).toBe(false);
expect($b(eq._(_s('a'))._(_s('abc')))).toEqual(false);
});
it('"abc" eq "a" is False', () => {
expect($b(eq._(_s('abc'))._(_s('a')))).toBe(false);
expect($b(eq._(_s('abc'))._(_s('a')))).toEqual(false);
});
it('"bca" eq "abc" is False', () => {
expect($b(eq._(_s('bca'))._(_s('abc')))).toBe(false);
expect($b(eq._(_s('bca'))._(_s('abc')))).toEqual(false);
});
it('"abc" eq "bca" is False', () => {
expect($b(eq._(_s('abc'))._(_s('bca')))).toBe(false);
expect($b(eq._(_s('abc'))._(_s('bca')))).toEqual(false);
});
it('"abc" eq "abc" is True', () => {
expect($b(eq._(_s('abc'))._(_s('abc')))).toBe(true);
expect($b(eq._(_s('abc'))._(_s('abc')))).toEqual(true);
});
it('handles infinite strings', () => {
expect($b(eq._(_s('abc'))._(infinite))).toEqual(false);
expect($b(eq._(infinite)._(_s('abc')))).toEqual(false);
});
});
describe('ge', () => {
it('"" ge "" is True', () => {
expect($b(ge._(_s(''))._(_s('')))).toEqual(true);
});
it('"" ge "abc" is False', () => {
expect($b(ge._(_s(''))._(_s('abc')))).toEqual(false);
});
it('"abc" ge "" is True', () => {
expect($b(ge._(_s('abc'))._(_s('')))).toEqual(true);
});
it('"a" ge "abc" is False', () => {
expect($b(ge._(_s('a'))._(_s('abc')))).toEqual(false);
});
it('"abc" ge "a" is True', () => {
expect($b(ge._(_s('abc'))._(_s('a')))).toEqual(true);
});
it('"bca" ge "abc" is True', () => {
expect($b(ge._(_s('bca'))._(_s('abc')))).toEqual(true);
});
it('"abc" ge "bca" is False', () => {
expect($b(ge._(_s('abc'))._(_s('bca')))).toEqual(false);
});
it('"abc" ge "abc" is True', () => {
expect($b(ge._(_s('abc'))._(_s('abc')))).toEqual(true);
});
it('handles infinite strings', () => {
expect($b(ge._(_s('abc'))._(infinite))).toEqual(true);
expect($b(ge._(infinite)._(_s('abc')))).toEqual(false);
});
});
describe('gt', () => {
it('"" gt "" is False', () => {
expect($b(gt._(_s(''))._(_s('')))).toEqual(false);
});
it('"" gt "abc" is False', () => {
expect($b(gt._(_s(''))._(_s('abc')))).toEqual(false);
});
it('"abc" gt "" is True', () => {
expect($b(gt._(_s('abc'))._(_s('')))).toEqual(true);
});
it('"a" gt "abc" is False', () => {
expect($b(gt._(_s('a'))._(_s('abc')))).toEqual(false);
});
it('"abc" gt "a" is True', () => {
expect($b(gt._(_s('abc'))._(_s('a')))).toEqual(true);
});
it('"bca" gt "abc" is True', () => {
expect($b(gt._(_s('bca'))._(_s('abc')))).toEqual(true);
});
it('"abc" gt "bca" is False', () => {
expect($b(gt._(_s('abc'))._(_s('bca')))).toEqual(false);
});
it('"abc" gt "abc" is False', () => {
expect($b(gt._(_s('abc'))._(_s('abc')))).toEqual(false);
});
it('handles infinite strings', () => {
expect($b(eq._(_s('abc'))._(infinite))).toBe(false);
expect($b(gt._(_s('abc'))._(infinite))).toEqual(true);
expect($b(gt._(infinite)._(_s('abc')))).toEqual(false);
});
});
});

Loading…
Cancel
Save