master
Freywar Ulvnaudgari 2 years ago
parent 252e795a65
commit 96b66f1413
  1. 1
      eslint.config.mjs
  2. 4
      src/bool.ts
  3. 28
      src/char.ts
  4. 8
      src/debug.ts
  5. 28
      src/list.ts
  6. 8
      src/num.ts
  7. 4
      src/ord.ts
  8. 8
      src/pair.ts
  9. 17
      src/string.ts
  10. 109
      test/bool.spec.ts
  11. 107
      test/char.spec.ts
  12. 129
      test/list.spec.ts
  13. 201
      test/num.spec.ts
  14. 25
      test/pair.spec.ts
  15. 71
      test/string.spec.ts

@ -32,6 +32,7 @@ export default [
'@stylistic/quotes': ['error', 'single'],
'@stylistic/semi': ['error', 'always'],
'@stylistic/indent': 'error',
'@stylistic/arrow-parens': ['error', 'as-needed', { requireForBlockBody: false }],
'@typescript-eslint/no-unused-vars': [
'error',
{

@ -1,5 +1,6 @@
import { toNative as $$, L, P, _, fromNative as __ } from './core';
import { EQ, GT, LT, Ord } from './ord';
import { String, fromString as _s } from './string';
export type Bool = L<<T extends P>(t: T) => L<(f: T) => T>>;
@ -42,6 +43,9 @@ export const or: L<(l: Bool) => L<(r: Bool) => Bool>>
export const xor: L<(l: Bool) => L<(r: Bool) => Bool>>
= _(l => _(r => l._(not._(r))._(r)));
export const show: L<(b: Bool) => String>
= _(b => iif._(b)._(_s('True'))._(_s('False')));
export const fromBoolean: (b: boolean) => Bool
= b => b ? True : False;

@ -1,30 +1,16 @@
import { L, _ } from './core';
import { Bool } from './bool';
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';
import { toNumber as $n, Byte, fromNumber as _n, x00 } from './byte';
import { Empty, String, cons } from './string';
export type Char = Num;
export type Char = Byte;
export const Null: Char
= Zero;
= x00;
export const cmp: L<(l: Char) => L<(r: Char) => Ord>>
= cmpn;
export { inc, dec, ifz as ifn, cmp, lt, le, eq, ge, gt } from './byte';
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 show: L<(c: Char) => String>
= _(c => cons._(fromChar('\''))._(cons._(c)._(cons._(fromChar('\''))._(Empty))));
export const fromChar: (c: string) => Char
= c => _n(c.charCodeAt(0));

@ -0,0 +1,8 @@
import { L, P, _ } from './core';
import { String, toString } from './string';
export const log: L<<T extends P>(s: String) => L<(p: T) => T>>
= _(s => _(p => {
console.log(toString(s));
return p;
}));

@ -1,7 +1,8 @@
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 { Num } from 'src/num';
import { Num, Zero, succ } from './num';
import { String, fromString as _s } from './string';
export type List<T extends P> = L<<R extends P>(z: R) => L<(f: L<(x: T) => L<(xs: List<T>) => R>>) => R>>;
@ -14,8 +15,21 @@ 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;
export const concat: L<<T extends P>(l: List<T>) => L<(r: List<T>) => List<T>>>
= _(l => _(r => l._(r)._(_(x => _(xs => cons._(x)._(concat._(xs)._(r)))))));
export const snoc: L<<T extends P>(xs: List<T>) => L<(x: T) => List<T>>>
= _(<T extends P>(xs: List<T>) =>
_((x: T) => xs._(cons._(x)._(Nil))._(_(y => _(ys => cons._(y)._(snoc._(ys)._(x)))))));
export const nul: L<<T extends P>(xs: List<T>) => Bool>
= _(xs => xs._(True)._(_(_x => _(_xs => False))));
export const len: L<<T extends P>(xs: List<T>) => Num>
= _(xs => xs._(Zero)._(_(_x => _(xs => succ._(len._(xs))))));
export const append: L<<T extends P>(l: List<T>) => L<(r: List<T>) => List<T>>>
= _(l => _(r => l._(r)._(_(x => _(xs => cons._(x)._(append._(xs)._(r)))))));
export const concat: L<<T extends P>(ls: List<List<T>>) => List<T>>
= _(ls => ls._(Nil)._(_(x => _(xs => append._(x)._(concat._(xs))))));
export const head: L<<T extends P>(xs: List<T>) => T>
= _(xs => xs._(undef)._(_(x => _(_xs => x))));
@ -114,6 +128,14 @@ export const update: L<<T extends P>(f: L< (p: T) => T>) => L<(i: Num) => L<(xs:
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)));
export const intersperse: L<<T extends P>(v: T) => L<(xs: List<T>) => List<T>>>
= _(v => _(xs =>
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>>
= _(eshow => _(xs =>
concat._(snoc._(cons._(_s('['))._(intersperse._(_s(', '))._(map._(eshow)._(xs))))._(_s(']')))));
export const fromArray: <T extends P>(xs: T[]) => List<T>
= xs => xs.length === 0 ? Nil : Cons._(xs[0])._(new L(() => fromArray(xs.slice(1)).value));

@ -1,6 +1,7 @@
import { toNative as $$, L, P, _, fromNative as __, id } from './core';
import { EQ, GT, LT, Ord } from './ord';
import { Bool, False, iif, True } from './bool';
import { Bool, False, True, iif } from './bool';
import { Empty, String, append, cons } from './string';
export type Num = L<<T extends P>(z: T) => L<(n: L<(p: Num) => T>) => T>>;
@ -58,6 +59,11 @@ export const div: 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))));
export const show: L<(n: Num) => String>
= _(n => iif._(lt._(n)._(fromNumber(10)))
._(cons._(sum._(n)._(fromNumber(48)))._(Empty))
._(append._(show._(div._(n)._(fromNumber(10))))._(show._(mod._(n)._(fromNumber(10))))));
export const fromNumber: (n: number) => Num
= n => !n ? Zero : Succ._(new L(() => fromNumber(n - 1).value));

@ -1,5 +1,6 @@
import { toNative as $$, L, P, _, fromNative as __ } from './core';
import { Bool, False, True } from './bool';
import { String, fromString as _s } from './string';
export type Ord = L<<T extends P>(lt: T) => L<(eq: T) => L<(gt: T) => T>>>;
@ -24,6 +25,9 @@ export const eq: L<(l: Ord) => L<(r: Ord) => Bool>>
._(r._(False)._(True)._(False))
._(r._(False)._(False)._(True))));
export const show: L<(o: Ord) => String>
= _(o => o._(_s('LT'))._(_s('EQ'))._(_s('GT')));
export const fromNOrd: (b: NOrd) => Ord
= o => o === NOrd.LT ? LT : o === NOrd.EQ ? EQ : GT;

