|
|
|
|
@ -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); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|