UNPKG

spica

Version:

Supervisor, Coroutine, Channel, select, AtomicPromise, Cancellation, Cache, List, Queue, Stack, and some utils.

170 lines (144 loc) 5.09 kB
import { Sequence } from './sequence'; export const nat = new Sequence<number, number>((n = 0, cons) => cons(n, n + 1)); describe('Unit: lib/monad/sequence', () => { describe('Iterable', () => { it('idempotence', () => { const s = Sequence.from([0, 1, 2]); assert.deepStrictEqual([...s], [0, 1, 2]); assert.deepStrictEqual([...s], [0, 1, 2]); assert.deepStrictEqual(Sequence.from(s).extract(), [0, 1, 2]); assert.deepStrictEqual(Sequence.from(s).extract(), [0, 1, 2]); assert.deepStrictEqual([...s], [0, 1, 2]); assert.deepStrictEqual(Sequence.from(s).extract(), [0, 1, 2]); }); it('to Sequence', () => { assert.deepStrictEqual(Sequence.from(Sequence.from([])).extract(), []); assert.deepStrictEqual(Sequence.from(Sequence.from([0])).extract(), [0]); assert.deepStrictEqual(Sequence.from(Sequence.from([0, 1])).extract(), [0, 1]); assert.deepStrictEqual(Sequence.from(Sequence.from([0, 1, 2])).extract(), [0, 1, 2]); }); it('to Array', () => { assert.deepStrictEqual([...Sequence.from([])], []); assert.deepStrictEqual([...Sequence.from([0])], [0]); assert.deepStrictEqual([...Sequence.from([0, 1])], [0, 1]); assert.deepStrictEqual([...Sequence.from([0, 1, 2])], [0, 1, 2]); }); }); describe('Monoid', () => { it('Monoid law 1', () => { const x = Sequence.Return(0); const ma = Sequence.mappend(Sequence.mempty, x); assert.deepStrictEqual(ma.extract(), x.extract()); }); it('Monoid law 2', () => { const x = Sequence.Return(0); const ma = Sequence.mappend(x, Sequence.mempty); assert.deepStrictEqual(ma.extract(), x.extract()); }); it('Monoid law 3', () => { const x = Sequence.Return(0); const y = Sequence.Return(1); const z = Sequence.Return(2); const ma = Sequence.mappend(Sequence.mappend(x, y), z); const mb = Sequence.mappend(x, Sequence.mappend(y, z)); assert.deepStrictEqual(ma.extract(), mb.extract()); }); }); describe('Functor', () => { it('fmap', () => { assert.deepStrictEqual(Sequence.fmap(n => n + 1, Sequence.Return(0)).extract(), [1]); }); it('Functor law 1', () => { const f = <T>(n: T) => n; const x = 0; const fa = Sequence.Return(x).fmap(f); const fb = f(Sequence.Return(x)); assert.deepStrictEqual(fa.extract(), fb.extract()); }); it('Functor law 2', () => { const f = (n: number) => n + 2; const g = (n: number) => n * 3; const x = 1; const fa = Sequence.Return(x).fmap(n => g(f(n))); const fb = Sequence.Return(x).fmap(f).fmap(g); assert.deepStrictEqual(fa.extract(), fb.extract()); }); }); describe('Applicative', () => { it('ap 1', () => { assert.deepStrictEqual( Sequence.pure((a: number) => a) .ap(Sequence.pure(1)) .extract(), [1]); assert.deepStrictEqual( Sequence.pure((a: number) => a) .ap(Sequence.pure(1)) .extract(), [1]); }); it('ap 2', () => { assert.deepStrictEqual( Sequence.pure((a: number, b: number) => a + b) .ap(Sequence.pure(1)) .ap(Sequence.pure(2)) .extract(), [3]); }); it('ap 3', () => { assert.deepStrictEqual( Sequence.pure((a: number, b: number, c: number) => a + b + c) .ap(Sequence.pure(1)) .ap(Sequence.pure(2)) .ap(Sequence.pure(3)) .extract(), [6]); }); it('combination 1', () => { assert.deepStrictEqual( Sequence.from([(n: number) => n, (n: number) => -n]) .ap(Sequence.from([1, 2])) .extract(), [1, 2, -1, -2]); }); it('combination 2', () => { assert.deepStrictEqual( Sequence.from([(n: number, m: number) => n + m, (n: number, m: number) => n * m]) .ap(Sequence.from([1, 2])) .ap(Sequence.from([3, 4])) .extract(), [4, 5, 5, 6, 3, 4, 6, 8]); }); }); describe('Monad', () => { it('bind', () => { assert.deepStrictEqual(Sequence.bind(n => Sequence.Return(n + 1), Sequence.Return(0)).extract(), [1]); }); it('Monad law 1', () => { const f = (n: number) => Sequence.Return(n + 1); const x = 0; const ma = Sequence.Return(x).bind(f); const mb = f(x); assert.deepStrictEqual(ma.extract(), mb.extract()); }); it('Monad law 2', () => { const x = 0; const ma = Sequence.Return(x); const mb = ma.bind(Sequence.Return); assert.deepStrictEqual(ma.extract(), mb.extract()); }); it('Monad law 3', () => { const f = (n: number) => Sequence.Return(n + 2); const g = (n: number) => Sequence.Return(n * 3); const x = 1; const ma = Sequence.Return(x) .bind(f) .bind(g); const mb = Sequence.Return(x) .bind(x => f(x) .bind(g)); assert.deepStrictEqual(ma.extract(), mb.extract()); }); }); });