@ -1,6 +1,8 @@
import { L, P, _ } from './core';
import { GT, LT, Ord } from './ord';
import { Bool, False, True, and } from './bool';
import { Nil, concat, cons } from './list';
import { String, fromString as _s } from './string';
export type Pair<F extends P, S extends P> = L<<R extends P>(f: L<(f: F) => L<(s: S) => R>>) => R>;
@ -73,3 +75,9 @@ export const gt: L<<F extends P, S extends P>(fcmp: L<(l: F) => L<(r: F) => Ord>
_((l: Pair<F, S>) =>
_((r: Pair<F, S>) =>
fcmp._(fst._(l))._(fst._(r))._(False)._(scmp._(snd._(l))._(snd._(r))._(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>>>
= _(<F extends P>(fshow: L<(f: F) => String>) =>
_(<S extends P>(sshow: L<(s: S) => String>) =>
_((p: Pair<F, S>) =>
uncurry._(_(f => _(s => concat._(cons._(_s('('))._(cons._(fshow._(f))._(cons._(_s(', '))._(cons._(sshow._(s))._(cons._(_s(')'))._(Nil)))))))))._(p))));

@ -3,21 +3,11 @@ import { Ord } from './ord';
import { Bool } from './bool';
import { fromNumber as _nn } from './num';
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';
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';
export type String = List<Char>;
export const Empty: String
= Nil;
export const Cons: L<(c: Char) => L<(s: String) => String>>
= ConsL;
export const cons: L<(c: Char) => L<(s: String) => String>>
= Cons;
export const concat: L<(l: String) => L<(r: String) => String>>
= concatl;
export { Nil as Empty, nul as empty, len, Cons, cons, snoc, append, get, update, set } from './list';
export const cmp: L<(l: String) => L<(r: String) => Ord>>
= cmpl._(cmpc);
@ -37,6 +27,9 @@ export const ge: L<(l: String) => L<(r: String) => Bool>>
export const gt: L<(l: String) => L<(r: String) => Bool>>
= gtl._(cmpc);
export const show: L<(s: String) => String>
= _(s => concat._(cons._(fromString('"'))._(cons._(s)._(cons._(fromString('"'))._(Nil)))));
export const fromString: (xs: string) => String
= xs => xs.length === 0 ? Nil : Cons._(_c(xs[0]))._(new L(() => fromString(xs.slice(1)).value));

@ -1,157 +1,158 @@
import { describe, expect, it } from '@jest/globals';
import { undef } from '../src/core';
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';
import { toBoolean as $b, False, True, fromBoolean as _b, and, cmp, eq, ge, gt, iif, le, lt, not, or, show, xor } from '../src/bool';
import { toString as $s } from '../src/string';
describe('Bool', () => {
describe('toBoolean', () => {
it('converts True', () => {
expect($(True)).toBe(true);
expect($b(True)).toBe(true);
});
it('converts False', () => {
expect($(False)).toBe(false);
expect($b(False)).toBe(false);
});
});
describe('fromBoolean', () => {
it('converts true', () => {
expect($(_(true))).toBe(true);
expect($b(_b(true))).toBe(true);
});
it('converts false', () => {
expect($(_(false))).toBe(false);
expect($b(_b(false))).toBe(false);
});
});
describe('iif', () => {
it('returns true argument', () => {
expect($(iif._(True)._(True)._(False))).toBe(true);
expect($b(iif._(True)._(True)._(False))).toBe(true);
});
it('returns false argument', () => {
expect($(iif._(False)._(True)._(False))).toBe(false);
expect($b(iif._(False)._(True)._(False))).toBe(false);
});
it('ignores other argument', () => {
expect($(iif._(True)._(True)._(undef))).toBe(true);
expect($(iif._(False)._(undef)._(False))).toBe(false);
expect($b(iif._(True)._(True)._(undef))).toBe(true);
expect($b(iif._(False)._(undef)._(False))).toBe(false);
});
});
describe('not', () => {
it('not False is True', () => {
expect($(not._(False))).toBe(true);
expect($b(not._(False))).toBe(true);
});
it('not True is False', () => {
expect($(not._(True))).toBe(false);
expect($b(not._(True))).toBe(false);
});
});
describe('lt', () => {
it('False lt False is False', () => {
expect($(lt._(False)._(False))).toBe(false);
expect($b(lt._(False)._(False))).toBe(false);
});
it('False lt True is True', () => {
expect($(lt._(False)._(True))).toBe(true);
expect($b(lt._(False)._(True))).toBe(true);
});
it('True lt False is False', () => {
expect($(lt._(True)._(False))).toBe(false);
expect($b(lt._(True)._(False))).toBe(false);
});
it('True lt True is False', () => {
expect($(lt._(True)._(True))).toBe(false);
expect($b(lt._(True)._(True))).toBe(false);
});
it('True lt ignores second argument', () => {
expect($(lt._(True)._(undef))).toBe(false);
expect($b(lt._(True)._(undef))).toBe(false);
});
});
describe('le', () => {
it('False le False is True', () => {
expect($(le._(False)._(False))).toBe(true);
expect($b(le._(False)._(False))).toBe(true);
});
it('False le True is True', () => {
expect($(le._(False)._(True))).toBe(true);
expect($b(le._(False)._(True))).toBe(true);
});
it('True le False is False', () => {
expect($(le._(True)._(False))).toBe(false);
expect($b(le._(True)._(False))).toBe(false);
});
it('True le True is True', () => {
expect($(le._(True)._(True))).toBe(true);
expect($b(le._(True)._(True))).toBe(true);
});
it('False le ignores second argument', () => {
expect($(le._(False)._(undef))).toBe(true);
expect($b(le._(False)._(undef))).toBe(true);
});
});
describe('eq', () => {
it('False eq False is True', () => {
expect($(eq._(False)._(False))).toBe(true);
expect($b(eq._(False)._(False))).toBe(true);
});
it('False eq True is False', () => {
expect($(eq._(False)._(True))).toBe(false);
expect($b(eq._(False)._(True))).toBe(false);
});
it('True eq False is False', () => {
expect($(eq._(True)._(False))).toBe(false);
expect($b(eq._(True)._(False))).toBe(false);
});
it('True eq True is True', () => {
expect($(eq._(True)._(True))).toBe(true);
expect($b(eq._(True)._(True))).toBe(true);
});
});
describe('ge', () => {
it('False ge False is True', () => {
expect($(ge._(False)._(False))).toBe(true);
expect($b(ge._(False)._(False))).toBe(true);
});
it('False ge True is False', () => {
expect($(ge._(False)._(True))).toBe(false);
expect($b(ge._(False)._(True))).toBe(false);
});
it('True ge False is True', () => {
expect($(ge._(True)._(False))).toBe(true);
expect($b(ge._(True)._(False))).toBe(true);
});
it('True ge True is True', () => {
expect($(ge._(True)._(True))).toBe(true);
expect($b(ge._(True)._(True))).toBe(true);
});
it('True ge ignores second argument', () => {
expect($(ge._(True)._(undef))).toBe(true);
expect($b(ge._(True)._(undef))).toBe(true);
});
});
describe('gt', () => {
it('False gt False is False', () => {
expect($(gt._(False)._(False))).toBe(false);
expect($b(gt._(False)._(False))).toBe(false);
});
it('False gt True is False', () => {
expect($(gt._(False)._(True))).toBe(false);
expect($b(gt._(False)._(True))).toBe(false);
});
it('True gt False is True', () => {
expect($(gt._(True)._(False))).toBe(true);
expect($b(gt._(True)._(False))).toBe(true);
});
it('True gt True is False', () => {
expect($(gt._(True)._(True))).toBe(false);
expect($b(gt._(True)._(True))).toBe(false);
});
it('False gt ignores second argument', () => {
expect($(gt._(False)._(undef))).toBe(false);
expect($b(gt._(False)._(undef))).toBe(false);
});
});
@ -175,63 +176,73 @@ describe('Bool', () => {
describe('and', () => {
it('False and False is False', () => {
expect($(and._(False)._(False))).toBe(false);
expect($b(and._(False)._(False))).toBe(false);
});
it('False and True is False', () => {
expect($(and._(False)._(True))).toBe(false);
expect($b(and._(False)._(True))).toBe(false);
});
it('True and False is False', () => {
expect($(and._(True)._(False))).toBe(false);
expect($b(and._(True)._(False))).toBe(false);
});
it('True and True is True', () => {
expect($(and._(True)._(True))).toBe(true);
expect($b(and._(True)._(True))).toBe(true);
});
it('False and ignores other argument', () => {
expect($(and._(False)._(undef))).toBe(false);
expect($b(and._(False)._(undef))).toBe(false);
});
});
describe('or', () => {
it('False or False is False', () => {
expect($(or._(False)._(False))).toBe(false);
expect($b(or._(False)._(False))).toBe(false);
});
it('False or True is True', () => {
expect($(or._(False)._(True))).toBe(true);
expect($b(or._(False)._(True))).toBe(true);
});
it('True or False is True', () => {
expect($(or._(True)._(False))).toBe(true);
expect($b(or._(True)._(False))).toBe(true);
});
it('True or True is True', () => {
expect($(or._(True)._(True))).toBe(true);
expect($b(or._(True)._(True))).toBe(true);
});
it('True or ignores other argument', () => {
expect($(or._(True)._(undef))).toBe(true);
expect($b(or._(True)._(undef))).toBe(true);
});
});
describe('xor', () => {
it('False xor False is False', () => {
expect($(xor._(False)._(False))).toBe(false);
expect($b(xor._(False)._(False))).toBe(false);
});
it('False xor True is True', () => {
expect($(xor._(False)._(True))).toBe(true);
expect($b(xor._(False)._(True))).toBe(true);
});
it('True xor False is True', () => {
expect($(xor._(True)._(False))).toBe(true);
expect($b(xor._(True)._(False))).toBe(true);
});
it('True xor True is False', () => {
expect($(xor._(True)._(True))).toBe(false);
expect($b(xor._(True)._(True))).toBe(false);
});
});
describe('show', () => {
it('show False is "False"', () => {
expect($s(show._(False))).toBe('False');
});
it('show True is "True"', () => {
expect($s(show._(True))).toBe('True');
});
});
});

@ -1,199 +1,214 @@
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 _, cmp, eq, ge, gt, le, lt } from '../src/char';
import { fromNumber as _n } from '../src/byte';
import { toChar as $c, fromChar as _c, cmp, eq, ge, gt, le, lt, show } from '../src/char';
import { toString as $s } from '../src/string';
describe('Char', () => {
describe('toChar', () => {
it('converts "0"', () => {
expect($(_n(48))).toBe('0');
expect($c(_n(48))).toBe('0');
});
it('converts "a"', () => {
expect($(_n(97))).toBe('a');
expect($c(_n(97))).toBe('a');
});
it('converts "Z"', () => {
expect($(_n(90))).toBe('Z');
expect($c(_n(90))).toBe('Z');
});
it('converts "-"', () => {
expect($(_n(45))).toBe('-');
expect($c(_n(45))).toBe('-');
});
});
describe('fromChar', () => {
it('converts "0"', () => {
expect($(_('0'))).toBe('0');
expect($c(_c('0'))).toBe('0');
});
it('converts "a"', () => {
expect($(_('a'))).toBe('a');
expect($c(_c('a'))).toBe('a');
});
it('converts "Z"', () => {
expect($(_('Z'))).toBe('Z');
expect($c(_c('Z'))).toBe('Z');
});
it('converts "-"', () => {
expect($(_('-'))).toBe('-');
expect($c(_c('-'))).toBe('-');
});
});
describe('cmp', () => {
it('"0" cmp "0" is EQ', () => {
expect($o(cmp._(_('0'))._(_('0')))).toBe(NOrd.EQ);
expect($o(cmp._(_c('0'))._(_c('0')))).toBe(NOrd.EQ);
});
it('"0" cmp "a" is LT', () => {
expect($o(cmp._(_('0'))._(_('a')))).toBe(NOrd.LT);
expect($o(cmp._(_c('0'))._(_c('a')))).toBe(NOrd.LT);
});
it('"a" cmp "0" is GT', () => {
expect($o(cmp._(_('a'))._(_('0')))).toBe(NOrd.GT);
expect($o(cmp._(_c('a'))._(_c('0')))).toBe(NOrd.GT);
});
it('"z" cmp "z" is EQ', () => {
expect($o(cmp._(_('z'))._(_('z')))).toBe(NOrd.EQ);
expect($o(cmp._(_c('z'))._(_c('z')))).toBe(NOrd.EQ);
});
it('"z" cmp "-" is GT', () => {
expect($o(cmp._(_('z'))._(_('-')))).toBe(NOrd.GT);
expect($o(cmp._(_c('z'))._(_c('-')))).toBe(NOrd.GT);
});
it('"-" cmp "z" is LT', () => {
expect($o(cmp._(_('-'))._(_('z')))).toBe(NOrd.LT);
expect($o(cmp._(_c('-'))._(_c('z')))).toBe(NOrd.LT);
});
});
describe('lt', () => {
it('"0" lt "0" is False', () => {
expect($b(lt._(_('0'))._(_('0')))).toBe(false);
expect($b(lt._(_c('0'))._(_c('0')))).toBe(false);
});
it('"0" lt "a" is True', () => {
expect($b(lt._(_('0'))._(_('a')))).toBe(true);
expect($b(lt._(_c('0'))._(_c('a')))).toBe(true);
});
it('"a" lt "0" is False', () => {
expect($b(lt._(_('a'))._(_('0')))).toBe(false);
expect($b(lt._(_c('a'))._(_c('0')))).toBe(false);
});
it('"z" lt "z" is False', () => {
expect($b(lt._(_('z'))._(_('z')))).toBe(false);
expect($b(lt._(_c('z'))._(_c('z')))).toBe(false);
});
it('"z" lt "-" is False', () => {
expect($b(lt._(_('z'))._(_('-')))).toBe(false);
expect($b(lt._(_c('z'))._(_c('-')))).toBe(false);
});
it('"-" lt "z" is True', () => {
expect($b(lt._(_('-'))._(_('z')))).toBe(true);
expect($b(lt._(_c('-'))._(_c('z')))).toBe(true);
});
});
describe('le', () => {
it('"0" le "0" is True', () => {
expect($b(le._(_('0'))._(_('0')))).toBe(true);
expect($b(le._(_c('0'))._(_c('0')))).toBe(true);
});
it('"0" le "a" is True', () => {
expect($b(le._(_('0'))._(_('a')))).toBe(true);
expect($b(le._(_c('0'))._(_c('a')))).toBe(true);
});
it('"a" le "0" is False', () => {
expect($b(le._(_('a'))._(_('0')))).toBe(false);
expect($b(le._(_c('a'))._(_c('0')))).toBe(false);
});
it('"z" le "z" is True', () => {
expect($b(le._(_('z'))._(_('z')))).toBe(true);
expect($b(le._(_c('z'))._(_c('z')))).toBe(true);
});
it('"z" le "-" is False', () => {
expect($b(le._(_('z'))._(_('-')))).toBe(false);
expect($b(le._(_c('z'))._(_c('-')))).toBe(false);
});
it('"-" le "z" is True', () => {
expect($b(le._(_('-'))._(_('z')))).toBe(true);
expect($b(le._(_c('-'))._(_c('z')))).toBe(true);
});
});
describe('eq', () => {
it('"0" eq "0" is True', () => {
expect($b(eq._(_('0'))._(_('0')))).toBe(true);
expect($b(eq._(_c('0'))._(_c('0')))).toBe(true);
});
it('"0" eq "a" is False', () => {
expect($b(eq._(_('0'))._(_('a')))).toBe(false);
expect($b(eq._(_c('0'))._(_c('a')))).toBe(false);
});
it('"a" eq "0" is False', () => {
expect($b(eq._(_('a'))._(_('0')))).toBe(false);
expect($b(eq._(_c('a'))._(_c('0')))).toBe(false);
});
it('"z" eq "z" is True', () => {
expect($b(eq._(_('z'))._(_('z')))).toBe(true);
expect($b(eq._(_c('z'))._(_c('z')))).toBe(true);
});
it('"z" eq "-" is False', () => {
expect($b(eq._(_('z'))._(_('-')))).toBe(false);
expect($b(eq._(_c('z'))._(_c('-')))).toBe(false);
});
it('"-" eq "z" is False', () => {
expect($b(eq._(_('-'))._(_('z')))).toBe(false);
expect($b(eq._(_c('-'))._(_c('z')))).toBe(false);
});
});
describe('ge', () => {
it('"0" ge "0" is True', () => {
expect($b(ge._(_('0'))._(_('0')))).toBe(true);
expect($b(ge._(_c('0'))._(_c('0')))).toBe(true);
});
it('"0" ge "a" is False', () => {
expect($b(ge._(_('0'))._(_('a')))).toBe(false);
expect($b(ge._(_c('0'))._(_c('a')))).toBe(false);
});
it('"a" ge "0" is True', () => {
expect($b(ge._(_('a'))._(_('0')))).toBe(true);
expect($b(ge._(_c('a'))._(_c('0')))).toBe(true);
});
it('"z" ge "z" is True', () => {
expect($b(ge._(_('z'))._(_('z')))).toBe(true);
expect($b(ge._(_c('z'))._(_c('z')))).toBe(true);
});
it('"z" ge "-" is True', () => {
expect($b(ge._(_('z'))._(_('-')))).toBe(true);
expect($b(ge._(_c('z'))._(_c('-')))).toBe(true);
});
it('"-" ge "z" is False', () => {
expect($b(ge._(_('-'))._(_('z')))).toBe(false);
expect($b(ge._(_c('-'))._(_c('z')))).toBe(false);
});
});
describe('gt', () => {
it('"0" gt "0" is False', () => {
expect($b(gt._(_('0'))._(_('0')))).toBe(false);
expect($b(gt._(_c('0'))._(_c('0')))).toBe(false);
});
it('"0" gt "a" is False', () => {
expect($b(gt._(_('0'))._(_('a')))).toBe(false);
expect($b(gt._(_c('0'))._(_c('a')))).toBe(false);
});
it('"a" gt "0" is True', () => {
expect($b(gt._(_('a'))._(_('0')))).toBe(true);
expect($b(gt._(_c('a'))._(_c('0')))).toBe(true);
});
it('"z" gt "z" is False', () => {
expect($b(gt._(_('z'))._(_('z')))).toBe(false);
expect($b(gt._(_c('z'))._(_c('z')))).toBe(false);
});
it('"z" gt "-" is True', () => {
expect($b(gt._(_('z'))._(_('-')))).toBe(true);
expect($b(gt._(_c('z'))._(_c('-')))).toBe(true);
});
it('"-" gt "z" is False', () => {
expect($b(gt._(_('-'))._(_('z')))).toBe(false);
expect($b(gt._(_c('-'))._(_c('z')))).toBe(false);
});
});
describe('show', () => {
it('show "0" is "\'0\'"', () => {
expect($s(show._(_c('0')))).toBe('\'0\'');
});
it('show "a" is "\'a\'"', () => {
expect($s(show._(_c('a')))).toBe('\'a\'');
});
it('show "-" is "\'-\'"', () => {
expect($s(show._(_c('-')))).toBe('\'-\'');
});
});
});

@ -2,8 +2,10 @@ import { describe, expect, it } from '@jest/globals';
import { toNative as $$, L, _, fromNative 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, 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, get, gt, head, le, lt, map, set, tail, update } 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, gt as ngt, show as nshow, odd, succ, sum } from '../src/num';
import { toChar as $c } from '../src/char';
import { toArray as $a, Cons, List, Nil, fromArray as _a, all, any, append, cmp, concat, cons, eq, filter, foldl, foldlz, foldr, foldrz, ge, get, gt, head, intersperse, le, len, lt, map, nul, set, show, snoc, tail, update } from '../src/list';
import { toString as $s } from '../src/string';
describe('List', () => {
const iterate: (n: Num) => List<Num> = n => new L(() => Cons._(n)._(iterate(Succ._(n))).value);
@ -61,21 +63,94 @@ describe('List', () => {
});
});
describe('snoc', () => {
it('Nil snoc 0 is [0]', () => {
expect($na(snoc._(Nil)._(_n(0)))).toEqual([0]);
});
it('[1] snoc 0 is [1, 0]', () => {
expect($na(snoc._(_na([1]))._(_n(0)))).toEqual([1, 0]);
});
it('[1, 2] snoc 0 is [1, 2, 0]', () => {
expect($na(snoc._(_na([1, 2]))._(_n(0)))).toEqual([1, 2, 0]);
});
it('handles infinite lists', () => {
expect($n(snoc._(infinite)._(_n(0))._(undef)._(_(x => _(_xs => x))))).toBe(0);
});
});
describe('nul', () => {
it('nul Nil is True', () => {
expect($b(nul._(_na([])))).toEqual(true);
});
it('nul [1] is False', () => {
expect($b(nul._(_na([1])))).toEqual(false);
});
it('nul [1, 2] is False', () => {
expect($b(nul._(_na([1, 2])))).toEqual(false);
});
it('handles infinite lists', () => {
expect($b(nul._(infinite))).toEqual(false);
});
});
describe('len', () => {
it('len Nil is 0', () => {
expect($n(len._(_na([])))).toEqual(0);
});
it('len [1] is 1', () => {
expect($n(len._(_na([1])))).toEqual(1);
});
it('len [1, 2] is 2', () => {
expect($n(len._(_na([1, 2])))).toEqual(2);
});
it('handles infinite lists', () => {
expect($b(ngt._(len._(infinite))._(Zero))).toEqual(true);
});
});
describe('append', () => {
it('Nil append Nil is Nil', () => {
expect($na(append._(Nil)._(Nil))).toEqual([]);
});
it('[0] append [1] is [0, 1]', () => {
expect($na(append._(_na([0]))._(_na([1])))).toEqual([0, 1]);
});
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]);
});
it('handles infinite lists', () => {
expect($n(append._(infinite)._(infinite)._(undef)._(_(x => _(_xs => x))))).toBe(0);
});
});
describe('concat', () => {
it('Nil concat Nil is Nil', () => {
expect($na(concat._(Nil)._(Nil))).toEqual([]);
it('concat [Nil, Nil, Nil] is Nil', () => {
expect($na(concat._(cons._(Nil)._(cons._(Nil)._(cons._(Nil)._(Nil)))))).toEqual([]);
});
it('[0] concat [1] is [0, 1]', () => {
expect($na(concat._(_na([0]))._(_na([1])))).toEqual([0, 1]);
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]);
});
it('[0, 1] concat [2, 3] is [0, 1, 2, 3]', () => {
expect($na(concat._(_na([0, 1]))._(_na([2, 3])))).toEqual([0, 1, 2, 3]);
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]);
});
it('handles infinite lists', () => {
expect($n(concat._(infinite)._(infinite)._(undef)._(_(x => _(_xs => x))))).toBe(0);
const dinfinite: List<Num> = cons._(infinite)._(new L(() => dinfinite.value));
expect($n(concat._(dinfinite)._(undef)._(_(x => _(_xs => x))))).toBe(0);
});
});
@ -583,4 +658,40 @@ describe('List', () => {
expect($n(get._(_n(4))._(update._(succ)._(_n(4))._(infinite)))).toBe(5);
});
});
describe('intersperse', () => {
it('0 intersperse Nil is Nil', () => {
expect($na(intersperse._(_n(0))._(Nil))).toEqual([]);
});
it('0 intersperse [1] is [1]', () => {
expect($na(intersperse._(_n(0))._(_na([1])))).toEqual([1]);
});
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]);
});
it('handles infinite lists', () => {
expect($n(head._(intersperse._(_n(0))._(infinite)))).toBe(0);
});
});
describe('show', () => {
it('show Nil is "[]"', () => {
expect($s(show._(nshow)._(_na([])))).toBe('[]');
});
it('show [0] is "[0]"', () => {
expect($s(show._(nshow)._(_na([0])))).toBe('[0]');
});
it('show [0, 1, 2] is "[0, 1, 2]"', () => {
expect($s(show._(nshow)._(_na([0, 1, 2])))).toBe('[0, 1, 2]');
});
it('handles infinite lists', () => {
expect($c(head._(show._(nshow)._(infinite)))).toBe('[');
});
});
});

