This repository has been archived by the owner on May 3, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add initial tests for datum and reader
- Loading branch information
Showing
4 changed files
with
169 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { assertEquals } from "https://deno.land/std/testing/asserts.ts"; | ||
|
||
import { assertMonad } from "./assert.ts"; | ||
import { constant } from "../fns.ts"; | ||
import * as D from "../datum.ts"; | ||
|
||
const add = (a: number, b: number) => a + b; | ||
const addOne = (n: number): number => n + 1; | ||
const one = constant(1); | ||
|
||
Deno.test({ | ||
name: "Datum Constructors", | ||
fn(): void { | ||
assertEquals(D.replete(1), { tag: "Replete", value: 1 }); | ||
assertEquals(D.initial, { tag: "Initial" }); | ||
}, | ||
}); | ||
|
||
Deno.test({ | ||
name: "Datum Destructors", | ||
fn(): void { | ||
const fold = D.fold(one, one, addOne, addOne); | ||
|
||
assertEquals(fold(D.replete(1)), 2); | ||
assertEquals(fold(D.initial), 1); | ||
}, | ||
}); | ||
|
||
Deno.test({ | ||
name: "Datum Guards", | ||
fn(): void { | ||
assertEquals(D.isSome(D.initial), false); | ||
assertEquals(D.isSome(D.replete(1)), true); | ||
assertEquals(D.isNone(D.initial), true); | ||
assertEquals(D.isNone(D.replete(1)), false); | ||
}, | ||
}); | ||
|
||
Deno.test({ | ||
name: "Datum Instances", | ||
fn(): void { | ||
// Test Laws | ||
assertMonad(D.Monad, "Datum"); | ||
|
||
// Monad Join | ||
const { join } = D.Monad; | ||
|
||
assertEquals(join(D.replete(D.replete(1))), D.replete(1)); | ||
assertEquals(join(D.replete(D.initial)), D.initial); | ||
assertEquals(join(D.initial), D.initial); | ||
|
||
// Foldable | ||
const { reduce } = D.Foldable; | ||
assertEquals(reduce(add, 0, D.replete(1)), 1); | ||
assertEquals(reduce(add, 0, D.initial), 0); | ||
|
||
// Traversable | ||
const { traverse } = D.Traversable; | ||
assertEquals( | ||
traverse(D.Applicative, (_) => D.replete(1), D.initial), | ||
D.replete(D.initial) | ||
); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { assertEquals } from "https://deno.land/std/testing/asserts.ts"; | ||
|
||
import * as R from "../reader.ts"; | ||
|
||
const fab = (n: number) => n + 1; | ||
const fbc = (n: number): string => n.toString(); | ||
const fgab = (f: typeof fbc) => (g: typeof fab) => (n: number) => f(g(n)); | ||
|
||
Deno.test({ | ||
name: "Reader Instances", | ||
fn(): void { | ||
const M = R.Monad; | ||
|
||
const fatb = (n: number) => M.of<number, number>(n + 1); | ||
const fbtc = (n: number) => M.of<number, string>(n.toString()); | ||
|
||
const famb = (n: number) => (n < 0 ? M.of(0) : M.of<number, number>(n)); | ||
const fbmc = (n: number) => M.of<number, string>(n.toString()); | ||
|
||
// Test Laws | ||
// Apply Composition: A.ap(A.ap(A.map(f => g => x => f(g(x)), a), u), v) ≡ A.ap(a, A.ap(u, v)) | ||
assertEquals( | ||
M.ap(M.ap(M.map(fgab, M.of(fbc)), M.of(fab)), M.of(1))(1), | ||
M.ap(M.of(fbc), M.ap(M.of(fab), M.of(1)))(1), | ||
`Reader : Apply Composition` | ||
); | ||
|
||
// Functor Identity: F.map(x => x, a) ≡ a | ||
assertEquals( | ||
M.map((n: number) => n, M.of(1))(1), | ||
M.of(1)(1), | ||
`Reader : Functor Identity` | ||
); | ||
|
||
// Functor Composition: F.map(x => f(g(x)), a) ≡ F.map(f, F.map(g, a)) | ||
assertEquals( | ||
M.map((x: number) => fbc(fab(x)), M.of(1))(1), | ||
M.map(fbc, M.map(fab, M.of(1)))(1), | ||
`Reader : Functor Composition` | ||
); | ||
|
||
// Applicative Identity: A.ap(A.of(x => x), v) ≡ v | ||
assertEquals( | ||
M.ap( | ||
M.of((n: number) => n), | ||
M.of(1) | ||
)(1), | ||
M.of(1)(1), | ||
`Reader : Applicative Identity` | ||
); | ||
|
||
// Applicative Homomorphism: M.ap(A.of(f), A.of(x)) ≡ A.of(f(x)) | ||
assertEquals( | ||
M.ap(M.of(fab), M.of(1))(1), | ||
M.of(fab(1))(1), | ||
`Reader : Applicative Homomorphism` | ||
); | ||
|
||
// Applicative Interchange: A.ap(u, A.of(y)) ≡ A.ap(A.of(f => f(y)), u) | ||
assertEquals( | ||
M.ap(M.of(fab), M.of(2))(1), | ||
M.ap( | ||
M.of((f: typeof fab) => f(2)), | ||
M.of(fab) | ||
)(1), | ||
`Reader : Applicative Interchange` | ||
); | ||
|
||
// Chain Associativity: M.chain(g, M.chain(f, u)) ≡ M.chain(x => M.chain(g, f(x)), u) | ||
assertEquals( | ||
M.chain(fbtc, M.chain(fatb, M.of(1)))(1), | ||
M.chain((x) => M.chain(fbtc, fatb(x)), M.of<number, number>(1))(1), | ||
`Reader : Chain Associativity` | ||
); | ||
|
||
// Monad Left Identity: M.chain(f, M.of(a)) ≡ f(a) | ||
assertEquals( | ||
M.chain(famb, M.of(1))(1), | ||
famb(1)(1), | ||
`Reader : Monad Left Identity` | ||
); | ||
|
||
// Monad Right Identity: M.chain(M.of, u) ≡ u | ||
assertEquals( | ||
M.chain(M.of, M.of<number, number>(1))(1), | ||
M.of(1)(1), | ||
`Reader : Monad Right Identity` | ||
); | ||
|
||
// Monad Associativity: M.chain(b => Mc, M.chain(a => Mb, Ma)) === M.chain(a => M.chain(b => Mc, (a => Mb)(a)), Ma) | ||
assertEquals( | ||
M.chain(fbmc, M.chain(famb, M.of(1)))(1), | ||
M.chain((a) => M.chain(fbmc, famb(a)), M.of<number, number>(1))(1), | ||
`Reader : Monad Associativity 1` | ||
); | ||
|
||
assertEquals( | ||
M.chain(fbmc, M.chain(famb, M.of(-1)))(1), | ||
M.chain((a) => M.chain(fbmc, famb(a)), M.of<number, number>(-1))(1), | ||
`Reader : Monad Associativity 2` | ||
); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters