From 3eb50e7480bf9a0464be55407e9209508d92d883 Mon Sep 17 00:00:00 2001 From: Giulio Canti Date: Sat, 21 Dec 2019 11:31:52 +0100 Subject: [PATCH] add some kleisli chains RE: https://github.com/gcanti/fp-ts/issues/1049#issuecomment-566923339 --- CHANGELOG.md | 15 +++++++ docs/modules/IOEither.ts.md | 11 +++++ docs/modules/ReaderEither.ts.md | 13 ++++++ docs/modules/ReaderTask.ts.md | 33 +++++++++++++++ docs/modules/ReaderTaskEither.ts.md | 39 ++++++++++++++++++ docs/modules/StateReaderTaskEither.ts.md | 52 ++++++++++++++++++++++++ docs/modules/Task.ts.md | 11 +++++ docs/modules/TaskEither.ts.md | 22 ++++++++++ src/IOEither.ts | 7 ++++ src/ReaderEither.ts | 9 ++++ src/ReaderTask.ts | 21 ++++++++++ src/ReaderTaskEither.ts | 27 ++++++++++++ src/StateReaderTaskEither.ts | 36 ++++++++++++++++ src/Task.ts | 7 ++++ src/TaskEither.ts | 14 +++++++ test/IOEither.ts | 6 +++ test/ReaderEither.ts | 6 +++ test/ReaderTask.ts | 17 +++++++- test/ReaderTaskEither.ts | 27 ++++++++++-- test/StateReaderTaskEither.ts | 33 +++++++++++++-- test/Task.ts | 48 +++++++++++++--------- test/TaskEither.ts | 13 ++++++ 22 files changed, 437 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f3f79e45..26cf0caf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,21 @@ high state of flux, you're at risk of it changing without notice. - add `getMonoid` (@vicrac) - `Ordering` - add `monoidOrdering` (@gcanti) + - `Task` + - add `chainIO` (@gcanti) + - `TaskEither` + - add `chainEither`, `chainIOEither` (@gcanti) + - `IOEither` + - add `chainEither` (@gcanti) + - `ReaderEither` + - add `chainEither` (@gcanti) + - `ReaderTask` + - add `run` (@gcanti) + - add `chainIO`, `chainTask` (@gcanti) + - `ReaderTaskEither` + - add `chainEither`, `chainIOEither`, `chainTaskEither` (@gcanti) + - `StateReaderTaskEither` + - add `chainEither`, `chainIOEither`, `chainTaskEither`, `chainReaderTaskEither` (@gcanti) - **Deprecation** - `Ord` - deprecate `getSemigroup` in favor of `getMonoid` (@gcanti) diff --git a/docs/modules/IOEither.ts.md b/docs/modules/IOEither.ts.md index 88d09a77b..1aefc8125 100644 --- a/docs/modules/IOEither.ts.md +++ b/docs/modules/IOEither.ts.md @@ -25,6 +25,7 @@ Added in v2.0.0 - [rightIO (constant)](#rightio-constant) - [swap (constant)](#swap-constant) - [bracket (function)](#bracket-function) +- [chainEither (function)](#chaineither-function) - [fold (function)](#fold-function) - [getApplyMonoid (function)](#getapplymonoid-function) - [getApplySemigroup (function)](#getapplysemigroup-function) @@ -160,6 +161,16 @@ export function bracket( Added in v2.0.0 +# chainEither (function) + +**Signature** + +```ts +export function chainEither(f: (a: A) => Either): (ma: IOEither) => IOEither { ... } +``` + +Added in v2.4.0 + # fold (function) **Signature** diff --git a/docs/modules/ReaderEither.ts.md b/docs/modules/ReaderEither.ts.md index ac53dd723..e9fa2b693 100644 --- a/docs/modules/ReaderEither.ts.md +++ b/docs/modules/ReaderEither.ts.md @@ -23,6 +23,7 @@ Added in v2.0.0 - [swap (constant)](#swap-constant) - [ask (function)](#ask-function) - [asks (function)](#asks-function) +- [chainEither (function)](#chaineither-function) - [fold (function)](#fold-function) - [getApplyMonoid (function)](#getapplymonoid-function) - [getApplySemigroup (function)](#getapplysemigroup-function) @@ -158,6 +159,18 @@ export function asks(f: (r: R) => A): ReaderEither( + f: (a: A) => Either +): (ma: ReaderEither) => ReaderEither { ... } +``` + +Added in v2.4.0 + # fold (function) **Signature** diff --git a/docs/modules/ReaderTask.ts.md b/docs/modules/ReaderTask.ts.md index 3cf8e410f..62fb1d5b1 100644 --- a/docs/modules/ReaderTask.ts.md +++ b/docs/modules/ReaderTask.ts.md @@ -22,10 +22,13 @@ Added in v2.3.0 - [of (constant)](#of-constant) - [readerTask (constant)](#readertask-constant) - [readerTaskSeq (constant)](#readertaskseq-constant) +- [chainIO (function)](#chainio-function) +- [chainTask (function)](#chaintask-function) - [fromIO (function)](#fromio-function) - [getMonoid (function)](#getmonoid-function) - [getSemigroup (function)](#getsemigroup-function) - [local (function)](#local-function) +- [run (function)](#run-function) - [ap (export)](#ap-export) - [apFirst (export)](#apfirst-export) - [apSecond (export)](#apsecond-export) @@ -140,6 +143,26 @@ export const readerTaskSeq: typeof readerTask = ... Added in v2.3.0 +# chainIO (function) + +**Signature** + +```ts +export function chainIO(f: (a: A) => IO): (ma: ReaderTask) => ReaderTask { ... } +``` + +Added in v2.4.0 + +# chainTask (function) + +**Signature** + +```ts +export function chainTask(f: (a: A) => Task): (ma: ReaderTask) => ReaderTask { ... } +``` + +Added in v2.4.0 + # fromIO (function) **Signature** @@ -180,6 +203,16 @@ export function local(f: (f: Q) => R): (ma: ReaderTask) => Rea Added in v2.3.0 +# run (function) + +**Signature** + +```ts +export function run(ma: ReaderTask, r: R): Promise { ... } +``` + +Added in v2.4.0 + # ap (export) **Signature** diff --git a/docs/modules/ReaderTaskEither.ts.md b/docs/modules/ReaderTaskEither.ts.md index b0a9543dc..55ab8b08e 100644 --- a/docs/modules/ReaderTaskEither.ts.md +++ b/docs/modules/ReaderTaskEither.ts.md @@ -23,6 +23,9 @@ Added in v2.0.0 - [right (constant)](#right-constant) - [rightReader (constant)](#rightreader-constant) - [bracket (function)](#bracket-function) +- [chainEither (function)](#chaineither-function) +- [chainIOEither (function)](#chainioeither-function) +- [chainTaskEither (function)](#chaintaskeither-function) - [fold (function)](#fold-function) - [fromIOEither (function)](#fromioeither-function) - [fromReaderEither (function)](#fromreadereither-function) @@ -181,6 +184,42 @@ export function bracket( Added in v2.0.4 +# chainEither (function) + +**Signature** + +```ts +export function chainEither( + f: (a: A) => Either +): (ma: ReaderTaskEither) => ReaderTaskEither { ... } +``` + +Added in v2.4.0 + +# chainIOEither (function) + +**Signature** + +```ts +export function chainIOEither( + f: (a: A) => IOEither +): (ma: ReaderTaskEither) => ReaderTaskEither { ... } +``` + +Added in v2.4.0 + +# chainTaskEither (function) + +**Signature** + +```ts +export function chainTaskEither( + f: (a: A) => TaskEither +): (ma: ReaderTaskEither) => ReaderTaskEither { ... } +``` + +Added in v2.4.0 + # fold (function) **Signature** diff --git a/docs/modules/StateReaderTaskEither.ts.md b/docs/modules/StateReaderTaskEither.ts.md index e817f1663..8086fa690 100644 --- a/docs/modules/StateReaderTaskEither.ts.md +++ b/docs/modules/StateReaderTaskEither.ts.md @@ -26,6 +26,10 @@ Added in v2.0.0 - [rightState (constant)](#rightstate-constant) - [stateReaderTaskEither (constant)](#statereadertaskeither-constant) - [stateReaderTaskEitherSeq (constant)](#statereadertaskeitherseq-constant) +- [chainEither (function)](#chaineither-function) +- [chainIOEither (function)](#chainioeither-function) +- [chainReaderTaskEither (function)](#chainreadertaskeither-function) +- [chainTaskEither (function)](#chaintaskeither-function) - [fromIOEither (function)](#fromioeither-function) - [fromReaderEither (function)](#fromreadereither-function) - [fromTaskEither (function)](#fromtaskeither-function) @@ -206,6 +210,54 @@ export const stateReaderTaskEitherSeq: typeof stateReaderTaskEither = ... Added in v2.0.0 +# chainEither (function) + +**Signature** + +```ts +export function chainEither( + f: (a: A) => Either +): (ma: StateReaderTaskEither) => StateReaderTaskEither { ... } +``` + +Added in v2.4.0 + +# chainIOEither (function) + +**Signature** + +```ts +export function chainIOEither( + f: (a: A) => IOEither +): (ma: StateReaderTaskEither) => StateReaderTaskEither { ... } +``` + +Added in v2.4.0 + +# chainReaderTaskEither (function) + +**Signature** + +```ts +export function chainReaderTaskEither( + f: (a: A) => ReaderTaskEither +): (ma: StateReaderTaskEither) => StateReaderTaskEither { ... } +``` + +Added in v2.4.0 + +# chainTaskEither (function) + +**Signature** + +```ts +export function chainTaskEither( + f: (a: A) => TaskEither +): (ma: StateReaderTaskEither) => StateReaderTaskEither { ... } +``` + +Added in v2.4.0 + # fromIOEither (function) **Signature** diff --git a/docs/modules/Task.ts.md b/docs/modules/Task.ts.md index 8e71566c3..a0b068355 100644 --- a/docs/modules/Task.ts.md +++ b/docs/modules/Task.ts.md @@ -20,6 +20,7 @@ Added in v2.0.0 - [URI (constant)](#uri-constant) - [task (constant)](#task-constant) - [taskSeq (constant)](#taskseq-constant) +- [chainIO (function)](#chainio-function) - [delay (function)](#delay-function) - [fromIO (function)](#fromio-function) - [getMonoid (function)](#getmonoid-function) @@ -91,6 +92,16 @@ export const taskSeq: typeof task = ... Added in v2.0.0 +# chainIO (function) + +**Signature** + +```ts +export function chainIO(f: (a: A) => IO): (ma: Task) => Task { ... } +``` + +Added in v2.4.0 + # delay (function) **Signature** diff --git a/docs/modules/TaskEither.ts.md b/docs/modules/TaskEither.ts.md index 4bdc12ba9..bfdd9b566 100644 --- a/docs/modules/TaskEither.ts.md +++ b/docs/modules/TaskEither.ts.md @@ -27,6 +27,8 @@ Added in v2.0.0 - [taskEither (constant)](#taskeither-constant) - [taskEitherSeq (constant)](#taskeitherseq-constant) - [bracket (function)](#bracket-function) +- [chainEither (function)](#chaineither-function) +- [chainIOEither (function)](#chainioeither-function) - [fold (function)](#fold-function) - [getApplyMonoid (function)](#getapplymonoid-function) - [getApplySemigroup (function)](#getapplysemigroup-function) @@ -187,6 +189,26 @@ export function bracket( Added in v2.0.0 +# chainEither (function) + +**Signature** + +```ts +export function chainEither(f: (a: A) => Either): (ma: TaskEither) => TaskEither { ... } +``` + +Added in v2.4.0 + +# chainIOEither (function) + +**Signature** + +```ts +export function chainIOEither(f: (a: A) => IOEither): (ma: TaskEither) => TaskEither { ... } +``` + +Added in v2.4.0 + # fold (function) **Signature** diff --git a/src/IOEither.ts b/src/IOEither.ts index e5f378ef4..b9f3e3584 100644 --- a/src/IOEither.ts +++ b/src/IOEither.ts @@ -172,6 +172,13 @@ export function getFilterable(M: Monoid): Filterable2C { } } +/** + * @since 2.4.0 + */ +export function chainEither(f: (a: A) => Either): (ma: IOEither) => IOEither { + return chain(a => fromEither(f(a))) +} + /** * @since 2.0.0 */ diff --git a/src/ReaderEither.ts b/src/ReaderEither.ts index a9a95d91e..e8a55e40e 100644 --- a/src/ReaderEither.ts +++ b/src/ReaderEither.ts @@ -151,6 +151,15 @@ export function getReaderValidation( } } +/** + * @since 2.4.0 + */ +export function chainEither( + f: (a: A) => Either +): (ma: ReaderEither) => ReaderEither { + return chain(a => fromEither(f(a))) +} + /** * @since 2.0.0 */ diff --git a/src/ReaderTask.ts b/src/ReaderTask.ts index 9eb566201..0e8f9057e 100644 --- a/src/ReaderTask.ts +++ b/src/ReaderTask.ts @@ -38,6 +38,13 @@ export interface ReaderTask { (r: R): Task } +/** + * @since 2.4.0 + */ +export function run(ma: ReaderTask, r: R): Promise { + return ma(r)() +} + /** * @since 2.3.0 */ @@ -94,6 +101,20 @@ export function local(f: (f: Q) => R): (ma: ReaderTask) => Rea return ma => T.local(ma, f) } +/** + * @since 2.4.0 + */ +export function chainIO(f: (a: A) => IO): (ma: ReaderTask) => ReaderTask { + return chain(a => fromIO(f(a))) +} + +/** + * @since 2.4.0 + */ +export function chainTask(f: (a: A) => Task): (ma: ReaderTask) => ReaderTask { + return chain(a => fromTask(f(a))) +} + /** * @since 2.3.0 */ diff --git a/src/ReaderTaskEither.ts b/src/ReaderTaskEither.ts index 7aaa472ee..35e8aad41 100644 --- a/src/ReaderTaskEither.ts +++ b/src/ReaderTaskEither.ts @@ -248,6 +248,33 @@ export function getReaderTaskValidation( } } +/** + * @since 2.4.0 + */ +export function chainEither( + f: (a: A) => Either +): (ma: ReaderTaskEither) => ReaderTaskEither { + return chain(a => fromEither(f(a))) +} + +/** + * @since 2.4.0 + */ +export function chainIOEither( + f: (a: A) => IOEither +): (ma: ReaderTaskEither) => ReaderTaskEither { + return chain(a => fromIOEither(f(a))) +} + +/** + * @since 2.4.0 + */ +export function chainTaskEither( + f: (a: A) => TaskEither +): (ma: ReaderTaskEither) => ReaderTaskEither { + return chain(a => fromTaskEither(f(a))) +} + /** * @since 2.0.0 */ diff --git a/src/StateReaderTaskEither.ts b/src/StateReaderTaskEither.ts index c34ebf5f1..eae4dae90 100644 --- a/src/StateReaderTaskEither.ts +++ b/src/StateReaderTaskEither.ts @@ -187,6 +187,42 @@ export const modify: (f: (s: S) => S) => StateReaderTaskEither< */ export const gets: (f: (s: S) => A) => StateReaderTaskEither = T.gets +/** + * @since 2.4.0 + */ +export function chainEither( + f: (a: A) => Either +): (ma: StateReaderTaskEither) => StateReaderTaskEither { + return chain(a => fromEither(f(a))) +} + +/** + * @since 2.4.0 + */ +export function chainIOEither( + f: (a: A) => IOEither +): (ma: StateReaderTaskEither) => StateReaderTaskEither { + return chain(a => fromIOEither(f(a))) +} + +/** + * @since 2.4.0 + */ +export function chainTaskEither( + f: (a: A) => TaskEither +): (ma: StateReaderTaskEither) => StateReaderTaskEither { + return chain(a => fromTaskEither(f(a))) +} + +/** + * @since 2.4.0 + */ +export function chainReaderTaskEither( + f: (a: A) => ReaderTaskEither +): (ma: StateReaderTaskEither) => StateReaderTaskEither { + return chain(a => fromReaderTaskEither(f(a))) +} + /** * @since 2.0.0 */ diff --git a/src/Task.ts b/src/Task.ts index 38e280c1c..4a91bafff 100644 --- a/src/Task.ts +++ b/src/Task.ts @@ -114,6 +114,13 @@ export function of(a: A): Task { return () => Promise.resolve(a) } +/** + * @since 2.4.0 + */ +export function chainIO(f: (a: A) => IO): (ma: Task) => Task { + return chain(a => fromIO(f(a))) +} + /** * @since 2.0.0 */ diff --git a/src/TaskEither.ts b/src/TaskEither.ts index d3fb543a7..a275c7235 100644 --- a/src/TaskEither.ts +++ b/src/TaskEither.ts @@ -266,6 +266,20 @@ export function getFilterable(M: Monoid): Filterable2C { } } +/** + * @since 2.4.0 + */ +export function chainEither(f: (a: A) => Either): (ma: TaskEither) => TaskEither { + return chain(a => fromEither(f(a))) +} + +/** + * @since 2.4.0 + */ +export function chainIOEither(f: (a: A) => IOEither): (ma: TaskEither) => TaskEither { + return chain(a => fromIOEither(f(a))) +} + /** * @since 2.0.0 */ diff --git a/test/IOEither.ts b/test/IOEither.ts index 433c62eff..dc9a117a5 100644 --- a/test/IOEither.ts +++ b/test/IOEither.ts @@ -310,4 +310,10 @@ describe('IOEither', () => { assert.deepStrictEqual(r3(), _.left(['a'])()) }) }) + + it('chainEither', () => { + const f = (s: string) => E.right(s.length) + const x = pipe(_.right('a'), _.chainEither(f))() + assert.deepStrictEqual(x, E.right(1)) + }) }) diff --git a/test/ReaderEither.ts b/test/ReaderEither.ts index 4b1df85a0..08a12dc40 100644 --- a/test/ReaderEither.ts +++ b/test/ReaderEither.ts @@ -130,4 +130,10 @@ describe('ReaderEither', () => { assert.deepStrictEqual(e4, E.left('ab')) }) }) + + it('chainEither', () => { + const f = (s: string) => E.right(s.length) + const x = pipe(_.right('a'), _.chainEither(f))(undefined) + assert.deepStrictEqual(x, E.right(1)) + }) }) diff --git a/test/ReaderTask.ts b/test/ReaderTask.ts index fd4ef25a3..0fa030cff 100644 --- a/test/ReaderTask.ts +++ b/test/ReaderTask.ts @@ -3,7 +3,8 @@ import { array } from '../src/Array' import { pipe } from '../src/pipeable' import { reader } from '../src/Reader' import * as _ from '../src/ReaderTask' -import { task } from '../src/Task' +import * as T from '../src/Task' +import * as I from '../src/IO' import { monoidString } from '../src/Monoid' import { semigroupString } from '../src/Semigroup' @@ -59,7 +60,7 @@ describe('ReaderTask', () => { }) it('fromTask', async () => { - const e = await _.fromTask(task.of(1))({})() + const e = await _.fromTask(T.of(1))({})() assert.deepStrictEqual(e, 1) }) @@ -117,4 +118,16 @@ describe('ReaderTask', () => { assert.deepStrictEqual(e, 1) }) }) + + it('chainIO', async () => { + const f = (s: string) => I.of(s.length) + const x = await _.run(pipe(_.of('a'), _.chainIO(f)), undefined) + assert.strictEqual(x, 1) + }) + + it('chainTask', async () => { + const f = (s: string) => T.of(s.length) + const x = await _.run(pipe(_.of('a'), _.chainTask(f)), undefined) + assert.strictEqual(x, 1) + }) }) diff --git a/test/ReaderTaskEither.ts b/test/ReaderTaskEither.ts index 72c7114f8..e86064e20 100644 --- a/test/ReaderTaskEither.ts +++ b/test/ReaderTaskEither.ts @@ -2,15 +2,16 @@ import * as assert from 'assert' import { array } from '../src/Array' import * as E from '../src/Either' import { io } from '../src/IO' +import * as IE from '../src/IOEither' import { monoidSum } from '../src/Monoid' import { none, some } from '../src/Option' import { pipe } from '../src/pipeable' import { reader } from '../src/Reader' +import * as RE from '../src/ReaderEither' import * as _ from '../src/ReaderTaskEither' -import { semigroupSum, semigroupString } from '../src/Semigroup' +import { semigroupString, semigroupSum } from '../src/Semigroup' import { task } from '../src/Task' -import { taskEither } from '../src/TaskEither' -import * as RE from '../src/ReaderEither' +import * as TE from '../src/TaskEither' describe('ReaderTaskEither', () => { describe('Monad', () => { @@ -103,7 +104,7 @@ describe('ReaderTaskEither', () => { }) it('fromTaskEither', async () => { - const e = await _.run(_.fromTaskEither(taskEither.of(1)), {}) + const e = await _.run(_.fromTaskEither(TE.taskEither.of(1)), {}) assert.deepStrictEqual(e, E.right(1)) }) @@ -454,4 +455,22 @@ describe('ReaderTaskEither', () => { assert.deepStrictEqual(e, E.left('release failure')) }) }) + + it('chainEither', async () => { + const f = (s: string) => E.right(s.length) + const x = await _.run(pipe(_.right('a'), _.chainEither(f)), undefined) + assert.deepStrictEqual(x, E.right(1)) + }) + + it('chainIOEither', async () => { + const f = (s: string) => IE.right(s.length) + const x = await _.run(pipe(_.right('a'), _.chainIOEither(f)), undefined) + assert.deepStrictEqual(x, E.right(1)) + }) + + it('chainTaskEither', async () => { + const f = (s: string) => TE.right(s.length) + const x = await _.run(pipe(_.right('a'), _.chainTaskEither(f)), undefined) + assert.deepStrictEqual(x, E.right(1)) + }) }) diff --git a/test/StateReaderTaskEither.ts b/test/StateReaderTaskEither.ts index f24d91433..71978a347 100644 --- a/test/StateReaderTaskEither.ts +++ b/test/StateReaderTaskEither.ts @@ -1,15 +1,16 @@ import * as assert from 'assert' import * as E from '../src/Either' +import { io } from '../src/IO' import * as IE from '../src/IOEither' import * as O from '../src/Option' +import { pipe } from '../src/pipeable' import { reader } from '../src/Reader' +import * as RE from '../src/ReaderEither' import * as RTE from '../src/ReaderTaskEither' import { State } from '../src/State' import * as _ from '../src/StateReaderTaskEither' import { task } from '../src/Task' -import { taskEither } from '../src/TaskEither' -import { io } from '../src/IO' -import * as RE from '../src/ReaderEither' +import * as TE from '../src/TaskEither' describe('StateReaderTaskEither', () => { it('run', async () => { @@ -91,7 +92,7 @@ describe('StateReaderTaskEither', () => { }) it('fromTaskEither', async () => { - const e = await _.run(_.fromTaskEither(taskEither.of(1)), {}, {}) + const e = await _.run(_.fromTaskEither(TE.taskEither.of(1)), {}, {}) assert.deepStrictEqual(e, E.right([1, {}])) }) @@ -149,4 +150,28 @@ describe('StateReaderTaskEither', () => { const e2 = await _.run(_.fromReaderEither(RE.right(1)), {}, {}) assert.deepStrictEqual(e2, E.right([1, {}])) }) + + it('chainEither', async () => { + const f = (s: string) => E.right(s.length) + const x = await _.run(pipe(_.right('a'), _.chainEither(f)), undefined, undefined) + assert.deepStrictEqual(x, E.right([1, undefined])) + }) + + it('chainIOEither', async () => { + const f = (s: string) => IE.right(s.length) + const x = await _.run(pipe(_.right('a'), _.chainIOEither(f)), undefined, undefined) + assert.deepStrictEqual(x, E.right([1, undefined])) + }) + + it('chainTaskEither', async () => { + const f = (s: string) => TE.right(s.length) + const x = await _.run(pipe(_.right('a'), _.chainTaskEither(f)), undefined, undefined) + assert.deepStrictEqual(x, E.right([1, undefined])) + }) + + it('chainReaderTaskEither', async () => { + const f = (s: string) => RTE.right(s.length) + const x = await _.run(pipe(_.right('a'), _.chainReaderTaskEither(f)), undefined, undefined) + assert.deepStrictEqual(x, E.right([1, undefined])) + }) }) diff --git a/test/Task.ts b/test/Task.ts index 174fdfcbf..3bac39ff6 100644 --- a/test/Task.ts +++ b/test/Task.ts @@ -1,18 +1,20 @@ import * as assert from 'assert' import { array } from '../src/Array' +import * as I from '../src/IO' import { monoidString } from '../src/Monoid' -import * as T from '../src/Task' +import { pipe } from '../src/pipeable' +import * as _ from '../src/Task' -const delayReject = (n: number, a: A): T.Task => () => +const delayReject = (n: number, a: A): _.Task => () => new Promise((_, reject) => { setTimeout(() => reject(a), n) }) -const delay = (millis: number, a: A): T.Task => T.delay(millis)(T.task.of(a)) +const delay = (millis: number, a: A): _.Task => _.delay(millis)(_.task.of(a)) describe('Task', () => { describe('getRaceMonoid', () => { - const M = T.getRaceMonoid() + const M = _.getRaceMonoid() it('concat', async () => { const x = await M.concat(delay(10, 1), delay(10, 2))() @@ -39,7 +41,7 @@ describe('Task', () => { }) describe('getMonoid', () => { - const M = T.getMonoid(monoidString) + const M = _.getMonoid(monoidString) it('concat', async () => { const x = await M.concat(delay(10, 'a'), delay(10, 'b'))() @@ -60,7 +62,7 @@ describe('Task', () => { describe('Monad', () => { it('map', async () => { const double = (n: number): number => n * 2 - const x = await T.task.map(delay(0, 1), double)() + const x = await _.task.map(delay(0, 1), double)() assert.strictEqual(x, 2) }) @@ -68,13 +70,13 @@ describe('Task', () => { const double = (n: number): number => n * 2 const tab = delay(0, double) const ta = delay(0, 1) - const x = await T.task.ap(tab, ta)() + const x = await _.task.ap(tab, ta)() assert.strictEqual(x, 2) }) it('chain', async () => { - const f = (n: number): T.Task => () => Promise.resolve(n * 2) - const x = await T.task.chain(delay(0, 1), f)() + const f = (n: number): _.Task => () => Promise.resolve(n * 2) + const x = await _.task.chain(delay(0, 1), f)() return assert.strictEqual(x, 2) }) }) @@ -82,10 +84,10 @@ describe('Task', () => { describe('Traversable', () => { it('sequence parallel', async () => { const log: Array = [] - const append = (message: string): T.Task => () => Promise.resolve(log.push(message)) - const t1 = T.task.chain(append('start 1'), () => append('end 1')) - const t2 = T.task.chain(append('start 2'), () => append('end 2')) - const sequenceParallel = array.sequence(T.task) + const append = (message: string): _.Task => () => Promise.resolve(log.push(message)) + const t1 = _.task.chain(append('start 1'), () => append('end 1')) + const t2 = _.task.chain(append('start 2'), () => append('end 2')) + const sequenceParallel = array.sequence(_.task) const x = await sequenceParallel([t1, t2])() assert.deepStrictEqual(x, [3, 4]) assert.deepStrictEqual(log, ['start 1', 'start 2', 'end 1', 'end 2']) @@ -93,10 +95,10 @@ describe('Task', () => { it('sequence series', async () => { const log: Array = [] - const append = (message: string): T.Task => () => Promise.resolve(log.push(message)) - const t1 = T.task.chain(append('start 1'), () => append('end 1')) - const t2 = T.task.chain(append('start 2'), () => append('end 2')) - const sequenceSeries = array.sequence(T.taskSeq) + const append = (message: string): _.Task => () => Promise.resolve(log.push(message)) + const t1 = _.task.chain(append('start 1'), () => append('end 1')) + const t2 = _.task.chain(append('start 2'), () => append('end 2')) + const sequenceSeries = array.sequence(_.taskSeq) const x = await sequenceSeries([t1, t2])() assert.deepStrictEqual(x, [2, 4]) assert.deepStrictEqual(log, ['start 1', 'end 1', 'start 2', 'end 2']) @@ -106,7 +108,7 @@ describe('Task', () => { describe('MonadIO', () => { it('fromIO', async () => { const io = () => 1 - const task = T.task.fromIO(io) + const task = _.task.fromIO(io) const x = await task() assert.strictEqual(x, 1) }) @@ -115,8 +117,14 @@ describe('Task', () => { describe('MonadTask', () => { it('fromTask', async () => { const io = () => 1 - const t = T.task.fromIO(io) - assert.strictEqual(T.task.fromTask(t), t) + const t = _.task.fromIO(io) + assert.strictEqual(_.task.fromTask(t), t) }) }) + + it('chainIO', async () => { + const f = (s: string) => I.of(s.length) + const x = await pipe(_.of('a'), _.chainIO(f))() + assert.strictEqual(x, 1) + }) }) diff --git a/test/TaskEither.ts b/test/TaskEither.ts index 0609dabb9..382161ff1 100644 --- a/test/TaskEither.ts +++ b/test/TaskEither.ts @@ -7,6 +7,7 @@ import { none, some } from '../src/Option' import { pipe, pipeable } from '../src/pipeable' import { semigroupString, semigroupSum } from '../src/Semigroup' import * as _ from '../src/TaskEither' +import { ioEither } from '../src/IOEither' describe('TaskEither', () => { describe('Monad', () => { @@ -362,4 +363,16 @@ describe('TaskEither', () => { assert.deepStrictEqual(await r3(), await _.left(['a'])()) }) }) + + it('chainEither', async () => { + const f = (s: string) => E.right(s.length) + const x = await pipe(_.right('a'), _.chainEither(f))() + assert.deepStrictEqual(x, E.right(1)) + }) + + it('chainIOEither', async () => { + const f = (s: string) => ioEither.of(s.length) + const x = await pipe(_.right('a'), _.chainIOEither(f))() + assert.deepStrictEqual(x, E.right(1)) + }) })