You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
6.3 KiB
208 lines
6.3 KiB
import { describe, expect, it } from '@jest/globals';
|
|
import { L, toNative } from '../src/core';
|
|
import { toNumber as $n, Num, Succ, Zero, fromNumber as _n, odd, succ, sum } from '../src/num';
|
|
import { toArray as $, toNumberArray as $na, Cons, List, Nil, fromArray as _, fromNumberArray as _na, filter, foldl, foldlz, foldr, foldrz, head, map, tail } from '../src/list';
|
|
|
|
describe('List', () => {
|
|
const iterate: (n: Num) => List<Num> = n => new L(() => Cons._(n)._(iterate(Succ._(n))).value);
|
|
|
|
describe('toArray', () => {
|
|
it('converts []', () => {
|
|
expect($(Nil)).toEqual([]);
|
|
});
|
|
|
|
it('converts [0]', () => {
|
|
expect($(Cons._(_n(0))._(Nil)).map($n)).toEqual([0]);
|
|
});
|
|
|
|
it('converts [0, 1]', () => {
|
|
expect($(Cons._(_n(0))._(Cons._(_n(1))._(Nil))).map($n)).toEqual([0, 1]);
|
|
});
|
|
});
|
|
|
|
describe('fromArray', () => {
|
|
it('converts []', () => {
|
|
expect($(_([]))).toEqual([]);
|
|
});
|
|
|
|
it('converts [0]', () => {
|
|
expect($(_([0].map(_n))).map($n)).toEqual([0]);
|
|
});
|
|
|
|
it('converts 2', () => {
|
|
expect($(_([0, 1].map(_n))).map($n)).toEqual([0, 1]);
|
|
});
|
|
});
|
|
|
|
describe('head', () => {
|
|
it('returns nothing from empty list', () => {
|
|
expect(() => head._(Nil)).not.toThrow();
|
|
expect(() => toNative(head._(Nil))).toThrow();
|
|
});
|
|
|
|
it('returns only item', () => {
|
|
expect(head).toDeferEvaluationOf(_na([0]));
|
|
expect($n(head._(_na([0])))).toBe(0);
|
|
});
|
|
|
|
it('returns first item', () => {
|
|
expect(head).toDeferEvaluationOf(_na([0, 1]));
|
|
expect($n(head._(_na([0, 1])))).toBe(0);
|
|
});
|
|
|
|
it('handles infinite lists', () => {
|
|
expect($n(head._(iterate(Zero)))).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('tail', () => {
|
|
it('drops nothing from empty list', () => {
|
|
expect(() => tail._(Nil)).not.toThrow();
|
|
expect(() => $na(tail._(Nil))).toThrow();
|
|
});
|
|
|
|
it('drops only item', () => {
|
|
expect(tail).toDeferEvaluationOf(_na([0]));
|
|
expect($na(tail._(_na([0])))).toEqual([]);
|
|
});
|
|
|
|
it('drops first item', () => {
|
|
expect(tail).toDeferEvaluationOf(_na([0, 1]));
|
|
expect($na(tail._(_na([0, 1])))).toEqual([1]);
|
|
});
|
|
|
|
it('handles infinite lists', () => {
|
|
expect($n(head._(tail._(iterate(Zero))))).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('foldl', () => {
|
|
it('folds empty list', () => {
|
|
expect(foldl._(sum)).toDeferEvaluationOf(Zero, _na([]));
|
|
expect($n(foldl._(sum)._(Zero)._(_na([])))).toBe(0);
|
|
});
|
|
|
|
it('folds single item', () => {
|
|
expect(foldl._(sum)).toDeferEvaluationOf(Zero, _na([1]));
|
|
expect($n(foldl._(sum)._(Zero)._(_na([1])))).toBe(1);
|
|
});
|
|
|
|
it('folds several items', () => {
|
|
expect(foldl._(sum)).toDeferEvaluationOf(Zero, _na([1, 2]));
|
|
expect($n(foldl._(sum)._(Zero)._(_na([1, 2])))).toBe(3);
|
|
});
|
|
});
|
|
|
|
describe('foldlz', () => {
|
|
it('does not fold empty list', () => {
|
|
expect(() => foldlz._(sum)._(Nil)).not.toThrow();
|
|
expect(() => $n(foldlz._(sum)._(Nil))).toThrow();
|
|
});
|
|
|
|
it('folds single item', () => {
|
|
expect(foldlz._(sum)).toDeferEvaluationOf(_na([1]));
|
|
expect($n(foldlz._(sum)._(_na([1])))).toBe(1);
|
|
});
|
|
|
|
it('folds several items', () => {
|
|
expect(foldlz._(sum)).toDeferEvaluationOf(_na([1, 2]));
|
|
expect($n(foldlz._(sum)._(_na([1, 2])))).toBe(3);
|
|
});
|
|
});
|
|
|
|
describe('foldr', () => {
|
|
it('folds empty list', () => {
|
|
expect(foldr._(sum)).toDeferEvaluationOf(Zero, _na([]));
|
|
expect($n(foldr._(sum)._(Zero)._(_na([])))).toBe(0);
|
|
});
|
|
|
|
it('folds single item', () => {
|
|
expect(foldr._(sum)).toDeferEvaluationOf(Zero, _na([1]));
|
|
expect($n(foldr._(sum)._(Zero)._(_na([1])))).toBe(1);
|
|
});
|
|
|
|
it('folds several items', () => {
|
|
expect(foldr._(sum)).toDeferEvaluationOf(Zero, _na([1, 2]));
|
|
expect($n(foldr._(sum)._(Zero)._(_na([1, 2])))).toBe(3);
|
|
});
|
|
|
|
// it('handles infinite lists', () => {
|
|
// expect(foldr<Lazy<number>, Lazy<number>>(x => _(a =>
|
|
// iif<Lazy<number>>
|
|
// (x.call(x => fromBoolean(x === 0)))
|
|
// .call(
|
|
// (x).call(
|
|
// (x.call(x => a.call(a => _(x + a)))))))
|
|
// ).call((fromNumber(0)).call((iterate(-5))))).toEvaluateTo(-15);
|
|
// });
|
|
});
|
|
|
|
describe('foldrz', () => {
|
|
it('does not fold empty list', () => {
|
|
expect(() => foldrz._(sum)._(Nil)).not.toThrow();
|
|
expect(() => $n(foldrz._(sum)._(Nil))).toThrow();
|
|
});
|
|
|
|
it.failing('folds single item', () => {
|
|
expect(foldrz._(sum)).toDeferEvaluationOf(_na([1]));
|
|
expect($n(foldrz._(sum)._(_na([1])))).toBe(1);
|
|
});
|
|
|
|
it.failing('folds several items', () => {
|
|
expect(foldrz._(sum)).toDeferEvaluationOf(_na([1, 2]));
|
|
expect($n(foldrz._(sum)._(_na([1, 2])))).toBe(3);
|
|
});
|
|
|
|
// it.failing('handles infinite lists', () => {
|
|
// expect(foldrz<Lazy<number>>(x => _(a =>
|
|
// iif<Lazy<number>>
|
|
// (x.call(x => fromBoolean(x === 0)))
|
|
// .call(
|
|
// (x).call(
|
|
// (x.call(x => a.call(a => _(x + a)))))))
|
|
// ).call((iterate(-5)))).toEvaluateTo(-10);
|
|
// });
|
|
});
|
|
|
|
describe('map', () => {
|
|
it('maps empty list', () => {
|
|
expect(map._(succ)).toDeferEvaluationOf(_na([]));
|
|
expect($na(map._(succ)._(_na([])))).toEqual([]);
|
|
});
|
|
|
|
it('maps only item', () => {
|
|
expect(map._(succ)).toDeferEvaluationOf(_na([0]));
|
|
expect($na(map._(succ)._(_na([0])))).toEqual([1]);
|
|
});
|
|
|
|
it('maps several items', () => {
|
|
expect(map._(succ)).toDeferEvaluationOf(_na([0, 1]));
|
|
expect($na(map._(succ)._(_na([0, 1])))).toEqual([1, 2]);
|
|
});
|
|
|
|
it('handles infinite lists', () => {
|
|
expect($n(head._(map._(succ)._(iterate(Zero))))).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('filter', () => {
|
|
it('filter empty list', () => {
|
|
expect(filter._(odd)).toDeferEvaluationOf(_na([]));
|
|
expect($na(filter._(odd)._(_na([])))).toEqual([]);
|
|
});
|
|
|
|
it('filters only item', () => {
|
|
expect(filter._(odd)).toDeferEvaluationOf(_na([0]));
|
|
expect($na(filter._(odd)._(_na([])))).toEqual([]);
|
|
});
|
|
|
|
it('filters several items', () => {
|
|
expect(filter._(odd)).toDeferEvaluationOf(_na([0, 1]));
|
|
expect($na(filter._(odd)._(_na([0, 1])))).toEqual([1]);
|
|
});
|
|
|
|
it('handles infinite lists', () => {
|
|
expect($n(head._(filter._(odd)._(iterate(Zero))))).toBe(1);
|
|
});
|
|
});
|
|
});
|
|
|