@ -2,50 +2,51 @@ 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 _, cmp, div, eq, ge, gt, ifz, le, lt, mod, mul, pred, 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';
describe('Num', () => {
const infinity: Num = new L(() => Succ._(infinity).value);
describe('toNumber', () => {
it('converts 0', () => {
expect($(Zero)).toBe(0);
expect($n(Zero)).toBe(0);
});
it('converts 1', () => {
expect($(Succ._(Zero))).toBe(1);
expect($n(Succ._(Zero))).toBe(1);
});
it('converts 2', () => {
expect($(Succ._(Succ._(Zero)))).toBe(2);
expect($n(Succ._(Succ._(Zero)))).toBe(2);
});
});
describe('fromNumber', () => {
it('converts 0', () => {
expect($(_(0))).toBe(0);
expect($n(_n(0))).toBe(0);
});
it('converts 1', () => {
expect($(_(1))).toBe(1);
expect($n(_n(1))).toBe(1);
});
it('converts 2', () => {
expect($(_(2))).toBe(2);
expect($n(_n(2))).toBe(2);
});
});
describe('ifz', () => {
it('returns zero branch', () => {
expect($b(ifz._(_(0))._(_b(true))._(_b(false)))).toBe(true);
expect($b(ifz._(_n(0))._(_b(true))._(_b(false)))).toBe(true);
});
it('returns non-zero branch', () => {
expect($b(ifz._(_(1))._(_b(true))._(_b(false)))).toBe(false);
expect($b(ifz._(_n(1))._(_b(true))._(_b(false)))).toBe(false);
});
it('returns non-zero branch', () => {
expect($b(ifz._(_(10))._(_b(true))._(_b(false)))).toBe(false);
expect($b(ifz._(_n(10))._(_b(true))._(_b(false)))).toBe(false);
});
it('handles infinity', () => {
@ -55,333 +56,351 @@ describe('Num', () => {
describe('succ', () => {
it('succ 0 is 1', () => {
expect($(succ._(_(0)))).toBe(1);
expect($n(succ._(_n(0)))).toBe(1);
});
it('succ 1 is 2', () => {
expect($(succ._(_(1)))).toBe(2);
expect($n(succ._(_n(1)))).toBe(2);
});
it('succ 10 is 11', () => {
expect($(succ._(_(10)))).toBe(11);
expect($n(succ._(_n(10)))).toBe(11);
});
});
describe('pred', () => {
it('pred 0 is 0', () => {
expect($(pred._(_(0)))).toBe(0);
expect($n(pred._(_n(0)))).toBe(0);
});
it('pred 1 is 0', () => {
expect($(pred._(_(1)))).toBe(0);
expect($n(pred._(_n(1)))).toBe(0);
});
it('pred 10 is 9', () => {
expect($(pred._(_(10)))).toBe(9);
expect($n(pred._(_n(10)))).toBe(9);
});
});
describe('cmp', () => {
it('0 cmp 0 is EQ', () => {
expect($o(cmp._(_(0))._(_(0)))).toBe(NOrd.EQ);
expect($o(cmp._(_n(0))._(_n(0)))).toBe(NOrd.EQ);
});
it('0 cmp 1 is LT', () => {
expect($o(cmp._(_(0))._(_(1)))).toBe(NOrd.LT);
expect($o(cmp._(_n(0))._(_n(1)))).toBe(NOrd.LT);
});
it('1 cmp 0 is GT', () => {
expect($o(cmp._(_(1))._(_(0)))).toBe(NOrd.GT);
expect($o(cmp._(_n(1))._(_n(0)))).toBe(NOrd.GT);
});
it('3 cmp 3 is EQ', () => {
expect($o(cmp._(_(3))._(_(3)))).toBe(NOrd.EQ);
expect($o(cmp._(_n(3))._(_n(3)))).toBe(NOrd.EQ);
});
it('3 cmp 7 is LT', () => {
expect($o(cmp._(_(3))._(_(7)))).toBe(NOrd.LT);
expect($o(cmp._(_n(3))._(_n(7)))).toBe(NOrd.LT);
});
it('7 cmp 3 is GT', () => {
expect($o(cmp._(_(7))._(_(3)))).toBe(NOrd.GT);
expect($o(cmp._(_n(7))._(_n(3)))).toBe(NOrd.GT);
});
it('handles infinity', () => {
expect($o(cmp._(_(7))._(infinity))).toBe(NOrd.LT);
expect($o(cmp._(infinity)._(_(7)))).toBe(NOrd.GT);
expect($o(cmp._(_n(7))._(infinity))).toBe(NOrd.LT);
expect($o(cmp._(infinity)._(_n(7)))).toBe(NOrd.GT);
});
});
describe('lt', () => {
it('0 lt 0 is False', () => {
expect($b(lt._(_(0))._(_(0)))).toBe(false);
expect($b(lt._(_n(0))._(_n(0)))).toBe(false);
});
it('0 lt 1 is True', () => {
expect($b(lt._(_(0))._(_(1)))).toBe(true);
expect($b(lt._(_n(0))._(_n(1)))).toBe(true);
});
it('1 lt 0 is False', () => {
expect($b(lt._(_(1))._(_(0)))).toBe(false);
expect($b(lt._(_n(1))._(_n(0)))).toBe(false);
});
it('3 lt 3 is False', () => {
expect($b(lt._(_(3))._(_(3)))).toBe(false);
expect($b(lt._(_n(3))._(_n(3)))).toBe(false);
});
it('3 lt 7 is True', () => {
expect($b(lt._(_(3))._(_(7)))).toBe(true);
expect($b(lt._(_n(3))._(_n(7)))).toBe(true);
});
it('7 lt 3 is False', () => {
expect($b(lt._(_(7))._(_(3)))).toBe(false);
expect($b(lt._(_n(7))._(_n(3)))).toBe(false);
});
it('handles infinity', () => {
expect($b(lt._(_(7))._(infinity))).toBe(true);
expect($b(lt._(infinity)._(_(7)))).toBe(false);
expect($b(lt._(_n(7))._(infinity))).toBe(true);
expect($b(lt._(infinity)._(_n(7)))).toBe(false);
});
});
describe('le', () => {
it('0 le 0 is True', () => {
expect($b(le._(_(0))._(_(0)))).toBe(true);
expect($b(le._(_n(0))._(_n(0)))).toBe(true);
});
it('0 le 1 is True', () => {
expect($b(le._(_(0))._(_(1)))).toBe(true);
expect($b(le._(_n(0))._(_n(1)))).toBe(true);
});
it('1 le 0 is False', () => {
expect($b(le._(_(1))._(_(0)))).toBe(false);
expect($b(le._(_n(1))._(_n(0)))).toBe(false);
});
it('3 le 3 is True', () => {
expect($b(le._(_(3))._(_(3)))).toBe(true);
expect($b(le._(_n(3))._(_n(3)))).toBe(true);
});
it('3 le 7 is True', () => {
expect($b(le._(_(3))._(_(7)))).toBe(true);
expect($b(le._(_n(3))._(_n(7)))).toBe(true);
});
it('7 le 3 is False', () => {
expect($b(le._(_(7))._(_(3)))).toBe(false);
expect($b(le._(_n(7))._(_n(3)))).toBe(false);
});
it('handles infinity', () => {
expect($b(le._(_(7))._(infinity))).toBe(true);
expect($b(le._(infinity)._(_(7)))).toBe(false);
expect($b(le._(_n(7))._(infinity))).toBe(true);
expect($b(le._(infinity)._(_n(7)))).toBe(false);
});
});
describe('eq', () => {
it('0 eq 0 is True', () => {
expect($b(eq._(_(0))._(_(0)))).toBe(true);
expect($b(eq._(_n(0))._(_n(0)))).toBe(true);
});
it('0 eq 1 is False', () => {
expect($b(eq._(_(0))._(_(1)))).toBe(false);
expect($b(eq._(_n(0))._(_n(1)))).toBe(false);
});
it('1 eq 0 is False', () => {
expect($b(eq._(_(1))._(_(0)))).toBe(false);
expect($b(eq._(_n(1))._(_n(0)))).toBe(false);
});
it('3 eq 3 is True', () => {
expect($b(eq._(_(3))._(_(3)))).toBe(true);
expect($b(eq._(_n(3))._(_n(3)))).toBe(true);
});
it('3 eq 7 is False', () => {
expect($b(eq._(_(3))._(_(7)))).toBe(false);
expect($b(eq._(_n(3))._(_n(7)))).toBe(false);
});
it('7 eq 3 is False', () => {
expect($b(eq._(_(7))._(_(3)))).toBe(false);
expect($b(eq._(_n(7))._(_n(3)))).toBe(false);
});
it('handles infinity', () => {
expect($b(eq._(_(7))._(infinity))).toBe(false);
expect($b(eq._(infinity)._(_(7)))).toBe(false);
expect($b(eq._(_n(7))._(infinity))).toBe(false);
expect($b(eq._(infinity)._(_n(7)))).toBe(false);
});
});
describe('ge', () => {
it('0 ge 0 is True', () => {
expect($b(ge._(_(0))._(_(0)))).toBe(true);
expect($b(ge._(_n(0))._(_n(0)))).toBe(true);
});
it('0 ge 1 is False', () => {
expect($b(ge._(_(0))._(_(1)))).toBe(false);
expect($b(ge._(_n(0))._(_n(1)))).toBe(false);
});
it('1 ge 0 is True', () => {
expect($b(ge._(_(1))._(_(0)))).toBe(true);
expect($b(ge._(_n(1))._(_n(0)))).toBe(true);
});
it('3 ge 3 is True', () => {
expect($b(ge._(_(3))._(_(3)))).toBe(true);
expect($b(ge._(_n(3))._(_n(3)))).toBe(true);
});
it('3 ge 7 is False', () => {
expect($b(ge._(_(3))._(_(7)))).toBe(false);
expect($b(ge._(_n(3))._(_n(7)))).toBe(false);
});
it('7 ge 3 is True', () => {
expect($b(ge._(_(7))._(_(3)))).toBe(true);
expect($b(ge._(_n(7))._(_n(3)))).toBe(true);
});
it('handles infinity', () => {
expect($b(ge._(_(7))._(infinity))).toBe(false);
expect($b(ge._(infinity)._(_(7)))).toBe(true);
expect($b(ge._(_n(7))._(infinity))).toBe(false);
expect($b(ge._(infinity)._(_n(7)))).toBe(true);
});
});
describe('gt', () => {
it('0 gt 0 is False', () => {
expect($b(gt._(_(0))._(_(0)))).toBe(false);
expect($b(gt._(_n(0))._(_n(0)))).toBe(false);
});
it('0 gt 1 is False', () => {
expect($b(gt._(_(0))._(_(1)))).toBe(false);
expect($b(gt._(_n(0))._(_n(1)))).toBe(false);
});
it('1 gt 0 is True', () => {
expect($b(gt._(_(1))._(_(0)))).toBe(true);
expect($b(gt._(_n(1))._(_n(0)))).toBe(true);
});
it('3 gt 3 is False', () => {
expect($b(gt._(_(3))._(_(3)))).toBe(false);
expect($b(gt._(_n(3))._(_n(3)))).toBe(false);
});
it('3 gt 7 is False', () => {
expect($b(gt._(_(3))._(_(7)))).toBe(false);
expect($b(gt._(_n(3))._(_n(7)))).toBe(false);
});
it('7 gt 3 is True', () => {
expect($b(gt._(_(7))._(_(3)))).toBe(true);
expect($b(gt._(_n(7))._(_n(3)))).toBe(true);
});
it('handles infinity', () => {
expect($b(gt._(_(7))._(infinity))).toBe(false);
expect($b(gt._(infinity)._(_(7)))).toBe(true);
expect($b(gt._(_n(7))._(infinity))).toBe(false);
expect($b(gt._(infinity)._(_n(7)))).toBe(true);
});
});
describe('sum', () => {
it('0 sum 0 is 0', () => {
expect($(sum._(_(0))._(_(0)))).toBe(0);
expect($n(sum._(_n(0))._(_n(0)))).toBe(0);
});
it('0 sum 1 is 1', () => {
expect($(sum._(_(0))._(_(1)))).toBe(1);
expect($n(sum._(_n(0))._(_n(1)))).toBe(1);
});
it('1 sum 0 is 1', () => {
expect($(sum._(_(1))._(_(0)))).toBe(1);
expect($n(sum._(_n(1))._(_n(0)))).toBe(1);
});
it('3 sum 4 is 7', () => {
expect($(sum._(_(3))._(_(4)))).toBe(7);
expect($n(sum._(_n(3))._(_n(4)))).toBe(7);
});
});
describe('sub', () => {
it('0 sub 0 is 0', () => {
expect($(sub._(_(0))._(_(0)))).toBe(0);
expect($n(sub._(_n(0))._(_n(0)))).toBe(0);
});
it('0 sub 1 is 0', () => {
expect($(sub._(_(0))._(_(1)))).toBe(0);
expect($n(sub._(_n(0))._(_n(1)))).toBe(0);
});
it('1 sub 0 is 1', () => {
expect($(sub._(_(1))._(_(0)))).toBe(1);
expect($n(sub._(_n(1))._(_n(0)))).toBe(1);
});
it('7 sub 4 is 3', () => {
expect($(sub._(_(7))._(_(4)))).toBe(3);
expect($n(sub._(_n(7))._(_n(4)))).toBe(3);
});
});
describe('mul', () => {
it('0 mul 0 is 0', () => {
expect($(mul._(_(0))._(_(0)))).toBe(0);
expect($n(mul._(_n(0))._(_n(0)))).toBe(0);
});
it('0 mul 10 is 0', () => {
expect($(mul._(_(0))._(_(10)))).toBe(0);
expect($n(mul._(_n(0))._(_n(10)))).toBe(0);
});
it('10 mul 0 is 0', () => {
expect($(mul._(_(1))._(_(0)))).toBe(0);
expect($n(mul._(_n(1))._(_n(0)))).toBe(0);
});
it('1 mul 10 is 10', () => {
expect($(mul._(_(1))._(_(10)))).toBe(10);
expect($n(mul._(_n(1))._(_n(10)))).toBe(10);
});
it('10 mul 1 is 10', () => {
expect($(mul._(_(10))._(_(1)))).toBe(10);
expect($n(mul._(_n(10))._(_n(1)))).toBe(10);
});
it('3 mul 4 is 12', () => {
expect($(mul._(_(3))._(_(4)))).toBe(12);
expect($n(mul._(_n(3))._(_n(4)))).toBe(12);
});
it('0 mul ignores second argument', () => {
expect($(mul._(_(0))._(undef))).toBe(0);
expect($n(mul._(_n(0))._(undef))).toBe(0);
});
});
describe('div', () => {
it('0 div 10 is 0', () => {
expect($(div._(_(0))._(_(10)))).toBe(0);
expect($n(div._(_n(0))._(_n(10)))).toBe(0);
});
it('1 div 10 is 0', () => {
expect($(div._(_(1))._(_(10)))).toBe(0);
expect($n(div._(_n(1))._(_n(10)))).toBe(0);
});
it('10 div 1 is 10', () => {
expect($(div._(_(10))._(_(1)))).toBe(10);
expect($n(div._(_n(10))._(_n(1)))).toBe(10);
});
it('10 div 5 is 2', () => {
expect($(div._(_(10))._(_(5)))).toBe(2);
expect($n(div._(_n(10))._(_n(5)))).toBe(2);
});
it('10 div 3 is 3', () => {
expect($(div._(_(10))._(_(3)))).toBe(3);
expect($n(div._(_n(10))._(_n(3)))).toBe(3);
});
it.failing('0 div ignores second argument', () => {
expect($(div._(_(0))._(undef))).toBe(0);
expect($n(div._(_n(0))._(undef))).toBe(0);
});
});
describe('mod', () => {
it('0 mod 10 is 0', () => {
expect($(mod._(_(0))._(_(10)))).toBe(0);
expect($n(mod._(_n(0))._(_n(10)))).toBe(0);
});
it('1 mod 10 is 1', () => {
expect($(mod._(_(1))._(_(10)))).toBe(1);
expect($n(mod._(_n(1))._(_n(10)))).toBe(1);
});
it('10 mod 1 is 0', () => {
expect($(mod._(_(10))._(_(1)))).toBe(0);
expect($n(mod._(_n(10))._(_n(1)))).toBe(0);
});
it('10 mod 5 is 0', () => {
expect($(mod._(_(10))._(_(5)))).toBe(0);
expect($n(mod._(_n(10))._(_n(5)))).toBe(0);
});
it('10 mod 3 is 1', () => {
expect($(mod._(_(10))._(_(3)))).toBe(1);
expect($n(mod._(_n(10))._(_n(3)))).toBe(1);
});
it.failing('0 mod ignores second argument', () => {
expect($(mod._(_(0))._(undef))).toBe(0);
expect($n(mod._(_n(0))._(undef))).toBe(0);
});
});
describe('show', () => {
it('show 0 is "0"', () => {
expect($s(show._(_n(0)))).toBe('0');
});
it('show 1 is "1"', () => {
expect($s(show._(_n(1)))).toBe('1');
});
it('show 255 is "255"', () => {
expect($s(show._(_n(255)))).toBe('255');
});
it('show 1000 is "1000"', () => {
expect($s(show._(_n(1000)))).toBe('1000');
});
});
});

@ -1,9 +1,10 @@
import { describe, expect, it } from '@jest/globals';
import { undef } from '../src/core';
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';
import { toBoolean as $b, fromBoolean as _b, cmp as bcmp, eq as beq, show as bshow, not } from '../src/bool';
import { toNumber as $n, fromNumber as _n, cmp as ncmp, eq as neq, show as nshow, succ } from '../src/num';
import { Pair, both, cmp, eq, first, fst, ge, gt, le, lt, second, show, snd } from '../src/pair';
import { toString as $s } from '../src/string';
describe('Pair', () => {
describe('fst', () => {
@ -208,4 +209,22 @@ describe('Pair', () => {
expect($b(gt._(bcmp)._(undef)._(Pair._(_b(false))._(undef))._(Pair._(_b(true))._(undef)))).toBe(false);
});
});
describe('show', () => {
it('show (False, 0) is "(False, 0)"', () => {
expect($s(show._(bshow)._(nshow)._(Pair._(_b(false))._(_n(0))))).toBe('(False, 0)');
});
it('show (False, 1) is "(False, 1)"', () => {
expect($s(show._(bshow)._(nshow)._(Pair._(_b(false))._(_n(1))))).toBe('(False, 1)');
});
it('show (True, 0) is "(True, 0)"', () => {
expect($s(show._(bshow)._(nshow)._(Pair._(_b(true))._(_n(0))))).toBe('(True, 0)');
});
it('show (True, 1) is "(True, 1)"', () => {
expect($s(show._(bshow)._(nshow)._(Pair._(_b(true))._(_n(1))))).toBe('(True, 1)');
});
});
});

@ -2,11 +2,12 @@ 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 { toNumber as $n, Zero, gt as ngt } from '../src/num';
import { toChar as $c, fromChar as _c } from '../src/char';
import { toString as $s, Cons, Empty, String, fromString as _s, cmp, concat, eq, ge, gt, le, lt } from '../src/string';
import { toString as $s, Cons, Empty, String, fromString as _s, append, cmp, empty, eq, ge, gt, le, len, lt, show } from '../src/string';
describe('String', () => {
const infinite: String = new L(() => Cons._(_c('a'))._(infinite).value); ;
const infinite: String = Cons._(_c('a'))._(new L(() => infinite.value));
describe('toString', () => {
it('converts ""', () => {
@ -36,21 +37,57 @@ describe('String', () => {
});
});
describe('concat', () => {
it('"" concat "" is ""', () => {
expect($s(concat._(Empty)._(Empty))).toBe('');
describe('empty', () => {
it('empty "" is True', () => {
expect($b(empty._(_s('')))).toEqual(true);
});
it('"a" concat "b" is "ab"', () => {
expect($s(concat._(_s('a'))._(_s('b')))).toBe('ab');
it('empty "a" is False', () => {
expect($b(empty._(_s('a')))).toEqual(false);
});
it('"abc" concat "def" is "abcdef"', () => {
expect($s(concat._(_s('abc'))._(_s('def')))).toBe('abcdef');
it('empty "ab" is False', () => {
expect($b(empty._(_s('ab')))).toEqual(false);
});
it('handles infinite lists', () => {
expect($b(empty._(infinite))).toEqual(false);
});
});
describe('len', () => {
it('len "" is 0', () => {
expect($n(len._(_s('')))).toEqual(0);
});
it('len "a" is 1', () => {
expect($n(len._(_s('a')))).toEqual(1);
});
it('len "ab" is 2', () => {
expect($n(len._(_s('ab')))).toEqual(2);
});
it('handles infinite lists', () => {
expect($b(ngt._(len._(infinite))._(Zero))).toEqual(true);
});
});
describe('append', () => {
it('"" append "" is ""', () => {
expect($s(append._(Empty)._(Empty))).toBe('');
});
it('"a" append "b" is "ab"', () => {
expect($s(append._(_s('a'))._(_s('b')))).toBe('ab');
});
it('"abc" append "def" is "abcdef"', () => {
expect($s(append._(_s('abc'))._(_s('def')))).toBe('abcdef');
});
it('handles infinite strings', () => {
expect($c(concat._(infinite)._(infinite)._(undef)._(_(x => _(_xs => x))))).toBe('a');
expect($c(append._(infinite)._(infinite)._(undef)._(_(x => _(_xs => x))))).toBe('a');
});
});
@ -287,4 +324,18 @@ describe('String', () => {
expect($b(gt._(infinite)._(_s('abc')))).toEqual(false);
});
});
describe('show', () => {
it('show "" is """"', () => {
expect($s(show._(_s('')))).toBe('""');
});
it('show "a" is ""a""', () => {
expect($s(show._(_s('a')))).toBe('"a"');
});
it('show "abc" is ""abc""', () => {
expect($s(show._(_s('abc')))).toBe('"abc"');
});
});
});

Loading…
Cancel
Save