diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ddc5b5a0..1daa710b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,16 @@ **Note**: A feature tagged as Experimental is in a high state of flux, you're at risk of it changing without notice. +# 2.8.4 + +- **Polish** + - `IOEither` + - add `ApplicativePar` instance (@gcanti) + - add `ApplicativeSeq` instance (@gcanti) +- **Deprecation** + - `IOEither` + - deprecate `Applicative` in favour of `ApplicativePar` (@gcanti) + # 2.8.3 - **Polish** diff --git a/package.json b/package.json index cffd9824f..518b68ff8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fp-ts", - "version": "2.8.3", + "version": "2.8.4", "description": "Functional programming in TypeScript", "main": "lib/index.js", "module": "es6/index.js", diff --git a/src/IOEither.ts b/src/IOEither.ts index 066e660ad..b085db427 100644 --- a/src/IOEither.ts +++ b/src/IOEither.ts @@ -194,6 +194,11 @@ export const chainEitherK: ( const map_: Monad2['map'] = (fa, f) => pipe(fa, map(f)) /* istanbul ignore next */ const ap_: Monad2['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const apSeq_: Applicative2['ap'] = (fab, fa) => + pipe( + fab, + chain((f) => pipe(fa, map(f))) + ) const of = right /* istanbul ignore next */ const chain_: Monad2['chain'] = (ma, f) => pipe(ma, chain(f)) @@ -508,15 +513,34 @@ export const Bifunctor: Bifunctor2 = { /** * @category instances - * @since 2.7.0 + * @since 2.8.4 */ -export const Applicative: Applicative2 = { +export const ApplicativePar: Applicative2 = { URI, map: map_, ap: ap_, of } +/** + * @category instances + * @since 2.8.4 + */ +export const ApplicativeSeq: Applicative2 = { + URI, + map: map_, + ap: apSeq_, + of +} + +/** + * Use `ApplicativePar` instead + * + * @since 2.7.0 + * @deprecated + */ +export const Applicative: Applicative2 = ApplicativePar + /** * @category instances * @since 2.7.0 diff --git a/test/IOEither.ts b/test/IOEither.ts index 0fb6ffa2d..2aa304aaf 100644 --- a/test/IOEither.ts +++ b/test/IOEither.ts @@ -58,6 +58,36 @@ describe('IOEither', () => { assert.deepStrictEqual(pipe(_.right(double), _.ap(_.right(1)))(), E.right(2)) }) + it('ApplicativePar', () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const x = sequenceT(_.ApplicativePar)( + _.rightIO(() => log.push('a')), + _.leftIO(() => { + log.push('b') + return 'error' + }), + _.rightIO(() => log.push('c')) + )() + assert.deepStrictEqual(x, E.left('error')) + assert.deepStrictEqual(log, ['a', 'b', 'c']) + }) + + it('ApplicativeSeq', () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const x = sequenceT(_.ApplicativeSeq)( + _.rightIO(() => log.push('a')), + _.leftIO(() => { + log.push('b') + return 'error' + }), + _.rightIO(() => log.push('c')) + )() + assert.deepStrictEqual(x, E.left('error')) + assert.deepStrictEqual(log, ['a', 'b']) + }) + it('apFirst', () => { assert.deepStrictEqual(pipe(_.right('a'), _.apFirst(_.right('b')))(), E.right('a')) })