diff --git a/reader.ts b/reader.ts index 953a894..0df500d 100644 --- a/reader.ts +++ b/reader.ts @@ -29,6 +29,8 @@ declare module "./hkt.ts" { * Constructors ******************************************************************************/ +export const make: (r: R) => Reader = constant; + export const ask: () => Reader = () => identity; export const asks: (f: (r: R) => A) => Reader = identity; @@ -42,7 +44,7 @@ export const Functor: TC.Functor = { }; export const Apply: TC.Apply = { - ap: (tfab) => (ta) => (r) => pipe(ta(r), tfab(r)), + ap: (tfai) => (ta) => (r) => pipe(ta(r), tfai(r)), map: Functor.map, }; diff --git a/testing/assert.ts b/testing/assert.ts index 48f6c3c..1eb8725 100644 --- a/testing/assert.ts +++ b/testing/assert.ts @@ -33,7 +33,7 @@ export type MonadTest< * Utility Functions ******************************************************************************/ -export const add = (n: number) => n + n; +export const add = (n: number) => n + 1; export const multiply = (n: number) => n * n; @@ -830,45 +830,3 @@ export const assertComonad = < * Assert: Traversable * TODO ******************************************************************************/ - -/******************************************************************************* - * Assert: Monad Helper - ******************************************************************************/ - -export const testMonad = async ( - M: TC.Monad, - // deno-lint-ignore no-explicit-any - eq: ( - a: Kind, - b: Kind, - ) => Promise, -) => { - const ta = M.of(1); - const tb = M.of(2); - const fai = (n: number) => n + 1; - const tfai = M.of(fai); - const fati = (n: number) => M.of(n + 1); - - // of - assertEquals(await eq(ta, ta), true); - assertEquals(await eq(ta, tb), false); - - // ap - const r1 = pipe(ta, M.ap(tfai)); - assertEquals(await eq(r1, ta), false); - assertEquals(await eq(r1, tb), true); - - // map - const r2 = pipe(ta, M.map(fai)); - assertEquals(await eq(r2, ta), false); - assertEquals(await eq(r2, tb), true); - - // join - assertEquals(await eq(M.join(M.of(ta)), ta), true); - assertEquals(await eq(M.join(M.of(ta)), tb), false); - - // chain - const r3 = pipe(ta, M.chain(fati)); - assertEquals(await eq(r3, ta), false); - assertEquals(await eq(r3, tb), true); -}; diff --git a/testing/either.test.ts b/testing/either.test.ts index 358cd73..00d0b02 100644 --- a/testing/either.test.ts +++ b/testing/either.test.ts @@ -1,7 +1,5 @@ import { assertEquals } from "https://deno.land/std/testing/asserts.ts"; -import type * as HKT from "../hkt.ts"; - import * as E from "../either.ts"; import * as O from "../option.ts"; import { ordNumber } from "../ord.ts"; @@ -205,7 +203,6 @@ Deno.test("Either getRightMonoid", () => { Deno.test("Either getRightMonad", () => { const Monad = E.getRightMonad(semigroupSum); - const { equals } = E.getSetoid(setoidNumber, setoidNumber); AS.assertMonad(Monad, { a: 1, @@ -217,8 +214,6 @@ Deno.test("Either getRightMonad", () => { tfai: E.right((n: number) => n + 1), tfij: E.right((n: number) => n + 1), }); - - AS.testMonad(Monad, (a, b) => Promise.resolve(equals(a)(b))); }); Deno.test("Either Functor", () => { @@ -264,8 +259,6 @@ Deno.test("Either Chain", () => { }); Deno.test("Either Monad", () => { - const { equals } = E.getSetoid(setoidNumber, setoidNumber); - AS.assertMonad(E.Monad, { a: 1, ta: E.right(1), @@ -276,8 +269,6 @@ Deno.test("Either Monad", () => { fati: (n: number) => E.right(n), fitj: (n: number) => E.right(n), }); - - AS.testMonad(E.Monad, (a, b) => Promise.resolve(equals(a)(b))); }); Deno.test("Either Bifunctor", () => { diff --git a/testing/reader.test.ts b/testing/reader.test.ts new file mode 100644 index 0000000..c6aa762 --- /dev/null +++ b/testing/reader.test.ts @@ -0,0 +1,59 @@ +import { assertEquals } from "https://deno.land/std/testing/asserts.ts"; + +import * as R from "../reader.ts"; +import { pipe } from "../fns.ts"; + +import * as AS from "./assert.ts"; + +// deno-lint-ignore no-explicit-any +const assertEqualsR = (a: R.Reader, b: R.Reader) => + assertEquals(a(0), b(0)); + +Deno.test("Reader ask", () => { + assertEqualsR(R.ask(), R.ask()); +}); + +Deno.test("Reader asks", () => { + assertEqualsR(R.asks(AS.add), R.asks(AS.add)); +}); + +Deno.test("Reader of", () => { + assertEqualsR(R.of(0), R.ask()); +}); + +Deno.test("Reader ap", () => { + assertEqualsR(pipe(R.make(0), R.ap(R.of(AS.add))), R.make(1)); +}); + +Deno.test("Reader map", () => { + assertEqualsR(pipe(R.make(0), R.map(AS.add)), R.make(1)); +}); + +Deno.test("Reader join", () => { + const tta = R.asks((n: number) => R.make(n)); + assertEquals(R.join(tta)(0), 0); +}); + +Deno.test("Reader chain", () => { + const chain = R.chain((n: number) => R.make(n + 1)); + assertEqualsR(chain(R.make(0)), R.make(1)); +}); + +Deno.test("Reader Do, bind, bindTo", () => { + assertEqualsR( + pipe( + R.Do(), + R.bind("one", () => R.make(1)), + R.bind("two", ({ one }) => R.make(one + one)), + R.map(({ one, two }) => one + two), + ), + R.make(3), + ); + assertEqualsR( + pipe( + R.make(1), + R.bindTo("one"), + ), + R.asks((_: number) => ({ one: 1 })), + ); +});