diff --git a/docs/modules/ReaderTask.ts.md b/docs/modules/ReaderTask.ts.md index 45c1ee483..8a307394b 100644 --- a/docs/modules/ReaderTask.ts.md +++ b/docs/modules/ReaderTask.ts.md @@ -15,6 +15,7 @@ Added in v2.3.0 - [combinators](#combinators) - [tap](#tap) - [tapIO](#tapio) + - [tapTask](#taptask) - [constructors](#constructors) - [ask](#ask) - [asks](#asks) @@ -52,6 +53,7 @@ Added in v2.3.0 - [chain](#chain) - [chainFirst](#chainfirst) - [chainFirstIOK](#chainfirstiok) + - [chainFirstTaskK](#chainfirsttaskk) - [chainFirstW](#chainfirstw) - [chainW](#chainw) - [lifting](#lifting) @@ -71,7 +73,6 @@ Added in v2.3.0 - [chainFirstReaderIOKW](#chainfirstreaderiokw) - [chainFirstReaderK](#chainfirstreaderk) - [chainFirstReaderKW](#chainfirstreaderkw) - - [chainFirstTaskK](#chainfirsttaskk) - [chainIOK](#chainiok) - [chainReaderIOK](#chainreaderiok) - [chainReaderIOKW](#chainreaderiokw) @@ -165,6 +166,41 @@ test() Added in v2.16.0 +## tapTask + +Composes computations in sequence, using the return value of one computation to determine the next computation and +keeping only the result of the first. + +**Signature** + +```ts +export declare const tapTask: { + (self: ReaderTask, f: (a: A) => T.Task<_>): ReaderTask + (f: (a: A) => T.Task<_>): (self: ReaderTask) => ReaderTask +} +``` + +**Example** + +```ts +import { pipe } from 'fp-ts/function' +import * as RT from 'fp-ts/ReaderTask' +import * as T from 'fp-ts/Task' + +const effect = pipe( + RT.ask(), + RT.tapTask((value) => T.of(value + 1)) +) + +async function test() { + assert.deepStrictEqual(await effect(1)(), 1) +} + +test() +``` + +Added in v2.16.0 + # constructors ## ask @@ -542,6 +578,18 @@ export declare const chainFirstIOK: (f: (a: A) => IO) => (first: Rea Added in v2.10.0 +## chainFirstTaskK + +Alias of `tapTask`. + +**Signature** + +```ts +export declare const chainFirstTaskK: (f: (a: A) => T.Task) => (first: ReaderTask) => ReaderTask +``` + +Added in v2.10.0 + ## chainFirstW Alias of `tap`. @@ -742,16 +790,6 @@ export declare const chainFirstReaderKW: ( Added in v2.11.0 -## chainFirstTaskK - -**Signature** - -```ts -export declare const chainFirstTaskK: (f: (a: A) => T.Task) => (first: ReaderTask) => ReaderTask -``` - -Added in v2.10.0 - ## chainIOK **Signature** diff --git a/docs/modules/ReaderTaskEither.ts.md b/docs/modules/ReaderTaskEither.ts.md index 405d5356c..b61d34498 100644 --- a/docs/modules/ReaderTaskEither.ts.md +++ b/docs/modules/ReaderTaskEither.ts.md @@ -16,6 +16,7 @@ Added in v2.0.0 - [tap](#tap) - [tapEither](#tapeither) - [tapIO](#tapio) + - [tapTask](#taptask) - [constructors](#constructors) - [ask](#ask) - [asks](#asks) @@ -97,6 +98,7 @@ Added in v2.0.0 - [chainFirstEitherK](#chainfirsteitherk) - [chainFirstEitherKW](#chainfirsteitherkw) - [chainFirstIOK](#chainfirstiok) + - [chainFirstTaskK](#chainfirsttaskk) - [chainFirstW](#chainfirstw) - [chainNullableK](#chainnullablek) - [chainOptionK](#chainoptionk) @@ -145,7 +147,6 @@ Added in v2.0.0 - [chainFirstReaderTaskKW](#chainfirstreadertaskkw) - [chainFirstTaskEitherK](#chainfirsttaskeitherk) - [chainFirstTaskEitherKW](#chainfirsttaskeitherkw) - - [chainFirstTaskK](#chainfirsttaskk) - [chainIOEitherK](#chainioeitherk) - [chainIOEitherKW](#chainioeitherkw) - [chainIOK](#chainiok) @@ -299,6 +300,38 @@ test() Added in v2.16.0 +## tapTask + +Composes computations in sequence, using the return value of one computation to determine the next computation and +keeping only the result of the first. + +**Signature** + +```ts +export declare const tapTask: { + (self: ReaderTaskEither, f: (a: A) => T.Task<_>): ReaderTaskEither + (f: (a: A) => T.Task<_>): (self: ReaderTaskEither) => ReaderTaskEither +} +``` + +**Example** + +```ts +import * as RTE from 'fp-ts/ReaderTaskEither' +import * as E from 'fp-ts/Either' +import * as T from 'fp-ts/Task' + +const effect = RTE.tapTask(RTE.ask(), (value) => T.of(value + 1)) + +async function test() { + assert.deepStrictEqual(await effect(1)(), E.of(1)) +} + +test() +``` + +Added in v2.16.0 + # constructors ## ask @@ -1219,6 +1252,20 @@ export declare const chainFirstIOK: ( Added in v2.10.0 +## chainFirstTaskK + +Alias of `tapTask`. + +**Signature** + +```ts +export declare const chainFirstTaskK: ( + f: (a: A) => T.Task +) => (first: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.10.0 + ## chainFirstW Alias of `tap`. @@ -1818,18 +1865,6 @@ export declare const chainFirstTaskEitherKW: ( Added in v2.11.0 -## chainFirstTaskK - -**Signature** - -```ts -export declare const chainFirstTaskK: ( - f: (a: A) => T.Task -) => (first: ReaderTaskEither) => ReaderTaskEither -``` - -Added in v2.10.0 - ## chainIOEitherK **Signature** diff --git a/docs/modules/StateReaderTaskEither.ts.md b/docs/modules/StateReaderTaskEither.ts.md index e71907fa0..92a5e298d 100644 --- a/docs/modules/StateReaderTaskEither.ts.md +++ b/docs/modules/StateReaderTaskEither.ts.md @@ -16,6 +16,7 @@ Added in v2.0.0 - [tap](#tap) - [tapEither](#tapeither) - [tapIO](#tapio) + - [tapTask](#taptask) - [constructors](#constructors) - [ask](#ask) - [asks](#asks) @@ -79,6 +80,7 @@ Added in v2.0.0 - [chainFirstEitherK](#chainfirsteitherk) - [chainFirstEitherKW](#chainfirsteitherkw) - [chainFirstIOK](#chainfirstiok) + - [chainFirstTaskK](#chainfirsttaskk) - [chainFirstW](#chainfirstw) - [chainW](#chainw) - [lifting](#lifting) @@ -105,7 +107,6 @@ Added in v2.0.0 - [chainEitherKW](#chaineitherkw) - [chainFirstReaderK](#chainfirstreaderk) - [chainFirstReaderKW](#chainfirstreaderkw) - - [chainFirstTaskK](#chainfirsttaskk) - [chainIOEitherK](#chainioeitherk) - [chainIOEitherKW](#chainioeitherkw) - [chainIOK](#chainiok) @@ -218,6 +219,22 @@ export declare const tapIO: { Added in v2.16.0 +## tapTask + +Composes computations in sequence, using the return value of one computation to determine the next computation and +keeping only the result of the first. + +**Signature** + +```ts +export declare const tapTask: { + (self: StateReaderTaskEither, f: (a: A) => Task<_>): StateReaderTaskEither + (f: (a: A) => Task<_>): (self: StateReaderTaskEither) => StateReaderTaskEither +} +``` + +Added in v2.16.0 + # constructors ## ask @@ -888,6 +905,20 @@ export declare const chainFirstIOK: ( Added in v2.10.0 +## chainFirstTaskK + +Alias of `tapTask`. + +**Signature** + +```ts +export declare const chainFirstTaskK: ( + f: (a: A) => Task +) => (first: StateReaderTaskEither) => StateReaderTaskEither +``` + +Added in v2.10.0 + ## chainFirstW Alias of `tap`. @@ -1193,18 +1224,6 @@ export declare const chainFirstReaderKW: ( Added in v2.11.0 -## chainFirstTaskK - -**Signature** - -```ts -export declare const chainFirstTaskK: ( - f: (a: A) => Task -) => (first: StateReaderTaskEither) => StateReaderTaskEither -``` - -Added in v2.10.0 - ## chainIOEitherK **Signature** diff --git a/docs/modules/TaskEither.ts.md b/docs/modules/TaskEither.ts.md index 567771356..d5cd983f9 100644 --- a/docs/modules/TaskEither.ts.md +++ b/docs/modules/TaskEither.ts.md @@ -23,6 +23,7 @@ Added in v2.0.0 - [tap](#tap) - [tapEither](#tapeither) - [tapIO](#tapio) + - [tapTask](#taptask) - [constructors](#constructors) - [left](#left) - [leftIO](#leftio) @@ -96,6 +97,7 @@ Added in v2.0.0 - [chainFirstEitherK](#chainfirsteitherk) - [chainFirstEitherKW](#chainfirsteitherkw) - [chainFirstIOK](#chainfirstiok) + - [chainFirstTaskK](#chainfirsttaskk) - [chainFirstW](#chainfirstw) - [chainNullableK](#chainnullablek) - [chainOptionK](#chainoptionk) @@ -130,7 +132,6 @@ Added in v2.0.0 - [matchEW](#matchew) - [matchW](#matchw) - [sequencing](#sequencing) - - [chainFirstTaskK](#chainfirsttaskk) - [chainIOEitherK](#chainioeitherk) - [chainIOEitherKW](#chainioeitherkw) - [chainIOK](#chainiok) @@ -275,6 +276,38 @@ test() Added in v2.16.0 +## tapTask + +Composes computations in sequence, using the return value of one computation to determine the next computation and +keeping only the result of the first. + +**Signature** + +```ts +export declare const tapTask: { + (self: TaskEither, f: (a: A) => T.Task<_>): TaskEither + (f: (a: A) => T.Task<_>): (self: TaskEither) => TaskEither +} +``` + +**Example** + +```ts +import * as TE from 'fp-ts/TaskEither' +import * as T from 'fp-ts/Task' +import * as E from 'fp-ts/Either' + +const effect = TE.tapIO(TE.of(1), (value) => T.of(value + 1)) + +async function test() { + assert.deepStrictEqual(await effect(), E.of(1)) +} + +test() +``` + +Added in v2.16.0 + # constructors ## left @@ -1217,6 +1250,18 @@ export declare const chainFirstIOK: (f: (a: A) => IO) => (first: Tas Added in v2.10.0 +## chainFirstTaskK + +Alias of `tapTask`. + +**Signature** + +```ts +export declare const chainFirstTaskK: (f: (a: A) => T.Task) => (first: TaskEither) => TaskEither +``` + +Added in v2.10.0 + ## chainFirstW Alias of `tap`. @@ -1616,16 +1661,6 @@ Added in v2.10.0 # sequencing -## chainFirstTaskK - -**Signature** - -```ts -export declare const chainFirstTaskK: (f: (a: A) => T.Task) => (first: TaskEither) => TaskEither -``` - -Added in v2.10.0 - ## chainIOEitherK **Signature** diff --git a/docs/modules/TaskOption.ts.md b/docs/modules/TaskOption.ts.md index ace1f2757..5e1e81198 100644 --- a/docs/modules/TaskOption.ts.md +++ b/docs/modules/TaskOption.ts.md @@ -16,6 +16,7 @@ Added in v2.10.0 - [tap](#tap) - [tapEither](#tapeither) - [tapIO](#tapio) + - [tapTask](#taptask) - [constructors](#constructors) - [none](#none) - [of](#of) @@ -73,6 +74,7 @@ Added in v2.10.0 - [chainFirst](#chainfirst) - [chainFirstEitherK](#chainfirsteitherk) - [chainFirstIOK](#chainfirstiok) + - [chainFirstTaskK](#chainfirsttaskk) - [lifting](#lifting) - [fromEitherK](#fromeitherk) - [fromIOK](#fromiok) @@ -96,7 +98,6 @@ Added in v2.10.0 - [matchW](#matchw) - [sequencing](#sequencing) - [chainEitherK](#chaineitherk) - - [chainFirstTaskK](#chainfirsttaskk) - [chainIOK](#chainiok) - [chainNullableK](#chainnullablek) - [chainOptionK](#chainoptionk) @@ -223,6 +224,38 @@ test() Added in v2.16.0 +## tapTask + +Composes computations in sequence, using the return value of one computation to determine the next computation and +keeping only the result of the first. + +**Signature** + +```ts +export declare const tapTask: { + (self: TaskOption, f: (a: A) => T.Task<_>): TaskOption + (f: (a: A) => T.Task<_>): (self: TaskOption) => TaskOption +} +``` + +**Example** + +```ts +import * as TO from 'fp-ts/TaskOption' +import * as O from 'fp-ts/Option' +import * as T from 'fp-ts/Task' + +const effect = TO.tapIO(TO.of(1), (value) => T.of(value + 1)) + +async function test() { + assert.deepStrictEqual(await effect(), O.of(1)) +} + +test() +``` + +Added in v2.16.0 + # constructors ## none @@ -780,6 +813,18 @@ export declare const chainFirstIOK: (f: (a: A) => IO) => (first: TaskOp Added in v2.10.0 +## chainFirstTaskK + +Alias of `tapTask`. + +**Signature** + +```ts +export declare const chainFirstTaskK: (f: (a: A) => T.Task) => (first: TaskOption) => TaskOption +``` + +Added in v2.10.0 + # lifting ## fromEitherK @@ -1018,16 +1063,6 @@ export declare const chainEitherK: (f: (a: A) => Either) => (ma: Added in v2.12.0 -## chainFirstTaskK - -**Signature** - -```ts -export declare const chainFirstTaskK: (f: (a: A) => T.Task) => (first: TaskOption) => TaskOption -``` - -Added in v2.10.0 - ## chainIOK **Signature** diff --git a/src/FromTask.ts b/src/FromTask.ts index 98eded174..1240e8600 100644 --- a/src/FromTask.ts +++ b/src/FromTask.ts @@ -3,7 +3,7 @@ * * @since 2.10.0 */ -import { Chain, Chain1, Chain2, Chain2C, Chain3, Chain3C, Chain4, chainFirst } from './Chain' +import { Chain, Chain1, Chain2, Chain2C, Chain3, Chain3C, Chain4, tap } from './Chain' import { FromIO, FromIO1, FromIO2, FromIO2C, FromIO3, FromIO3C, FromIO4 } from './FromIO' import { flow } from './function' import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' @@ -179,6 +179,44 @@ export function chainFirstTaskK( F: FromTask, M: Chain ): (f: (a: A) => Task) => (first: HKT) => HKT { - const chainFirstM = chainFirst(M) - return (f) => chainFirstM(flow(f, F.fromTask)) + const tapTaskM = tapTask(F, M) + return (f) => (first) => tapTaskM(first, f) +} + +/** @internal */ +export function tapTask( + F: FromTask4, + M: Chain4 +): (self: Kind4, f: (a: A) => Task) => Kind4 +/** @internal */ +export function tapTask( + F: FromTask3, + M: Chain3 +): (self: Kind3, f: (a: A) => Task) => Kind3 +/** @internal */ +export function tapTask( + F: FromTask3C, + M: Chain3C +): (self: Kind3, f: (a: A) => Task) => Kind3 +/** @internal */ +export function tapTask( + F: FromTask2, + M: Chain2 +): (self: Kind2, f: (a: A) => Task) => Kind2 +/** @internal */ +export function tapTask( + F: FromTask2C, + M: Chain2C +): (self: Kind2, f: (a: A) => Task) => Kind2 +/** @internal */ +export function tapTask( + F: FromTask1, + M: Chain1 +): (self: Kind, f: (a: A) => Task) => Kind +/** @internal */ +export function tapTask(F: FromTask, M: Chain): (self: HKT, f: (a: A) => Task) => HKT +/** @internal */ +export function tapTask(F: FromTask, M: Chain): (self: HKT, f: (a: A) => Task) => HKT { + const tapM = tap(M) + return (self, f) => tapM(self, flow(f, F.fromTask)) } diff --git a/src/ReaderTask.ts b/src/ReaderTask.ts index f615643cc..9b5108f14 100644 --- a/src/ReaderTask.ts +++ b/src/ReaderTask.ts @@ -19,12 +19,7 @@ import { FromReader2, fromReaderK as fromReaderK_ } from './FromReader' -import { - chainFirstTaskK as chainFirstTaskK_, - chainTaskK as chainTaskK_, - FromTask2, - fromTaskK as fromTaskK_ -} from './FromTask' +import { chainTaskK as chainTaskK_, FromTask2, fromTaskK as fromTaskK_, tapTask as tapTask_ } from './FromTask' import { dual, flow, identity, pipe, SK } from './function' import { as as as_, asUnit as asUnit_, bindTo as bindTo_, flap as flap_, Functor2, let as let__ } from './Functor' import * as _ from './internal' @@ -362,6 +357,16 @@ export const FromIO: FromIO2 = { fromIO } +/** + * @category instances + * @since 2.10.0 + */ +export const FromTask: FromTask2 = { + URI, + fromIO, + fromTask +} + /** * Composes computations in sequence, using the return value of one computation to determine the next computation and * keeping only the result of the first. @@ -403,6 +408,34 @@ export const tapIO: { (f: (a: A) => IO<_>): (self: ReaderTask) => ReaderTask } = /*#__PURE__*/ dual(2, tapIO_(FromIO, Chain)) +/** + * Composes computations in sequence, using the return value of one computation to determine the next computation and + * keeping only the result of the first. + * + * @example + * import { pipe } from 'fp-ts/function' + * import * as RT from 'fp-ts/ReaderTask' + * import * as T from 'fp-ts/Task' + * + * const effect = pipe( + * RT.ask(), + * RT.tapTask((value) => T.of(value + 1)), + * ) + * + * async function test() { + * assert.deepStrictEqual(await effect(1)(), 1) + * } + * + * test() + * + * @category combinators + * @since 2.16.0 + */ +export const tapTask: { + (self: ReaderTask, f: (a: A) => Task<_>): ReaderTask + (f: (a: A) => Task<_>): (self: ReaderTask) => ReaderTask +} = /*#__PURE__*/ dual(2, tapTask_(FromTask, Chain)) + /** * @category lifting * @since 2.4.0 @@ -540,16 +573,6 @@ export const chainFirstReaderIOKW: ( export const chainFirstReaderIOK: (f: (a: A) => ReaderIO) => (ma: ReaderTask) => ReaderTask = chainFirstReaderIOKW -/** - * @category instances - * @since 2.10.0 - */ -export const FromTask: FromTask2 = { - URI, - fromIO, - fromTask -} - /** * @category lifting * @since 2.4.0 @@ -566,11 +589,12 @@ export const chainTaskK: (f: (a: A) => T.Task) => (first: ReaderTask /*#__PURE__*/ chainTaskK_(FromTask, Chain) /** - * @category sequencing + * Alias of `tapTask`. + * @category legacy * @since 2.10.0 */ export const chainFirstTaskK: (f: (a: A) => T.Task) => (first: ReaderTask) => ReaderTask = - /*#__PURE__*/ chainFirstTaskK_(FromTask, Chain) + tapTask // ------------------------------------------------------------------------------------- // do notation diff --git a/src/ReaderTaskEither.ts b/src/ReaderTaskEither.ts index 9f89bf7db..ef9513c01 100644 --- a/src/ReaderTaskEither.ts +++ b/src/ReaderTaskEither.ts @@ -43,12 +43,7 @@ import { FromReader3, fromReaderK as fromReaderK_ } from './FromReader' -import { - chainFirstTaskK as chainFirstTaskK_, - chainTaskK as chainTaskK_, - FromTask3, - fromTaskK as fromTaskK_ -} from './FromTask' +import { chainTaskK as chainTaskK_, FromTask3, fromTaskK as fromTaskK_, tapTask as tapTask_ } from './FromTask' import { dual, flow, identity, LazyArg, pipe, SK } from './function' import { as as as_, asUnit as asUnit_, bindTo as bindTo_, flap as flap_, Functor3, let as let__ } from './Functor' import * as _ from './internal' @@ -1004,6 +999,16 @@ export const FromIO: FromIO3 = { fromIO } +/** + * @category instances + * @since 2.10.0 + */ +export const FromTask: FromTask3 = { + URI, + fromIO, + fromTask +} + /** * Composes computations in sequence, using the return value of one computation to determine the next computation and * keeping only the result of the first. @@ -1083,6 +1088,35 @@ export const tapIO: { (f: (a: A) => IO<_>): (self: ReaderTaskEither) => ReaderTaskEither } = /*#__PURE__*/ dual(2, tapIO_(FromIO, Chain)) +/** + * Composes computations in sequence, using the return value of one computation to determine the next computation and + * keeping only the result of the first. + * + * @example + * import * as RTE from 'fp-ts/ReaderTaskEither' + * import * as E from 'fp-ts/Either' + * import * as T from 'fp-ts/Task' + * + * + * const effect = RTE.tapTask( + * RTE.ask(), + * (value) => T.of(value + 1) + * ) + * + * async function test() { + * assert.deepStrictEqual(await effect(1)(), E.of(1)) + * } + * + * test() + * + * @category combinators + * @since 2.16.0 + */ +export const tapTask: { + (self: ReaderTaskEither, f: (a: A) => Task<_>): ReaderTaskEither + (f: (a: A) => Task<_>): (self: ReaderTaskEither) => ReaderTaskEither +} = /*#__PURE__*/ dual(2, tapTask_(FromTask, Chain)) + /** * @category instances * @since 2.7.0 @@ -1516,16 +1550,6 @@ export const chainFirstIOK: ( f: (a: A) => IO ) => (first: ReaderTaskEither) => ReaderTaskEither = tapIO -/** - * @category instances - * @since 2.10.0 - */ -export const FromTask: FromTask3 = { - URI, - fromIO, - fromTask -} - /** * @category lifting * @since 2.10.0 @@ -1543,15 +1567,13 @@ export const chainTaskK: ( ) => (first: ReaderTaskEither) => ReaderTaskEither = /*#__PURE__*/ chainTaskK_(FromTask, Chain) /** - * @category sequencing + * Alias of `tapTask`. + * @category legacy * @since 2.10.0 */ export const chainFirstTaskK: ( f: (a: A) => T.Task -) => (first: ReaderTaskEither) => ReaderTaskEither = /*#__PURE__*/ chainFirstTaskK_( - FromTask, - Chain -) +) => (first: ReaderTaskEither) => ReaderTaskEither = tapTask // ------------------------------------------------------------------------------------- // utils diff --git a/src/StateReaderTaskEither.ts b/src/StateReaderTaskEither.ts index ad0951cd1..5d0b6bd71 100644 --- a/src/StateReaderTaskEither.ts +++ b/src/StateReaderTaskEither.ts @@ -37,12 +37,7 @@ import { modify as modify_, put as put_ } from './FromState' -import { - chainFirstTaskK as chainFirstTaskK_, - chainTaskK as chainTaskK_, - FromTask4, - fromTaskK as fromTaskK_ -} from './FromTask' +import { chainTaskK as chainTaskK_, FromTask4, fromTaskK as fromTaskK_, tapTask as tapTask_ } from './FromTask' import { dual, flow, identity, LazyArg, pipe } from './function' import { as as as_, asUnit as asUnit_, bindTo as bindTo_, flap as flap_, Functor4, let as let__ } from './Functor' import * as _ from './internal' @@ -774,6 +769,16 @@ export const FromIO: FromIO4 = { fromIO } +/** + * @category instances + * @since 2.10.0 + */ +export const FromTask: FromTask4 = { + URI, + fromIO, + fromTask +} + /** * Composes computations in sequence, using the return value of one computation to determine the next computation and * keeping only the result of the first. @@ -822,6 +827,18 @@ export const tapIO: { (f: (a: A) => IO<_>): (self: StateReaderTaskEither) => StateReaderTaskEither } = /*#__PURE__*/ dual(2, tapIO_(FromIO, Chain)) +/** + * Composes computations in sequence, using the return value of one computation to determine the next computation and + * keeping only the result of the first. + * + * @category combinators + * @since 2.16.0 + */ +export const tapTask: { + (self: StateReaderTaskEither, f: (a: A) => Task<_>): StateReaderTaskEither + (f: (a: A) => Task<_>): (self: StateReaderTaskEither) => StateReaderTaskEither +} = /*#__PURE__*/ dual(2, tapTask_(FromTask, Chain)) + /** * @category instances * @since 2.7.0 @@ -1103,16 +1120,6 @@ export const chainFirstIOK: ( f: (a: A) => IO ) => (first: StateReaderTaskEither) => StateReaderTaskEither = tapIO -/** - * @category instances - * @since 2.10.0 - */ -export const FromTask: FromTask4 = { - URI, - fromIO, - fromTask -} - /** * @category lifting * @since 2.10.0 @@ -1131,13 +1138,13 @@ export const chainTaskK: ( /*#__PURE__*/ chainTaskK_(FromTask, Chain) /** - * @category sequencing + * Alias of `tapTask`. + * @category legacy * @since 2.10.0 */ export const chainFirstTaskK: ( f: (a: A) => Task -) => (first: StateReaderTaskEither) => StateReaderTaskEither = - /*#__PURE__*/ chainFirstTaskK_(FromTask, Chain) +) => (first: StateReaderTaskEither) => StateReaderTaskEither = tapTask // ------------------------------------------------------------------------------------- // utils diff --git a/src/TaskEither.ts b/src/TaskEither.ts index 063268703..03bea17be 100644 --- a/src/TaskEither.ts +++ b/src/TaskEither.ts @@ -42,12 +42,7 @@ import { tapEither as tapEither_ } from './FromEither' import { chainIOK as chainIOK_, FromIO2, fromIOK as fromIOK_, tapIO as tapIO_ } from './FromIO' -import { - chainFirstTaskK as chainFirstTaskK_, - chainTaskK as chainTaskK_, - FromTask2, - fromTaskK as fromTaskK_ -} from './FromTask' +import { chainTaskK as chainTaskK_, FromTask2, fromTaskK as fromTaskK_, tapTask as tapTask_ } from './FromTask' import { dual, flow, identity, LazyArg, pipe, SK } from './function' import { as as as_, asUnit as asUnit_, bindTo as bindTo_, flap as flap_, Functor2, let as let__ } from './Functor' import * as _ from './internal' @@ -949,6 +944,16 @@ export const FromIO: FromIO2 = { fromIO } +/** + * @category instances + * @since 2.10.0 + */ +export const FromTask: FromTask2 = { + URI, + fromIO, + fromTask +} + /** * Composes computations in sequence, using the return value of one computation to determine the next computation and * keeping only the result of the first. @@ -1028,6 +1033,35 @@ export const tapIO: { (f: (a: A) => IO<_>): (self: TaskEither) => TaskEither } = /*#__PURE__*/ dual(2, tapIO_(FromIO, Chain)) +/** + * Composes computations in sequence, using the return value of one computation to determine the next computation and + * keeping only the result of the first. + * + * @example + * import * as TE from 'fp-ts/TaskEither' + * import * as T from 'fp-ts/Task' + * import * as E from 'fp-ts/Either' + * + * + * const effect = TE.tapIO( + * TE.of(1), + * (value) => T.of(value + 1) + * ) + * + * async function test() { + * assert.deepStrictEqual(await effect(), E.of(1)) + * } + * + * test() + * + * @category combinators + * @since 2.16.0 + */ +export const tapTask: { + (self: TaskEither, f: (a: A) => Task<_>): TaskEither + (f: (a: A) => Task<_>): (self: TaskEither) => TaskEither +} = /*#__PURE__*/ dual(2, tapTask_(FromTask, Chain)) + /** * @category instances * @since 2.7.0 @@ -1266,16 +1300,6 @@ export const chainIOK: (f: (a: A) => IO) => (first: TaskEither */ export const chainFirstIOK: (f: (a: A) => IO) => (first: TaskEither) => TaskEither = tapIO -/** - * @category instances - * @since 2.10.0 - */ -export const FromTask: FromTask2 = { - URI, - fromIO, - fromTask -} - /** * @category lifting * @since 2.10.0 @@ -1292,11 +1316,13 @@ export const chainTaskK: (f: (a: A) => T.Task) => (first: TaskEither /*#__PURE__*/ chainTaskK_(FromTask, Chain) /** - * @category sequencing + * Alias of `tapTask`. + * + * @category legacy * @since 2.10.0 */ export const chainFirstTaskK: (f: (a: A) => T.Task) => (first: TaskEither) => TaskEither = - /*#__PURE__*/ chainFirstTaskK_(FromTask, Chain) + tapTask // ------------------------------------------------------------------------------------- // utils diff --git a/src/TaskOption.ts b/src/TaskOption.ts index 33c4054c1..f27c23ab4 100644 --- a/src/TaskOption.ts +++ b/src/TaskOption.ts @@ -22,12 +22,7 @@ import { tapEither as tapEither_ } from './FromEither' import { chainIOK as chainIOK_, FromIO1, fromIOK as fromIOK_, tapIO as tapIO_ } from './FromIO' -import { - chainFirstTaskK as chainFirstTaskK_, - chainTaskK as chainTaskK_, - FromTask1, - fromTaskK as fromTaskK_ -} from './FromTask' +import { chainTaskK as chainTaskK_, FromTask1, fromTaskK as fromTaskK_, tapTask as tapTask_ } from './FromTask' import { dual, flow, identity, LazyArg, pipe, SK } from './function' import { as as as_, asUnit as asUnit_, bindTo as bindTo_, flap as flap_, Functor1, let as let__ } from './Functor' import * as _ from './internal' @@ -549,6 +544,16 @@ export const FromIO: FromIO1 = { fromIO } +/** + * @category instances + * @since 2.10.0 + */ +export const FromTask: FromTask1 = { + URI, + fromIO, + fromTask +} + /** * Composes computations in sequence, using the return value of one computation to determine the next computation and * keeping only the result of the first. @@ -629,6 +634,34 @@ export const tapIO: { (f: (a: A) => IO<_>): (self: TaskOption) => TaskOption } = /*#__PURE__*/ dual(2, tapIO_(FromIO, Chain)) +/** + * Composes computations in sequence, using the return value of one computation to determine the next computation and + * keeping only the result of the first. + * + * @example + * import * as TO from 'fp-ts/TaskOption' + * import * as O from 'fp-ts/Option' + * import * as T from 'fp-ts/Task' + * + * const effect = TO.tapIO( + * TO.of(1), + * (value) => T.of(value + 1) + * ) + * + * async function test() { + * assert.deepStrictEqual(await effect(), O.of(1)) + * } + * + * test() + * + * @category combinators + * @since 2.16.0 + */ +export const tapTask: { + (self: TaskOption, f: (a: A) => Task<_>): TaskOption + (f: (a: A) => Task<_>): (self: TaskOption) => TaskOption +} = /*#__PURE__*/ dual(2, tapTask_(FromTask, Chain)) + /** * @category instances * @since 2.10.0 @@ -778,16 +811,6 @@ export const chainEitherK: (f: (a: A) => Either) => (ma: TaskOpti */ export const chainFirstEitherK: (f: (a: A) => Either) => (ma: TaskOption) => TaskOption = tapEither -/** - * @category instances - * @since 2.10.0 - */ -export const FromTask: FromTask1 = { - URI, - fromIO, - fromTask -} - /** * @category lifting * @since 2.10.0 @@ -803,11 +826,12 @@ export const chainTaskK: (f: (a: A) => T.Task) => (first: TaskOption /*#__PURE__*/ chainTaskK_(FromTask, Chain) /** - * @category sequencing + * Alias of `tapTask`. + * + * @category legacy * @since 2.10.0 */ -export const chainFirstTaskK: (f: (a: A) => T.Task) => (first: TaskOption) => TaskOption = - /*#__PURE__*/ chainFirstTaskK_(FromTask, Chain) +export const chainFirstTaskK: (f: (a: A) => T.Task) => (first: TaskOption) => TaskOption = tapTask // ------------------------------------------------------------------------------------- // do notation diff --git a/test/ReaderTask.ts b/test/ReaderTask.ts index 071e8a517..7251a245f 100644 --- a/test/ReaderTask.ts +++ b/test/ReaderTask.ts @@ -296,6 +296,14 @@ describe.concurrent('ReaderTask', () => { U.deepStrictEqual(ref, [1]) }) + it('tapTask', async () => { + const ref: Array = [] + const add = (value: number) => T.fromIO(() => ref.push(value)) + + U.deepStrictEqual(await pipe(_.ask(), _.tapTask(add))(1)(), 1) + U.deepStrictEqual(ref, [1]) + }) + it('as', async () => { U.deepStrictEqual(await pipe(_.of('a'), _.as('b'))('c')(), 'b') }) diff --git a/test/ReaderTaskEither.ts b/test/ReaderTaskEither.ts index 8fb92b97f..f927274b3 100644 --- a/test/ReaderTaskEither.ts +++ b/test/ReaderTaskEither.ts @@ -761,4 +761,13 @@ describe.concurrent('ReaderTaskEither', () => { it('asUnit', async () => { U.deepStrictEqual(await pipe(_.of('a'), _.asUnit)(undefined)(), E.of(undefined)) }) + + it('tapTask', async () => { + const ref: Array = [] + const add = (value: number) => T.fromIO(() => ref.push(value)) + + U.deepStrictEqual(await pipe(_.ask(), _.tapTask(add))(1)(), E.of(1)) + U.deepStrictEqual(await pipe(_.left('error'), _.tapTask(add))(undefined)(), E.left('error')) + U.deepStrictEqual(ref, [1]) + }) }) diff --git a/test/StateReaderTaskEither.ts b/test/StateReaderTaskEither.ts index 4b9d50a0b..2aaa7fb1d 100644 --- a/test/StateReaderTaskEither.ts +++ b/test/StateReaderTaskEither.ts @@ -524,6 +524,15 @@ describe.concurrent('StateReaderTaskEither', () => { U.deepStrictEqual(ref, [1]) }) + it('tapTask', async () => { + const ref: Array = [] + const add = (value: number) => T.fromIO(() => ref.push(value)) + + U.deepStrictEqual(await pipe(_.ask(), _.tapTask(add), _.evaluate(state))(1)(), E.of(1)) + U.deepStrictEqual(await pipe(_.left('error'), _.tapTask(add), _.evaluate(state))(undefined)(), E.left('error')) + U.deepStrictEqual(ref, [1]) + }) + it('as', async () => { U.deepStrictEqual(await pipe(_.right('a'), _.as('b'), _.evaluate(state))(undefined)(), E.right('b')) U.deepStrictEqual(await pipe(_.as(_.left('error'), 'b'), _.evaluate(state))(undefined)(), E.left('error')) diff --git a/test/TaskEither.ts b/test/TaskEither.ts index d22086263..cbc1c33e8 100644 --- a/test/TaskEither.ts +++ b/test/TaskEither.ts @@ -872,4 +872,13 @@ describe.concurrent('TaskEither', () => { it('asUnit', async () => { U.deepStrictEqual(await pipe(_.of('a'), _.asUnit)(), E.of(undefined)) }) + + it('tapTask', async () => { + const ref: Array = [] + const add = (value: number) => T.fromIO(() => ref.push(value)) + + U.deepStrictEqual(await pipe(_.of(1), _.tapTask(add))(), E.of(1)) + U.deepStrictEqual(await pipe(_.left('error'), _.tapTask(add))(), E.left('error')) + U.deepStrictEqual(ref, [1]) + }) }) diff --git a/test/TaskOption.ts b/test/TaskOption.ts index 17c90ba13..109aa6a08 100644 --- a/test/TaskOption.ts +++ b/test/TaskOption.ts @@ -400,4 +400,13 @@ describe.concurrent('TaskOption', () => { it('asUnit', async () => { U.deepStrictEqual(await pipe(_.some('a'), _.asUnit)(), O.some(undefined)) }) + + it('tapIO', async () => { + const ref: Array = [] + const add = (value: number) => T.fromIO(() => ref.push(value)) + + U.deepStrictEqual(await pipe(_.of(1), _.tapTask(add))(), O.of(1)) + U.deepStrictEqual(await pipe(_.none, _.tapTask(add))(), O.none) + U.deepStrictEqual(ref, [1]) + }) })