pragmatic-fp-ts
Version:
Opinionated functional programming library with easy use in mind
163 lines (141 loc) • 4.72 kB
text/typescript
import * as l from "../main.ts";
import {
Chain,
chain,
either,
identity,
Just,
just,
Left,
left,
maybe,
Nothing,
nothing,
Right,
right,
M,
} from "../main.ts";
describe("monads", () => {
describe("Maybe", () => {
expect(maybe(1)).toBeInstanceOf(Just);
expect(maybe(null)).toBeInstanceOf(Nothing);
expect(maybe(undefined)).toBeInstanceOf(Nothing);
expect(just(4).bind(() => null)).toBeInstanceOf(Nothing);
expect(nothing().bind(() => 1)).toBeInstanceOf(Nothing);
expect(
just("just")
.match({ just: identity, nothing: () => "nothing" })
.getValue()
).toBe("just");
expect(
nothing()
.match({ just: identity, nothing: () => "nothing" })
.getValue()
).toBe("nothing");
expect(just(1).filter(() => true)).toBeInstanceOf(Just);
expect(just(1).filter(() => false)).toBeInstanceOf(Nothing);
expect(nothing().filter(() => true)).toBeInstanceOf(Nothing);
const x = maybe([1, 2, 3])
._(l.find(l.eq(4)))
._(l.add(3));
expect(x).toBeInstanceOf(Nothing);
});
describe("Either", () => {
expect(either(1)).toBeInstanceOf(Right);
expect(either(null)).toBeInstanceOf(Left);
expect(either(undefined)).toBeInstanceOf(Left);
expect(right(4).bind(() => null)).toBeInstanceOf(Left);
expect(left("Error").bind(() => 1)).toBeInstanceOf(Left);
expect(
right("right")
.match({ right: identity, left: () => "left" })
.getValue()
).toBe("right");
expect(
left("Error")
.match({ right: identity, left: () => "left" })
.getValue()
).toBe("left");
expect(right(1).filter(() => true)).toBeInstanceOf(Right);
expect(right(1).filter(() => false)).toBeInstanceOf(Left);
expect(left("Error").filter(() => true)).toBeInstanceOf(Left);
});
describe("transformers", () => {
it("transforms Maybe to Chain", () => {
expect(just(5).to(chain)).toBeInstanceOf(Chain);
expect(nothing().to(chain)).toBeInstanceOf(Chain);
expect(nothing().to(chain).getValue()).toBe(null);
});
it("transforms Maybe to Either", () => {
expect(just(5).to(either)).toBeInstanceOf(Right);
expect(just(null).to(either)).toBeInstanceOf(Left);
});
it("transforms Chain to Maybe", () => {
expect(chain(1).to(maybe)).toBeInstanceOf(Just);
expect(chain(null).to(maybe)).toBeInstanceOf(Nothing);
});
it("transforms Chain to Either", () => {
expect(chain(1).to(either)).toBeInstanceOf(Right);
expect(chain(null).to(either)).toBeInstanceOf(Left);
});
it("transforms Either to Chain", () => {
expect(left(1).to(chain)).toBeInstanceOf(Chain);
expect(right(1).to(chain)).toBeInstanceOf(Chain);
});
it("transforms Either to Maybe", () => {
expect(left(1).to(maybe)).toBeInstanceOf(Nothing);
expect(right(1).to(maybe)).toBeInstanceOf(Just);
});
});
});
describe("generic monad functions", () => {
describe("bind()", () => {
it("should map just", () => {
const j = M.bind((x: number) => x + 1)(just(1));
expect(j.isJust()).toBe(true);
expect(j.getValue()).toBe(2);
});
it("should map nothing", () => {
const j = M.bind((x: number) => x + 1)(nothing<number>());
expect(j.isNothing()).toBe(true);
});
it("should map right", () => {
const j = M.bind((x: number) => x + 1)(right<number, any>(1));
expect(j.isRight()).toBe(true);
expect(j.getValue()).toBe(2);
});
it("should map left", () => {
const j = M.bind((x: number) => x + 1)(left<any, any>(1));
expect(j.isLeft()).toBe(true);
});
it("should map chain", () => {
const j = M.bind((x: number) => x + 1)(chain(1));
expect(j.getValue()).toBe(2);
});
});
describe("bindM()", () => {
it("should map just", () => {
const j = M.bindM((x: number) => just(x + 1))(just(1));
console.log({ j });
expect(j.isJust()).toBe(true);
expect(j.getValue()).toBe(2);
});
it("should map nothing", () => {
const j = M.bindM((x: number) => just(x + 1))(nothing<number>());
expect(j.isNothing()).toBe(true);
});
it("should map right", () => {
const j = M.bindM((x: number) => right(x + 1))(right<number, any>(1));
expect(j.isRight()).toBe(true);
expect(j.getValue()).toBe(2);
});
it("should map left", () => {
const j = M.bindM((x: number) => left(x + 1))(right<any, any>(1));
expect(j.isLeft()).toBe(true);
});
it("should map chain", () => {
const j = M.bindM((x: number) => chain(x + 1))(chain(1));
expect(j.getValue()).toBe(2);
});
});
});