diff --git a/CHANGELOG.md b/CHANGELOG.md index d02e370ef..5ce393c51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,16 @@ **Note**: Gaps between patch versions are faulty/broken releases. **Note**: A feature tagged as Experimental is in a high state of flux, you're at risk of it changing without notice. +# 2.6.3 + +- **Polish** + - change `ReadonlyNonEmptyArray` definition to get better type inference (@gcanti) + - move `pipe` to `function` module (@gcanti) + - export `sequence` from all modules which admit a `Traversable` instance (@gcanti) + - export a pipeable `traverse` function from all modules which admit a `Traversable` instance (@gcanti) + - export a pipeable `traverseWithIndex` function from all modules which admit a `TraversableWithIndex` instance (@gcanti) + - remove monad transformers imports from all modules (@gcanti) + # 2.6.2 The goal of this release is to make `fp-ts` more "tree shaking" friendly. diff --git a/docs/modules/Array.ts.md b/docs/modules/Array.ts.md index de47682e9..8861dc3f0 100644 --- a/docs/modules/Array.ts.md +++ b/docs/modules/Array.ts.md @@ -119,7 +119,10 @@ Added in v2.0.0 - [isOutOfBound](#isoutofbound) - [lookup](#lookup) - [modifyAt](#modifyat) + - [sequence](#sequence) - [splitAt](#splitat) + - [traverse](#traverse) + - [traverseWithIndex](#traversewithindex) - [unzip](#unzip) - [updateAt](#updateat) @@ -1768,6 +1771,16 @@ assert.deepStrictEqual(modifyAt(1, double)([]), none) Added in v2.0.0 +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence1<'Array'> +``` + +Added in v2.6.3 + ## splitAt Splits an array into two pieces, the first piece has `n` elements. @@ -1791,6 +1804,26 @@ assert.deepStrictEqual(splitAt(2)([1, 2, 3, 4, 5]), [ Added in v2.0.0 +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse1<'Array'> +``` + +Added in v2.6.3 + +## traverseWithIndex + +**Signature** + +```ts +export declare const traverseWithIndex: PipeableTraverseWithIndex1<'Array', number> +``` + +Added in v2.6.3 + ## unzip The function is reverse of `zip`. Takes an array of pairs and return two corresponding arrays diff --git a/docs/modules/Either.ts.md b/docs/modules/Either.ts.md index 513ad9027..dfcf1791c 100644 --- a/docs/modules/Either.ts.md +++ b/docs/modules/Either.ts.md @@ -83,7 +83,9 @@ Added in v2.0.0 - [utils](#utils) - [elem](#elem) - [exists](#exists) + - [sequence](#sequence) - [toError](#toerror) + - [traverse](#traverse) --- @@ -783,6 +785,16 @@ assert.strictEqual(gt2(right(3)), true) Added in v2.0.0 +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence2<'Either'> +``` + +Added in v2.6.3 + ## toError Default value for the `onError` argument of `tryCatch` @@ -794,3 +806,13 @@ export declare function toError(e: unknown): Error ``` Added in v2.0.0 + +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse2<'Either'> +``` + +Added in v2.6.3 diff --git a/docs/modules/IOEither.ts.md b/docs/modules/IOEither.ts.md index fcdb784ce..e45c9e3ca 100644 --- a/docs/modules/IOEither.ts.md +++ b/docs/modules/IOEither.ts.md @@ -28,12 +28,16 @@ Added in v2.0.0 - [map](#map) - [Monad](#monad) - [chain](#chain) - - [chainEitherK](#chaineitherk) - [chainFirst](#chainfirst) - [chainW](#chainw) - [flatten](#flatten) +- [MonadThrow](#monadthrow) + - [bracket](#bracket) - [combinators](#combinators) + - [chainEitherK](#chaineitherk) + - [chainEitherKW](#chaineitherkw) - [filterOrElse](#filterorelse) + - [fromEitherK](#fromeitherk) - [orElse](#orelse) - [swap](#swap) - [constructors](#constructors) @@ -60,10 +64,6 @@ Added in v2.0.0 - [IOEither (interface)](#ioeither-interface) - [URI](#uri) - [URI (type alias)](#uri-type-alias) -- [utils](#utils) - - [bracket](#bracket) - - [chainEitherKW](#chaineitherkw) - - [fromEitherK](#fromeitherk) --- @@ -157,16 +157,6 @@ export declare const chain: (f: (a: A) => IOEither) => (ma: IOEit Added in v2.0.0 -## chainEitherK - -**Signature** - -```ts -export declare function chainEitherK(f: (a: A) => Either): (ma: IOEither) => IOEither -``` - -Added in v2.4.0 - ## chainFirst **Signature** @@ -197,8 +187,51 @@ export declare const flatten: (mma: IOEither>) => IOEith Added in v2.0.0 +# MonadThrow + +## bracket + +Make sure that a resource is cleaned up in the event of an exception (_). The release action is called regardless of +whether the body action throws (_) or returns. + +(\*) i.e. returns a `Left` + +**Signature** + +```ts +export declare const bracket: ( + acquire: IOEither, + use: (a: A) => IOEither, + release: (a: A, e: E.Either) => IOEither +) => IOEither +``` + +Added in v2.0.0 + # combinators +## chainEitherK + +**Signature** + +```ts +export declare function chainEitherK(f: (a: A) => Either): (ma: IOEither) => IOEither +``` + +Added in v2.4.0 + +## chainEitherKW + +**Signature** + +```ts +export declare const chainEitherKW: ( + f: (a: A) => E.Either +) => (ma: IOEither) => IOEither +``` + +Added in v2.6.1 + ## filterOrElse **Signature** @@ -212,12 +245,24 @@ export declare const filterOrElse: { Added in v2.0.0 +## fromEitherK + +**Signature** + +```ts +export declare function fromEitherK, B>( + f: (...a: A) => Either +): (...a: A) => IOEither +``` + +Added in v2.4.0 + ## orElse **Signature** ```ts -export declare function orElse(onLeft: (e: E) => IOEither): (ma: IOEither) => IOEither +export declare const orElse: (onLeft: (e: E) => IOEither) => (ma: IOEither) => IOEither ``` Added in v2.0.0 @@ -282,7 +327,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const leftIO: (me: IO) => IOEither +export declare const leftIO: (me: I.IO) => IOEither ``` Added in v2.0.0 @@ -302,7 +347,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const rightIO: (ma: IO) => IOEither +export declare const rightIO: (ma: I.IO) => IOEither ``` Added in v2.0.0 @@ -326,7 +371,10 @@ Added in v2.0.0 **Signature** ```ts -export declare function fold(onLeft: (e: E) => IO, onRight: (a: A) => IO): (ma: IOEither) => IO +export declare const fold: ( + onLeft: (e: E) => I.IO, + onRight: (a: A) => I.IO +) => (ma: IOEither) => I.IO ``` Added in v2.0.0 @@ -336,7 +384,7 @@ Added in v2.0.0 **Signature** ```ts -export declare function getOrElse(onLeft: (e: E) => IO): (ma: IOEither) => IO +export declare const getOrElse: (onLeft: (e: E) => I.IO) => (ma: IOEither) => I.IO ``` Added in v2.0.0 @@ -346,7 +394,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const getOrElseW: (onLeft: (e: E) => IO) => (ma: IOEither) => IO +export declare const getOrElseW: (onLeft: (e: E) => I.IO) => (ma: IOEither) => I.IO ``` Added in v2.6.0 @@ -456,48 +504,3 @@ export type URI = typeof URI ``` Added in v2.0.0 - -# utils - -## bracket - -Make sure that a resource is cleaned up in the event of an exception (_). The release action is called regardless of -whether the body action throws (_) or returns. - -(\*) i.e. returns a `Left` - -**Signature** - -```ts -export declare function bracket( - acquire: IOEither, - use: (a: A) => IOEither, - release: (a: A, e: Either) => IOEither -): IOEither -``` - -Added in v2.0.0 - -## chainEitherKW - -**Signature** - -```ts -export declare const chainEitherKW: ( - f: (a: A) => E.Either -) => (ma: IOEither) => IOEither -``` - -Added in v2.6.1 - -## fromEitherK - -**Signature** - -```ts -export declare function fromEitherK, B>( - f: (...a: A) => Either -): (...a: A) => IOEither -``` - -Added in v2.4.0 diff --git a/docs/modules/Identity.ts.md b/docs/modules/Identity.ts.md index a01b7dacd..c88cc8eff 100644 --- a/docs/modules/Identity.ts.md +++ b/docs/modules/Identity.ts.md @@ -41,6 +41,9 @@ Added in v2.0.0 - [Identity (type alias)](#identity-type-alias) - [URI](#uri) - [URI (type alias)](#uri-type-alias) +- [utils](#utils) + - [sequence](#sequence) + - [traverse](#traverse) --- @@ -266,3 +269,25 @@ export type URI = typeof URI ``` Added in v2.0.0 + +# utils + +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence1<'Identity'> +``` + +Added in v2.6.3 + +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse1<'Identity'> +``` + +Added in v2.6.3 diff --git a/docs/modules/NonEmptyArray.ts.md b/docs/modules/NonEmptyArray.ts.md index 8b9c6d7fa..fc7694011 100644 --- a/docs/modules/NonEmptyArray.ts.md +++ b/docs/modules/NonEmptyArray.ts.md @@ -75,7 +75,10 @@ Added in v2.0.0 - [max](#max) - [min](#min) - [modifyAt](#modifyat) + - [sequence](#sequence) - [tail](#tail) + - [traverse](#traverse) + - [traverseWithIndex](#traversewithindex) - [unzip](#unzip) - [updateAt](#updateat) @@ -685,6 +688,16 @@ export declare const modifyAt: (i: number, f: (a: A) => A) => (nea: NonEmptyA Added in v2.0.0 +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence1<'NonEmptyArray'> +``` + +Added in v2.6.3 + ## tail **Signature** @@ -695,6 +708,26 @@ export declare const tail: (nea: NonEmptyArray) => A[] Added in v2.0.0 +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse1<'NonEmptyArray'> +``` + +Added in v2.6.3 + +## traverseWithIndex + +**Signature** + +```ts +export declare const traverseWithIndex: PipeableTraverseWithIndex1<'NonEmptyArray', number> +``` + +Added in v2.6.3 + ## unzip **Signature** diff --git a/docs/modules/Option.ts.md b/docs/modules/Option.ts.md index 171f1bafc..cc90106c6 100644 --- a/docs/modules/Option.ts.md +++ b/docs/modules/Option.ts.md @@ -86,6 +86,8 @@ Added in v2.0.0 - [elem](#elem) - [exists](#exists) - [getRefinement](#getrefinement) + - [sequence](#sequence) + - [traverse](#traverse) --- @@ -1034,3 +1036,23 @@ export declare function getRefinement(getOption: (a: A) => Optio ``` Added in v2.0.0 + +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence1<'Option'> +``` + +Added in v2.6.3 + +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse1<'Option'> +``` + +Added in v2.6.3 diff --git a/docs/modules/Reader.ts.md b/docs/modules/Reader.ts.md index 779dd6f57..be341b722 100644 --- a/docs/modules/Reader.ts.md +++ b/docs/modules/Reader.ts.md @@ -29,6 +29,11 @@ Added in v2.0.0 - [promap](#promap) - [Semigroupoid](#semigroupoid) - [compose](#compose) +- [combinators](#combinators) + - [local](#local) +- [constructors](#constructors) + - [ask](#ask) + - [asks](#asks) - [instances](#instances) - [getMonoid](#getmonoid) - [getSemigroup](#getsemigroup) @@ -37,10 +42,6 @@ Added in v2.0.0 - [Reader (interface)](#reader-interface) - [URI](#uri) - [URI (type alias)](#uri-type-alias) -- [utils](#utils) - - [ask](#ask) - - [asks](#asks) - - [local](#local) --- @@ -107,7 +108,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const chain: (f: (a: A) => Reader) => (ma: Reader) => Reader +export declare const chain: (f: (a: A) => Reader) => (ma: Reader) => Reader ``` Added in v2.0.0 @@ -117,7 +118,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const chainFirst: (f: (a: A) => Reader) => (ma: Reader) => Reader +export declare const chainFirst: (f: (a: A) => Reader) => (ma: Reader) => Reader ``` Added in v2.0.0 @@ -166,111 +167,113 @@ export declare const compose: (la: Reader) => (ab: Reader) Added in v2.0.0 -# instances +# combinators -## getMonoid +## local + +Changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s +`contramap`). **Signature** ```ts -export declare function getMonoid(M: Monoid): Monoid> +export declare const local: (f: (d: Q) => R) => (ma: Reader) => Reader ``` Added in v2.0.0 -## getSemigroup +# constructors + +## ask + +Reads the current context **Signature** ```ts -export declare function getSemigroup(S: Semigroup): Semigroup> +export declare const ask: () => Reader ``` Added in v2.0.0 -## reader +## asks + +Projects a value from the global context in a Reader **Signature** ```ts -export declare const reader: Monad2<'Reader'> & - Profunctor2<'Reader'> & - Category2<'Reader'> & - Strong2<'Reader'> & - Choice2<'Reader'> +export declare const asks: (f: (r: R) => A) => Reader ``` Added in v2.0.0 -# model +# instances -## Reader (interface) +## getMonoid **Signature** ```ts -export interface Reader { - (r: R): A -} +export declare function getMonoid(M: Monoid): Monoid> ``` Added in v2.0.0 -## URI +## getSemigroup **Signature** ```ts -export declare const URI: 'Reader' +export declare function getSemigroup(S: Semigroup): Semigroup> ``` Added in v2.0.0 -## URI (type alias) +## reader **Signature** ```ts -export type URI = typeof URI +export declare const reader: Monad2<'Reader'> & + Profunctor2<'Reader'> & + Category2<'Reader'> & + Strong2<'Reader'> & + Choice2<'Reader'> ``` Added in v2.0.0 -# utils - -## ask +# model -Reads the current context +## Reader (interface) **Signature** ```ts -export declare const ask: () => Reader +export interface Reader { + (r: R): A +} ``` Added in v2.0.0 -## asks - -Projects a value from the global context in a Reader +## URI **Signature** ```ts -export declare const asks: (f: (r: R) => A) => Reader +export declare const URI: 'Reader' ``` Added in v2.0.0 -## local - -Changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s -`contramap`). +## URI (type alias) **Signature** ```ts -export declare function local(f: (d: Q) => R): (ma: Reader) => Reader +export type URI = typeof URI ``` Added in v2.0.0 diff --git a/docs/modules/ReaderEither.ts.md b/docs/modules/ReaderEither.ts.md index d8d5ba487..89ee44016 100644 --- a/docs/modules/ReaderEither.ts.md +++ b/docs/modules/ReaderEither.ts.md @@ -25,16 +25,20 @@ Added in v2.0.0 - [map](#map) - [Monad](#monad) - [chain](#chain) - - [chainEitherK](#chaineitherk) - [chainEitherKW](#chaineitherkw) - [chainFirst](#chainfirst) - [chainW](#chainw) - [flatten](#flatten) - [combinators](#combinators) + - [chainEitherK](#chaineitherk) - [filterOrElse](#filterorelse) + - [fromEitherK](#fromeitherk) + - [local](#local) - [orElse](#orelse) - [swap](#swap) - [constructors](#constructors) + - [ask](#ask) + - [asks](#asks) - [fromEither](#fromeither) - [fromOption](#fromoption) - [fromPredicate](#frompredicate) @@ -56,11 +60,6 @@ Added in v2.0.0 - [ReaderEither (interface)](#readereither-interface) - [URI](#uri) - [URI (type alias)](#uri-type-alias) -- [utils](#utils) - - [ask](#ask) - - [asks](#asks) - - [fromEitherK](#fromeitherk) - - [local](#local) --- @@ -167,18 +166,6 @@ export declare const chain: ( Added in v2.0.0 -## chainEitherK - -**Signature** - -```ts -export declare function chainEitherK( - f: (a: A) => Either -): (ma: ReaderEither) => ReaderEither -``` - -Added in v2.4.0 - ## chainEitherKW **Signature** @@ -227,6 +214,18 @@ Added in v2.0.0 # combinators +## chainEitherK + +**Signature** + +```ts +export declare function chainEitherK( + f: (a: A) => Either +): (ma: ReaderEither) => ReaderEither +``` + +Added in v2.4.0 + ## filterOrElse **Signature** @@ -242,14 +241,36 @@ export declare const filterOrElse: { Added in v2.0.0 +## fromEitherK + +**Signature** + +```ts +export declare function fromEitherK, B>( + f: (...a: A) => Either +): (...a: A) => ReaderEither +``` + +Added in v2.4.0 + +## local + +**Signature** + +```ts +export declare function local(f: (f: Q) => R): (ma: ReaderEither) => ReaderEither +``` + +Added in v2.0.0 + ## orElse **Signature** ```ts -export declare function orElse( +export declare const orElse: ( onLeft: (e: E) => ReaderEither -): (ma: ReaderEither) => ReaderEither +) => (ma: ReaderEither) => ReaderEither ``` Added in v2.0.0 @@ -266,6 +287,26 @@ Added in v2.0.0 # constructors +## ask + +**Signature** + +```ts +export declare const ask: () => ReaderEither +``` + +Added in v2.0.0 + +## asks + +**Signature** + +```ts +export declare const asks: (f: (r: R) => A) => ReaderEither +``` + +Added in v2.0.0 + ## fromEither **Signature** @@ -314,7 +355,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const leftReader: (me: Reader) => ReaderEither +export declare const leftReader: (me: R.Reader) => ReaderEither ``` Added in v2.0.0 @@ -334,7 +375,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const rightReader: (ma: Reader) => ReaderEither +export declare const rightReader: (ma: R.Reader) => ReaderEither ``` Added in v2.0.0 @@ -346,10 +387,10 @@ Added in v2.0.0 **Signature** ```ts -export declare function fold( - onLeft: (e: E) => Reader, - onRight: (a: A) => Reader -): (ma: ReaderEither) => Reader +export declare const fold: ( + onLeft: (e: E) => R.Reader, + onRight: (a: A) => R.Reader +) => (ma: ReaderEither) => R.Reader ``` Added in v2.0.0 @@ -359,7 +400,9 @@ Added in v2.0.0 **Signature** ```ts -export declare function getOrElse(onLeft: (e: E) => Reader): (ma: ReaderEither) => Reader +export declare const getOrElse: ( + onLeft: (e: E) => R.Reader +) => (ma: ReaderEither) => R.Reader ``` Added in v2.0.0 @@ -370,8 +413,8 @@ Added in v2.0.0 ```ts export declare const getOrElseW: ( - onLeft: (e: E) => Reader -) => (ma: ReaderEither) => Reader + onLeft: (e: E) => R.Reader +) => (ma: ReaderEither) => R.Reader ``` Added in v2.6.0 @@ -470,47 +513,3 @@ export type URI = typeof URI ``` Added in v2.0.0 - -# utils - -## ask - -**Signature** - -```ts -export declare function ask(): ReaderEither -``` - -Added in v2.0.0 - -## asks - -**Signature** - -```ts -export declare function asks(f: (r: R) => A): ReaderEither -``` - -Added in v2.0.0 - -## fromEitherK - -**Signature** - -```ts -export declare function fromEitherK, B>( - f: (...a: A) => Either -): (...a: A) => ReaderEither -``` - -Added in v2.4.0 - -## local - -**Signature** - -```ts -export declare function local(f: (f: Q) => R): (ma: ReaderEither) => ReaderEither -``` - -Added in v2.0.0 diff --git a/docs/modules/ReaderTask.ts.md b/docs/modules/ReaderTask.ts.md index cba046693..2c29f439d 100644 --- a/docs/modules/ReaderTask.ts.md +++ b/docs/modules/ReaderTask.ts.md @@ -23,10 +23,16 @@ Added in v2.3.0 - [Monad](#monad) - [chain](#chain) - [chainFirst](#chainfirst) + - [flatten](#flatten) +- [combinators](#combinators) - [chainIOK](#chainiok) - [chainTaskK](#chaintaskk) - - [flatten](#flatten) + - [fromIOK](#fromiok) + - [fromTaskK](#fromtaskk) + - [local](#local) - [constructors](#constructors) + - [ask](#ask) + - [asks](#asks) - [fromIO](#fromio) - [fromReader](#fromreader) - [fromTask](#fromtask) @@ -40,11 +46,6 @@ Added in v2.3.0 - [URI](#uri) - [URI (type alias)](#uri-type-alias) - [utils](#utils) - - [ask](#ask) - - [asks](#asks) - - [fromIOK](#fromiok) - - [fromTaskK](#fromtaskk) - - [local](#local) - [run](#run) --- @@ -112,7 +113,7 @@ Added in v2.3.0 **Signature** ```ts -export declare const chain: (f: (a: A) => ReaderTask) => (ma: ReaderTask) => ReaderTask +export declare const chain: (f: (a: A) => ReaderTask) => (ma: ReaderTask) => ReaderTask ``` Added in v2.3.0 @@ -122,207 +123,209 @@ Added in v2.3.0 **Signature** ```ts -export declare const chainFirst: (f: (a: A) => ReaderTask) => (ma: ReaderTask) => ReaderTask +export declare const chainFirst: (f: (a: A) => ReaderTask) => (ma: ReaderTask) => ReaderTask ``` Added in v2.3.0 -## chainIOK +## flatten **Signature** ```ts -export declare function chainIOK(f: (a: A) => IO): (ma: ReaderTask) => ReaderTask +export declare const flatten: (mma: ReaderTask>) => ReaderTask ``` -Added in v2.4.0 +Added in v2.3.0 -## chainTaskK +# combinators + +## chainIOK **Signature** ```ts -export declare function chainTaskK(f: (a: A) => Task): (ma: ReaderTask) => ReaderTask +export declare const chainIOK: (f: (a: A) => IO) => (ma: ReaderTask) => ReaderTask ``` Added in v2.4.0 -## flatten +## chainTaskK **Signature** ```ts -export declare const flatten: (mma: ReaderTask>) => ReaderTask +export declare const chainTaskK: (f: (a: A) => T.Task) => (ma: ReaderTask) => ReaderTask ``` -Added in v2.3.0 - -# constructors +Added in v2.4.0 -## fromIO +## fromIOK **Signature** ```ts -export declare function fromIO(ma: IO): ReaderTask +export declare function fromIOK, B>( + f: (...a: A) => IO +): (...a: A) => ReaderTask ``` -Added in v2.3.0 +Added in v2.4.0 -## fromReader +## fromTaskK **Signature** ```ts -export declare const fromReader: (ma: Reader) => ReaderTask +export declare function fromTaskK, B>( + f: (...a: A) => Task +): (...a: A) => ReaderTask ``` -Added in v2.3.0 +Added in v2.4.0 -## fromTask +## local **Signature** ```ts -export declare const fromTask: (ma: TA.Task) => ReaderTask +export declare const local: (f: (f: Q) => R) => (ma: ReaderTask) => ReaderTask ``` Added in v2.3.0 -# instances +# constructors -## getMonoid +## ask **Signature** ```ts -export declare function getMonoid(M: Monoid): Monoid> +export declare const ask: () => ReaderTask ``` Added in v2.3.0 -## getSemigroup +## asks **Signature** ```ts -export declare function getSemigroup(S: Semigroup): Semigroup> +export declare const asks: (f: (r: R) => A) => ReaderTask ``` Added in v2.3.0 -## readerTask +## fromIO **Signature** ```ts -export declare const readerTask: Monad2<'ReaderTask'> & MonadTask2<'ReaderTask'> +export declare const fromIO: (ma: IO) => ReaderTask ``` Added in v2.3.0 -## readerTaskSeq - -Like `readerTask` but `ap` is sequential +## fromReader **Signature** ```ts -export declare const readerTaskSeq: Monad2<'ReaderTask'> & MonadTask2<'ReaderTask'> +export declare const fromReader: (ma: R.Reader) => ReaderTask ``` Added in v2.3.0 -# model - -## ReaderTask (interface) +## fromTask **Signature** ```ts -export interface ReaderTask { - (r: R): Task -} +export declare const fromTask: (ma: T.Task) => ReaderTask ``` Added in v2.3.0 -## URI +# instances + +## getMonoid **Signature** ```ts -export declare const URI: 'ReaderTask' +export declare function getMonoid(M: Monoid): Monoid> ``` Added in v2.3.0 -## URI (type alias) +## getSemigroup **Signature** ```ts -export type URI = typeof URI +export declare function getSemigroup(S: Semigroup): Semigroup> ``` Added in v2.3.0 -# utils - -## ask +## readerTask **Signature** ```ts -export declare const ask: () => ReaderTask +export declare const readerTask: Monad2<'ReaderTask'> & MonadTask2<'ReaderTask'> ``` Added in v2.3.0 -## asks +## readerTaskSeq + +Like `readerTask` but `ap` is sequential **Signature** ```ts -export declare const asks: (f: (r: R) => A) => ReaderTask +export declare const readerTaskSeq: Monad2<'ReaderTask'> & MonadTask2<'ReaderTask'> ``` Added in v2.3.0 -## fromIOK +# model + +## ReaderTask (interface) **Signature** ```ts -export declare function fromIOK, B>( - f: (...a: A) => IO -): (...a: A) => ReaderTask +export interface ReaderTask { + (r: R): Task +} ``` -Added in v2.4.0 +Added in v2.3.0 -## fromTaskK +## URI **Signature** ```ts -export declare function fromTaskK, B>( - f: (...a: A) => Task -): (...a: A) => ReaderTask +export declare const URI: 'ReaderTask' ``` -Added in v2.4.0 +Added in v2.3.0 -## local +## URI (type alias) **Signature** ```ts -export declare function local(f: (f: Q) => R): (ma: ReaderTask) => ReaderTask +export type URI = typeof URI ``` Added in v2.3.0 +# utils + ## run **Signature** diff --git a/docs/modules/ReaderTaskEither.ts.md b/docs/modules/ReaderTaskEither.ts.md index f390d6df4..a5e073390 100644 --- a/docs/modules/ReaderTaskEither.ts.md +++ b/docs/modules/ReaderTaskEither.ts.md @@ -25,20 +25,26 @@ Added in v2.0.0 - [map](#map) - [Monad](#monad) - [chain](#chain) - - [chainEitherK](#chaineitherk) - [chainEitherKW](#chaineitherkw) - [chainFirst](#chainfirst) - - [chainIOEitherK](#chainioeitherk) - [chainIOEitherKW](#chainioeitherkw) - - [chainTaskEitherK](#chaintaskeitherk) - [chainTaskEitherKW](#chaintaskeitherkw) - [chainW](#chainw) - [flatten](#flatten) - [combinators](#combinators) + - [chainEitherK](#chaineitherk) + - [chainIOEitherK](#chainioeitherk) + - [chainTaskEitherK](#chaintaskeitherk) - [filterOrElse](#filterorelse) + - [fromEitherK](#fromeitherk) + - [fromIOEitherK](#fromioeitherk) + - [fromTaskEitherK](#fromtaskeitherk) + - [local](#local) - [orElse](#orelse) - [swap](#swap) - [constructors](#constructors) + - [ask](#ask) + - [asks](#asks) - [fromEither](#fromeither) - [fromIOEither](#fromioeither) - [fromOption](#fromoption) @@ -71,13 +77,7 @@ Added in v2.0.0 - [URI](#uri) - [URI (type alias)](#uri-type-alias) - [utils](#utils) - - [ask](#ask) - - [asks](#asks) - [bracket](#bracket) - - [fromEitherK](#fromeitherk) - - [fromIOEitherK](#fromioeitherk) - - [fromTaskEitherK](#fromtaskeitherk) - - [local](#local) - [run](#run) --- @@ -187,18 +187,6 @@ export declare const chain: ( Added in v2.0.0 -## chainEitherK - -**Signature** - -```ts -export declare function chainEitherK( - f: (a: A) => Either -): (ma: ReaderTaskEither) => ReaderTaskEither -``` - -Added in v2.4.0 - ## chainEitherKW **Signature** @@ -223,18 +211,6 @@ export declare const chainFirst: ( Added in v2.0.0 -## chainIOEitherK - -**Signature** - -```ts -export declare function chainIOEitherK( - f: (a: A) => IOEither -): (ma: ReaderTaskEither) => ReaderTaskEither -``` - -Added in v2.4.0 - ## chainIOEitherKW **Signature** @@ -247,18 +223,6 @@ export declare const chainIOEitherKW: ( Added in v2.6.1 -## chainTaskEitherK - -**Signature** - -```ts -export declare function chainTaskEitherK( - f: (a: A) => TaskEither -): (ma: ReaderTaskEither) => ReaderTaskEither -``` - -Added in v2.4.0 - ## chainTaskEitherKW **Signature** @@ -297,6 +261,42 @@ Added in v2.0.0 # combinators +## chainEitherK + +**Signature** + +```ts +export declare function chainEitherK( + f: (a: A) => Either +): (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.4.0 + +## chainIOEitherK + +**Signature** + +```ts +export declare function chainIOEitherK( + f: (a: A) => IOEither +): (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.4.0 + +## chainTaskEitherK + +**Signature** + +```ts +export declare function chainTaskEitherK( + f: (a: A) => TaskEither +): (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.4.0 + ## filterOrElse **Signature** @@ -312,6 +312,52 @@ export declare const filterOrElse: { Added in v2.0.0 +## fromEitherK + +**Signature** + +```ts +export declare function fromEitherK, B>( + f: (...a: A) => Either +): (...a: A) => ReaderTaskEither +``` + +Added in v2.4.0 + +## fromIOEitherK + +**Signature** + +```ts +export declare function fromIOEitherK, B>( + f: (...a: A) => IOEither +): (...a: A) => ReaderTaskEither +``` + +Added in v2.4.0 + +## fromTaskEitherK + +**Signature** + +```ts +export declare function fromTaskEitherK, B>( + f: (...a: A) => TaskEither +): (...a: A) => ReaderTaskEither +``` + +Added in v2.4.0 + +## local + +**Signature** + +```ts +export declare const local: (f: (f: Q) => R) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.0.0 + ## orElse **Signature** @@ -336,6 +382,26 @@ Added in v2.0.0 # constructors +## ask + +**Signature** + +```ts +export declare const ask: () => ReaderTaskEither +``` + +Added in v2.0.0 + +## asks + +**Signature** + +```ts +export declare const asks: (f: (r: R) => A) => ReaderTaskEither +``` + +Added in v2.0.0 + ## fromEither **Signature** @@ -474,7 +540,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const rightReader: (ma: Reader) => ReaderTaskEither +export declare const rightReader: (ma: R.Reader) => ReaderTaskEither ``` Added in v2.0.0 @@ -654,26 +720,6 @@ Added in v2.0.0 # utils -## ask - -**Signature** - -```ts -export declare const ask: () => ReaderTaskEither -``` - -Added in v2.0.0 - -## asks - -**Signature** - -```ts -export declare const asks: (f: (r: R) => A) => ReaderTaskEither -``` - -Added in v2.0.0 - ## bracket Make sure that a resource is cleaned up in the event of an exception (_). The release action is called regardless of @@ -693,52 +739,6 @@ export declare function bracket( Added in v2.0.4 -## fromEitherK - -**Signature** - -```ts -export declare function fromEitherK, B>( - f: (...a: A) => Either -): (...a: A) => ReaderTaskEither -``` - -Added in v2.4.0 - -## fromIOEitherK - -**Signature** - -```ts -export declare function fromIOEitherK, B>( - f: (...a: A) => IOEither -): (...a: A) => ReaderTaskEither -``` - -Added in v2.4.0 - -## fromTaskEitherK - -**Signature** - -```ts -export declare function fromTaskEitherK, B>( - f: (...a: A) => TaskEither -): (...a: A) => ReaderTaskEither -``` - -Added in v2.4.0 - -## local - -**Signature** - -```ts -export declare function local(f: (f: Q) => R): (ma: ReaderTaskEither) => ReaderTaskEither -``` - -Added in v2.0.0 - ## run **Signature** diff --git a/docs/modules/ReadonlyArray.ts.md b/docs/modules/ReadonlyArray.ts.md index 036d891fe..a0eff0d64 100644 --- a/docs/modules/ReadonlyArray.ts.md +++ b/docs/modules/ReadonlyArray.ts.md @@ -117,10 +117,13 @@ Added in v2.5.0 - [lookup](#lookup) - [modifyAt](#modifyat) - [of](#of) + - [sequence](#sequence) - [spanLeft](#spanleft) - [splitAt](#splitat) - [tail](#tail) - [takeRight](#takeright) + - [traverse](#traverse) + - [traverseWithIndex](#traversewithindex) - [unsafeInsertAt](#unsafeinsertat) - [unzip](#unzip) - [updateAt](#updateat) @@ -1739,6 +1742,16 @@ export declare const of: (a: A) => readonly A[] Added in v2.5.0 +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence1<'ReadonlyArray'> +``` + +Added in v2.6.3 + ## spanLeft Split an array into two parts: @@ -1829,6 +1842,26 @@ assert.deepStrictEqual(takeRight(2)([1, 2, 3, 4, 5]), [4, 5]) Added in v2.5.0 +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse1<'ReadonlyArray'> +``` + +Added in v2.6.3 + +## traverseWithIndex + +**Signature** + +```ts +export declare const traverseWithIndex: PipeableTraverseWithIndex1<'ReadonlyArray', number> +``` + +Added in v2.6.3 + ## unsafeInsertAt **Signature** diff --git a/docs/modules/ReadonlyMap.ts.md b/docs/modules/ReadonlyMap.ts.md index bc31bb9bd..65533eb33 100644 --- a/docs/modules/ReadonlyMap.ts.md +++ b/docs/modules/ReadonlyMap.ts.md @@ -68,7 +68,7 @@ Added in v2.5.0 **Signature** ```ts -export declare const compact: (fa: ReadonlyMap>) => ReadonlyMap +export declare const compact: (fa: ReadonlyMap>) => ReadonlyMap ``` Added in v2.5.0 @@ -105,7 +105,7 @@ Added in v2.5.0 **Signature** ```ts -export declare const filterMap: (f: (a: A) => Option) => (fa: ReadonlyMap) => ReadonlyMap +export declare const filterMap: (f: (a: A) => O.Option) => (fa: ReadonlyMap) => ReadonlyMap ``` Added in v2.5.0 @@ -263,11 +263,11 @@ Unfolds a map into a list of key/value pairs ```ts export declare function toUnfoldable( - O: Ord, + ord: Ord, U: Unfoldable1 ): (d: ReadonlyMap) => Kind export declare function toUnfoldable( - O: Ord, + ord: Ord, U: Unfoldable ): (d: ReadonlyMap) => HKT ``` diff --git a/docs/modules/ReadonlyNonEmptyArray.ts.md b/docs/modules/ReadonlyNonEmptyArray.ts.md index 0bce51498..e0960823a 100644 --- a/docs/modules/ReadonlyNonEmptyArray.ts.md +++ b/docs/modules/ReadonlyNonEmptyArray.ts.md @@ -61,7 +61,7 @@ Added in v2.5.0 - [getShow](#getshow) - [readonlyNonEmptyArray](#readonlynonemptyarray) - [model](#model) - - [ReadonlyNonEmptyArray (interface)](#readonlynonemptyarray-interface) + - [ReadonlyNonEmptyArray (type alias)](#readonlynonemptyarray-type-alias) - [URI](#uri) - [URI (type alias)](#uri-type-alias) - [utils](#utils) @@ -75,7 +75,10 @@ Added in v2.5.0 - [max](#max) - [min](#min) - [modifyAt](#modifyat) + - [sequence](#sequence) - [tail](#tail) + - [traverse](#traverse) + - [traverseWithIndex](#traversewithindex) - [unzip](#unzip) - [updateAt](#updateat) @@ -562,12 +565,12 @@ Added in v2.5.0 # model -## ReadonlyNonEmptyArray (interface) +## ReadonlyNonEmptyArray (type alias) **Signature** ```ts -export interface ReadonlyNonEmptyArray extends ReadonlyArray { +export type ReadonlyNonEmptyArray = ReadonlyArray & { readonly 0: A } ``` @@ -720,6 +723,16 @@ export declare function modifyAt( Added in v2.5.0 +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence1<'ReadonlyNonEmptyArray'> +``` + +Added in v2.6.3 + ## tail **Signature** @@ -730,6 +743,26 @@ export declare function tail(nea: ReadonlyNonEmptyArray): ReadonlyArray Added in v2.5.0 +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse1<'ReadonlyNonEmptyArray'> +``` + +Added in v2.6.3 + +## traverseWithIndex + +**Signature** + +```ts +export declare const traverseWithIndex: PipeableTraverseWithIndex1<'ReadonlyNonEmptyArray', number> +``` + +Added in v2.6.3 + ## unzip **Signature** diff --git a/docs/modules/ReadonlyTuple.ts.md b/docs/modules/ReadonlyTuple.ts.md index c3ccfa077..58786eb75 100644 --- a/docs/modules/ReadonlyTuple.ts.md +++ b/docs/modules/ReadonlyTuple.ts.md @@ -43,6 +43,9 @@ Added in v2.5.0 - [model](#model) - [URI](#uri) - [URI (type alias)](#uri-type-alias) +- [utils](#utils) + - [sequence](#sequence) + - [traverse](#traverse) --- @@ -279,3 +282,25 @@ export type URI = typeof URI ``` Added in v2.5.0 + +# utils + +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence2<'ReadonlyTuple'> +``` + +Added in v2.6.3 + +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse2<'ReadonlyTuple'> +``` + +Added in v2.6.3 diff --git a/docs/modules/State.ts.md b/docs/modules/State.ts.md index 17a77e476..b83113076 100644 --- a/docs/modules/State.ts.md +++ b/docs/modules/State.ts.md @@ -24,6 +24,11 @@ Added in v2.0.0 - [chain](#chain) - [chainFirst](#chainfirst) - [flatten](#flatten) +- [constructors](#constructors) + - [get](#get) + - [gets](#gets) + - [modify](#modify) + - [put](#put) - [instances](#instances) - [state](#state) - [model](#model) @@ -33,10 +38,6 @@ Added in v2.0.0 - [utils](#utils) - [evalState](#evalstate) - [execState](#execstate) - - [get](#get) - - [gets](#gets) - - [modify](#modify) - - [put](#put) --- @@ -128,122 +129,124 @@ export declare const flatten: (mma: State>) => State Added in v2.0.0 -# instances +# constructors -## state +## get + +Get the current state **Signature** ```ts -export declare const state: Monad2<'State'> +export declare const get: () => State ``` Added in v2.0.0 -# model +## gets -## State (interface) +Get a value which depends on the current state **Signature** ```ts -export interface State { - (s: S): [A, S] -} +export declare const gets: (f: (s: S) => A) => State ``` Added in v2.0.0 -## URI +## modify + +Modify the state by applying a function to the current state **Signature** ```ts -export declare const URI: 'State' +export declare const modify: (f: (s: S) => S) => State ``` Added in v2.0.0 -## URI (type alias) +## put + +Set the state **Signature** ```ts -export type URI = typeof URI +export declare const put: (s: S) => State ``` Added in v2.0.0 -# utils - -## evalState +# instances -Run a computation in the `State` monad, discarding the final state +## state **Signature** ```ts -export declare const evalState: (ma: State, s: S) => A +export declare const state: Monad2<'State'> ``` Added in v2.0.0 -## execState +# model -Run a computation in the `State` monad discarding the result +## State (interface) **Signature** ```ts -export declare const execState: (ma: State, s: S) => S +export interface State { + (s: S): [A, S] +} ``` Added in v2.0.0 -## get - -Get the current state +## URI **Signature** ```ts -export declare const get: () => State +export declare const URI: 'State' ``` Added in v2.0.0 -## gets - -Get a value which depends on the current state +## URI (type alias) **Signature** ```ts -export declare const gets: (f: (s: S) => A) => State +export type URI = typeof URI ``` Added in v2.0.0 -## modify +# utils -Modify the state by applying a function to the current state +## evalState + +Run a computation in the `State` monad, discarding the final state **Signature** ```ts -export declare const modify: (f: (s: S) => S) => State +export declare const evalState: (ma: State, s: S) => A ``` Added in v2.0.0 -## put +## execState -Set the state +Run a computation in the `State` monad discarding the result **Signature** ```ts -export declare const put: (s: S) => State +export declare const execState: (ma: State, s: S) => S ``` Added in v2.0.0 diff --git a/docs/modules/StateReaderTaskEither.ts.md b/docs/modules/StateReaderTaskEither.ts.md index 9a23c9ebf..bf2a0ee6a 100644 --- a/docs/modules/StateReaderTaskEither.ts.md +++ b/docs/modules/StateReaderTaskEither.ts.md @@ -12,42 +12,44 @@ Added in v2.0.0

Table of contents

-- [model](#model) - - [StateReaderTaskEither (interface)](#statereadertaskeither-interface) - - [URI](#uri) - - [URI (type alias)](#uri-type-alias) -- [utils](#utils) +- [Alt](#alt) - [alt](#alt) +- [Apply](#apply) - [ap](#ap) - [apFirst](#apfirst) - [apSecond](#apsecond) +- [Bifunctor](#bifunctor) - [bimap](#bimap) + - [mapLeft](#mapleft) +- [Functor](#functor) + - [map](#map) +- [Monad](#monad) - [chain](#chain) + - [chainFirst](#chainfirst) + - [chainW](#chainw) + - [flatten](#flatten) +- [combinators](#combinators) - [chainEitherK](#chaineitherk) - [chainEitherKW](#chaineitherkw) - - [chainFirst](#chainfirst) - [chainIOEitherK](#chainioeitherk) - [chainIOEitherKW](#chainioeitherkw) - [chainReaderTaskEitherK](#chainreadertaskeitherk) - [chainReaderTaskEitherKW](#chainreadertaskeitherkw) - [chainTaskEitherK](#chaintaskeitherk) - [chainTaskEitherKW](#chaintaskeitherkw) - - [chainW](#chainw) - - [evalState](#evalstate) - - [execState](#execstate) - [filterOrElse](#filterorelse) - - [flatten](#flatten) - - [fromEither](#fromeither) - [fromEitherK](#fromeitherk) - - [fromIOEither](#fromioeither) - [fromIOEitherK](#fromioeitherk) + - [fromReaderTaskEitherK](#fromreadertaskeitherk) + - [fromTaskEitherK](#fromtaskeitherk) +- [constructors](#constructors) + - [fromEither](#fromeither) + - [fromIOEither](#fromioeither) - [fromOption](#fromoption) - [fromPredicate](#frompredicate) - [fromReaderEither](#fromreadereither) - [fromReaderTaskEither](#fromreadertaskeither) - - [fromReaderTaskEitherK](#fromreadertaskeitherk) - [fromTaskEither](#fromtaskeither) - - [fromTaskEitherK](#fromtaskeitherk) - [get](#get) - [gets](#gets) - [left](#left) @@ -55,8 +57,6 @@ Added in v2.0.0 - [leftReader](#leftreader) - [leftState](#leftstate) - [leftTask](#lefttask) - - [map](#map) - - [mapLeft](#mapleft) - [modify](#modify) - [put](#put) - [right](#right) @@ -64,47 +64,20 @@ Added in v2.0.0 - [rightReader](#rightreader) - [rightState](#rightstate) - [rightTask](#righttask) +- [model](#model) + - [StateReaderTaskEither (interface)](#statereadertaskeither-interface) + - [URI](#uri) + - [URI (type alias)](#uri-type-alias) +- [utils](#utils) + - [evalState](#evalstate) + - [execState](#execstate) - [run](#run) - [stateReaderTaskEither](#statereadertaskeither) - [stateReaderTaskEitherSeq](#statereadertaskeitherseq) --- -# model - -## StateReaderTaskEither (interface) - -**Signature** - -```ts -export interface StateReaderTaskEither { - (s: S): ReaderTaskEither -} -``` - -Added in v2.0.0 - -## URI - -**Signature** - -```ts -export declare const URI: 'StateReaderTaskEither' -``` - -Added in v2.0.0 - -## URI (type alias) - -**Signature** - -```ts -export type URI = typeof URI -``` - -Added in v2.0.0 - -# utils +# Alt ## alt @@ -118,6 +91,8 @@ export declare const alt: ( Added in v2.6.2 +# Apply + ## ap **Signature** @@ -154,6 +129,8 @@ export declare const apSecond: ( Added in v2.0.0 +# Bifunctor + ## bimap **Signature** @@ -167,6 +144,34 @@ export declare const bimap: ( Added in v2.6.2 +## mapLeft + +**Signature** + +```ts +export declare const mapLeft: ( + f: (e: E) => G +) => (fa: StateReaderTaskEither) => StateReaderTaskEither +``` + +Added in v2.6.2 + +# Functor + +## map + +**Signature** + +```ts +export declare const map: ( + f: (a: A) => B +) => (fa: StateReaderTaskEither) => StateReaderTaskEither +``` + +Added in v2.0.0 + +# Monad + ## chain **Signature** @@ -179,6 +184,44 @@ export declare const chain: ( Added in v2.0.0 +## chainFirst + +**Signature** + +```ts +export declare const chainFirst: ( + f: (a: A) => StateReaderTaskEither +) => (ma: StateReaderTaskEither) => StateReaderTaskEither +``` + +Added in v2.0.0 + +## chainW + +**Signature** + +```ts +export declare const chainW: ( + f: (a: A) => StateReaderTaskEither +) => (ma: StateReaderTaskEither) => StateReaderTaskEither +``` + +Added in v2.6.0 + +## flatten + +**Signature** + +```ts +export declare const flatten: ( + mma: StateReaderTaskEither> +) => StateReaderTaskEither +``` + +Added in v2.0.0 + +# combinators + ## chainEitherK **Signature** @@ -203,18 +246,6 @@ export declare const chainEitherKW: ( Added in v2.6.1 -## chainFirst - -**Signature** - -```ts -export declare const chainFirst: ( - f: (a: A) => StateReaderTaskEither -) => (ma: StateReaderTaskEither) => StateReaderTaskEither -``` - -Added in v2.0.0 - ## chainIOEitherK **Signature** @@ -287,48 +318,6 @@ export declare const chainTaskEitherKW: ( Added in v2.6.1 -## chainW - -**Signature** - -```ts -export declare const chainW: ( - f: (a: A) => StateReaderTaskEither -) => (ma: StateReaderTaskEither) => StateReaderTaskEither -``` - -Added in v2.6.0 - -## evalState - -Run a computation in the `StateReaderTaskEither` monad, discarding the final state - -**Signature** - -```ts -export declare const evalState: ( - ma: StateReaderTaskEither, - s: S -) => RTE.ReaderTaskEither -``` - -Added in v2.0.0 - -## execState - -Run a computation in the `StateReaderTaskEither` monad discarding the result - -**Signature** - -```ts -export declare const execState: ( - ma: StateReaderTaskEither, - s: S -) => RTE.ReaderTaskEither -``` - -Added in v2.0.0 - ## filterOrElse **Signature** @@ -346,61 +335,75 @@ export declare const filterOrElse: { Added in v2.4.4 -## flatten +## fromEitherK **Signature** ```ts -export declare const flatten: ( - mma: StateReaderTaskEither> -) => StateReaderTaskEither +export declare function fromEitherK, B>( + f: (...a: A) => Either +): (...a: A) => StateReaderTaskEither ``` -Added in v2.0.0 +Added in v2.4.0 -## fromEither +## fromIOEitherK **Signature** ```ts -export declare const fromEither: (ma: Either) => StateReaderTaskEither +export declare function fromIOEitherK, B>( + f: (...a: A) => IOEither +): (...a: A) => StateReaderTaskEither ``` -Added in v2.0.0 +Added in v2.4.0 -## fromEitherK +## fromReaderTaskEitherK **Signature** ```ts -export declare function fromEitherK, B>( - f: (...a: A) => Either +export declare function fromReaderTaskEitherK, B>( + f: (...a: A) => ReaderTaskEither +): (...a: A) => StateReaderTaskEither +``` + +Added in v2.4.0 + +## fromTaskEitherK + +**Signature** + +```ts +export declare function fromTaskEitherK, B>( + f: (...a: A) => TaskEither ): (...a: A) => StateReaderTaskEither ``` Added in v2.4.0 -## fromIOEither +# constructors + +## fromEither **Signature** ```ts -export declare function fromIOEither(ma: IOEither): StateReaderTaskEither +export declare const fromEither: (ma: Either) => StateReaderTaskEither ``` Added in v2.0.0 -## fromIOEitherK +## fromIOEither **Signature** ```ts -export declare function fromIOEitherK, B>( - f: (...a: A) => IOEither -): (...a: A) => StateReaderTaskEither +export declare function fromIOEither(ma: IOEither): StateReaderTaskEither ``` -Added in v2.4.0 +Added in v2.0.0 ## fromOption @@ -449,18 +452,6 @@ export declare const fromReaderTaskEither: ( Added in v2.0.0 -## fromReaderTaskEitherK - -**Signature** - -```ts -export declare function fromReaderTaskEitherK, B>( - f: (...a: A) => ReaderTaskEither -): (...a: A) => StateReaderTaskEither -``` - -Added in v2.4.0 - ## fromTaskEither **Signature** @@ -471,18 +462,6 @@ export declare function fromTaskEither(ma: TaskEither): StateR Added in v2.0.0 -## fromTaskEitherK - -**Signature** - -```ts -export declare function fromTaskEitherK, B>( - f: (...a: A) => TaskEither -): (...a: A) => StateReaderTaskEither -``` - -Added in v2.4.0 - ## get Get the current state @@ -557,30 +536,6 @@ export declare function leftTask(me: Task): State Added in v2.0.0 -## map - -**Signature** - -```ts -export declare const map: ( - f: (a: A) => B -) => (fa: StateReaderTaskEither) => StateReaderTaskEither -``` - -Added in v2.0.0 - -## mapLeft - -**Signature** - -```ts -export declare const mapLeft: ( - f: (e: E) => G -) => (fa: StateReaderTaskEither) => StateReaderTaskEither -``` - -Added in v2.6.2 - ## modify Modify the state by applying a function to the current state @@ -655,6 +610,72 @@ export declare function rightTask(ma: Task
): Stat Added in v2.0.0 +# model + +## StateReaderTaskEither (interface) + +**Signature** + +```ts +export interface StateReaderTaskEither { + (s: S): ReaderTaskEither +} +``` + +Added in v2.0.0 + +## URI + +**Signature** + +```ts +export declare const URI: 'StateReaderTaskEither' +``` + +Added in v2.0.0 + +## URI (type alias) + +**Signature** + +```ts +export type URI = typeof URI +``` + +Added in v2.0.0 + +# utils + +## evalState + +Run a computation in the `StateReaderTaskEither` monad, discarding the final state + +**Signature** + +```ts +export declare const evalState: ( + ma: StateReaderTaskEither, + s: S +) => RTE.ReaderTaskEither +``` + +Added in v2.0.0 + +## execState + +Run a computation in the `StateReaderTaskEither` monad discarding the result + +**Signature** + +```ts +export declare const execState: ( + ma: StateReaderTaskEither, + s: S +) => RTE.ReaderTaskEither +``` + +Added in v2.0.0 + ## run **Signature** diff --git a/docs/modules/TaskEither.ts.md b/docs/modules/TaskEither.ts.md index 17e6fc8ce..0be4abf4c 100644 --- a/docs/modules/TaskEither.ts.md +++ b/docs/modules/TaskEither.ts.md @@ -28,17 +28,22 @@ Added in v2.0.0 - [map](#map) - [Monad](#monad) - [chain](#chain) - - [chainEitherK](#chaineitherk) - - [chainEitherKW](#chaineitherkw) - [chainFirst](#chainfirst) - - [chainIOEitherK](#chainioeitherk) - - [chainIOEitherKW](#chainioeitherkw) - [chainW](#chainw) - [flatten](#flatten) +- [MonadThrow](#monadthrow) + - [bracket](#bracket) - [combinators](#combinators) + - [chainEitherK](#chaineitherk) + - [chainEitherKW](#chaineitherkw) + - [chainIOEitherK](#chainioeitherk) + - [chainIOEitherKW](#chainioeitherkw) - [filterOrElse](#filterorelse) + - [fromEitherK](#fromeitherk) + - [fromIOEitherK](#fromioeitherk) - [orElse](#orelse) - [swap](#swap) + - [tryCatchK](#trycatchk) - [constructors](#constructors) - [fromEither](#fromeither) - [fromIOEither](#fromioeither) @@ -68,11 +73,6 @@ Added in v2.0.0 - [TaskEither (interface)](#taskeither-interface) - [URI](#uri) - [URI (type alias)](#uri-type-alias) -- [utils](#utils) - - [bracket](#bracket) - - [fromEitherK](#fromeitherk) - - [fromIOEitherK](#fromioeitherk) - - [tryCatchK](#trycatchk) --- @@ -166,83 +166,104 @@ export declare const chain: (f: (a: A) => TaskEither) => (ma: Tas Added in v2.0.0 -## chainEitherK +## chainFirst **Signature** ```ts -export declare function chainEitherK(f: (a: A) => Either): (ma: TaskEither) => TaskEither +export declare const chainFirst: (f: (a: A) => TaskEither) => (ma: TaskEither) => TaskEither ``` -Added in v2.4.0 +Added in v2.0.0 -## chainEitherKW +## chainW **Signature** ```ts -export declare const chainEitherKW: ( - f: (a: A) => E.Either +export declare const chainW: ( + f: (a: A) => TaskEither ) => (ma: TaskEither) => TaskEither ``` -Added in v2.6.1 +Added in v2.6.0 -## chainFirst +## flatten **Signature** ```ts -export declare const chainFirst: (f: (a: A) => TaskEither) => (ma: TaskEither) => TaskEither +export declare const flatten: (mma: TaskEither>) => TaskEither ``` Added in v2.0.0 -## chainIOEitherK +# MonadThrow + +## bracket + +Make sure that a resource is cleaned up in the event of an exception (_). The release action is called regardless of +whether the body action throws (_) or returns. + +(\*) i.e. returns a `Left` **Signature** ```ts -export declare function chainIOEitherK(f: (a: A) => IOEither): (ma: TaskEither) => TaskEither +export declare const bracket: ( + acquire: TaskEither, + use: (a: A) => TaskEither, + release: (a: A, e: E.Either) => TaskEither +) => TaskEither +``` + +Added in v2.0.0 + +# combinators + +## chainEitherK + +**Signature** + +```ts +export declare function chainEitherK(f: (a: A) => Either): (ma: TaskEither) => TaskEither ``` Added in v2.4.0 -## chainIOEitherKW +## chainEitherKW **Signature** ```ts -export declare const chainIOEitherKW: ( - f: (a: A) => IOEither +export declare const chainEitherKW: ( + f: (a: A) => E.Either ) => (ma: TaskEither) => TaskEither ``` Added in v2.6.1 -## chainW +## chainIOEitherK **Signature** ```ts -export declare const chainW: ( - f: (a: A) => TaskEither -) => (ma: TaskEither) => TaskEither +export declare function chainIOEitherK(f: (a: A) => IOEither): (ma: TaskEither) => TaskEither ``` -Added in v2.6.0 +Added in v2.4.0 -## flatten +## chainIOEitherKW **Signature** ```ts -export declare const flatten: (mma: TaskEither>) => TaskEither +export declare const chainIOEitherKW: ( + f: (a: A) => IOEither +) => (ma: TaskEither) => TaskEither ``` -Added in v2.0.0 - -# combinators +Added in v2.6.1 ## filterOrElse @@ -257,12 +278,36 @@ export declare const filterOrElse: { Added in v2.0.0 +## fromEitherK + +**Signature** + +```ts +export declare function fromEitherK, B>( + f: (...a: A) => Either +): (...a: A) => TaskEither +``` + +Added in v2.4.0 + +## fromIOEitherK + +**Signature** + +```ts +export declare function fromIOEitherK, B>( + f: (...a: A) => IOEither +): (...a: A) => TaskEither +``` + +Added in v2.4.0 + ## orElse **Signature** ```ts -export declare function orElse(onLeft: (e: E) => TaskEither): (ma: TaskEither) => TaskEither +export declare const orElse: (onLeft: (e: E) => TaskEither) => (ma: TaskEither) => TaskEither ``` Added in v2.0.0 @@ -277,6 +322,21 @@ export declare const swap: (ma: TaskEither) => TaskEither Added in v2.0.0 +## tryCatchK + +Converts a function returning a `Promise` to one returning a `TaskEither`. + +**Signature** + +```ts +export declare function tryCatchK, B>( + f: (...a: A) => Promise, + onRejected: (reason: unknown) => E +): (...a: A) => TaskEither +``` + +Added in v2.5.0 + # constructors ## fromEither @@ -337,7 +397,7 @@ Added in v2.0.0 **Signature** ```ts -export declare function leftIO(me: IO): TaskEither +export declare const leftIO: (me: IO) => TaskEither ``` Added in v2.0.0 @@ -347,7 +407,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const leftTask: (me: Task) => TaskEither +export declare const leftTask: (me: T.Task) => TaskEither ``` Added in v2.0.0 @@ -367,7 +427,7 @@ Added in v2.0.0 **Signature** ```ts -export declare function rightIO(ma: IO): TaskEither +export declare const rightIO: (ma: IO) => TaskEither ``` Added in v2.0.0 @@ -377,7 +437,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const rightTask: (ma: Task) => TaskEither +export declare const rightTask: (ma: T.Task) => TaskEither ``` Added in v2.0.0 @@ -469,10 +529,10 @@ Added in v2.0.0 **Signature** ```ts -export declare function fold( - onLeft: (e: E) => Task, - onRight: (a: A) => Task -): (ma: TaskEither) => Task +export declare const fold: ( + onLeft: (e: E) => T.Task, + onRight: (a: A) => T.Task +) => (ma: TaskEither) => T.Task ``` Added in v2.0.0 @@ -482,7 +542,7 @@ Added in v2.0.0 **Signature** ```ts -export declare function getOrElse(onLeft: (e: E) => Task): (ma: TaskEither) => Task +export declare const getOrElse: (onLeft: (e: E) => T.Task) => (ma: TaskEither) => T.Task ``` Added in v2.0.0 @@ -492,7 +552,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const getOrElseW: (onLeft: (e: E) => Task) => (ma: TaskEither) => Task +export declare const getOrElseW: (onLeft: (e: E) => T.Task) => (ma: TaskEither) => T.Task ``` Added in v2.6.0 @@ -618,63 +678,3 @@ export type URI = typeof URI ``` Added in v2.0.0 - -# utils - -## bracket - -Make sure that a resource is cleaned up in the event of an exception (_). The release action is called regardless of -whether the body action throws (_) or returns. - -(\*) i.e. returns a `Left` - -**Signature** - -```ts -export declare function bracket( - acquire: TaskEither, - use: (a: A) => TaskEither, - release: (a: A, e: Either) => TaskEither -): TaskEither -``` - -Added in v2.0.0 - -## fromEitherK - -**Signature** - -```ts -export declare function fromEitherK, B>( - f: (...a: A) => Either -): (...a: A) => TaskEither -``` - -Added in v2.4.0 - -## fromIOEitherK - -**Signature** - -```ts -export declare function fromIOEitherK, B>( - f: (...a: A) => IOEither -): (...a: A) => TaskEither -``` - -Added in v2.4.0 - -## tryCatchK - -Converts a function returning a `Promise` to one returning a `TaskEither`. - -**Signature** - -```ts -export declare function tryCatchK, B>( - f: (...a: A) => Promise, - onRejected: (reason: unknown) => E -): (...a: A) => TaskEither -``` - -Added in v2.5.0 diff --git a/docs/modules/TaskThese.ts.md b/docs/modules/TaskThese.ts.md index 808cb39ab..9cb732b6d 100644 --- a/docs/modules/TaskThese.ts.md +++ b/docs/modules/TaskThese.ts.md @@ -125,7 +125,7 @@ Added in v2.4.0 **Signature** ```ts -export declare function leftIO(me: IO): TaskThese +export declare const leftIO: (me: IO) => TaskThese ``` Added in v2.4.0 @@ -135,7 +135,7 @@ Added in v2.4.0 **Signature** ```ts -export declare const leftTask: (me: Task) => TaskThese +export declare const leftTask: (me: T.Task) => TaskThese ``` Added in v2.4.0 @@ -155,7 +155,7 @@ Added in v2.4.0 **Signature** ```ts -export declare function rightIO(ma: IO): TaskThese +export declare const rightIO: (ma: IO) => TaskThese ``` Added in v2.4.0 @@ -165,7 +165,7 @@ Added in v2.4.0 **Signature** ```ts -export declare const rightTask: (ma: Task) => TaskThese +export declare const rightTask: (ma: T.Task) => TaskThese ``` Added in v2.4.0 @@ -177,11 +177,11 @@ Added in v2.4.0 **Signature** ```ts -export declare function fold( - onLeft: (e: E) => Task, - onRight: (a: A) => Task, - onBoth: (e: E, a: A) => Task -): (fa: TaskThese) => Task +export declare const fold: ( + onLeft: (e: E) => T.Task, + onRight: (a: A) => T.Task, + onBoth: (e: E, a: A) => T.Task +) => (fa: TaskThese) => T.Task ``` Added in v2.4.0 @@ -191,7 +191,7 @@ Added in v2.4.0 **Signature** ```ts -export declare function toTuple(e: E, a: A): (fa: TaskThese) => Task<[E, A]> +export declare const toTuple: (e: E, a: A) => (fa: TaskThese) => T.Task<[E, A]> ``` Added in v2.4.0 diff --git a/docs/modules/These.ts.md b/docs/modules/These.ts.md index e13939e86..6068ae1a8 100644 --- a/docs/modules/These.ts.md +++ b/docs/modules/These.ts.md @@ -70,6 +70,9 @@ Added in v2.0.0 - [These (type alias)](#these-type-alias) - [URI](#uri) - [URI (type alias)](#uri-type-alias) +- [utils](#utils) + - [sequence](#sequence) + - [traverse](#traverse) --- @@ -510,3 +513,25 @@ export type URI = typeof URI ``` Added in v2.0.0 + +# utils + +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence2<'These'> +``` + +Added in v2.6.3 + +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse2<'These'> +``` + +Added in v2.6.3 diff --git a/docs/modules/Traversable.ts.md b/docs/modules/Traversable.ts.md index 30aa4688b..e9f0bf255 100644 --- a/docs/modules/Traversable.ts.md +++ b/docs/modules/Traversable.ts.md @@ -44,6 +44,8 @@ Added in v2.0.0 - [Traversable2C (interface)](#traversable2c-interface) - [Traversable3 (interface)](#traversable3-interface) - [utils](#utils) + - [PipeableTraverse1 (interface)](#pipeabletraverse1-interface) + - [PipeableTraverse2 (interface)](#pipeabletraverse2-interface) - [Sequence (interface)](#sequence-interface) - [Sequence1 (interface)](#sequence1-interface) - [Sequence2 (interface)](#sequence2-interface) @@ -134,6 +136,55 @@ Added in v2.0.0 # utils +## PipeableTraverse1 (interface) + +**Signature** + +```ts +export interface PipeableTraverse1 { + (F: Applicative3): ( + f: (a: A) => Kind3 + ) => (ta: Kind) => Kind3> + (F: Applicative3C): ( + f: (a: A) => Kind3 + ) => (ta: Kind) => Kind3> + (F: Applicative2): ( + f: (a: A) => Kind2 + ) => (ta: Kind) => Kind2> + (F: Applicative2C): ( + f: (a: A) => Kind2 + ) => (ta: Kind) => Kind2> + (F: Applicative1): (f: (a: A) => Kind) => (ta: Kind) => Kind> + (F: Applicative): (f: (a: A) => HKT) => (ta: Kind) => HKT> +} +``` + +Added in v2.6.3 + +## PipeableTraverse2 (interface) + +**Signature** + +```ts +export interface PipeableTraverse2 { + (F: Applicative3): ( + f: (a: A) => Kind3 + ) => (ta: Kind2) => Kind3> + (F: Applicative2): ( + f: (a: A) => Kind2 + ) => (ta: Kind2) => Kind2> + (F: Applicative2C): ( + f: (a: A) => Kind2 + ) => (ta: Kind2) => Kind2> + (F: Applicative1): ( + f: (a: A) => Kind + ) => (ta: Kind2) => Kind> + (F: Applicative): (f: (a: A) => HKT) => (ta: Kind2) => HKT> +} +``` + +Added in v2.6.3 + ## Sequence (interface) **Signature** diff --git a/docs/modules/TraversableWithIndex.ts.md b/docs/modules/TraversableWithIndex.ts.md index da38ff5ed..31e0a5a23 100644 --- a/docs/modules/TraversableWithIndex.ts.md +++ b/docs/modules/TraversableWithIndex.ts.md @@ -32,6 +32,8 @@ Added in v2.0.0

Table of contents

- [utils](#utils) + - [PipeableTraverseWithIndex1 (interface)](#pipeabletraversewithindex1-interface) + - [PipeableTraverseWithIndex2 (interface)](#pipeabletraversewithindex2-interface) - [TraversableWithIndex (interface)](#traversablewithindex-interface) - [TraversableWithIndex1 (interface)](#traversablewithindex1-interface) - [TraversableWithIndex2 (interface)](#traversablewithindex2-interface) @@ -45,6 +47,55 @@ Added in v2.0.0 # utils +## PipeableTraverseWithIndex1 (interface) + +**Signature** + +```ts +export interface PipeableTraverseWithIndex1 { + (F: Applicative3): ( + f: (i: I, a: A) => Kind3 + ) => (ta: Kind) => Kind3> + (F: Applicative3C): ( + f: (i: I, a: A) => Kind3 + ) => (ta: Kind) => Kind3> + (F: Applicative2): ( + f: (i: I, a: A) => Kind2 + ) => (ta: Kind) => Kind2> + (F: Applicative2C): ( + f: (i: I, a: A) => Kind2 + ) => (ta: Kind) => Kind2> + (F: Applicative1): (f: (i: I, a: A) => Kind) => (ta: Kind) => Kind> + (F: Applicative): (f: (i: I, a: A) => HKT) => (ta: Kind) => HKT> +} +``` + +Added in v2.6.3 + +## PipeableTraverseWithIndex2 (interface) + +**Signature** + +```ts +export interface PipeableTraverseWithIndex2 { + (F: Applicative3): ( + f: (i: I, a: A) => Kind3 + ) => (ta: Kind2) => Kind3> + (F: Applicative2): ( + f: (i: I, a: A) => Kind2 + ) => (ta: Kind2) => Kind2> + (F: Applicative2C): ( + f: (i: I, a: A) => Kind2 + ) => (ta: Kind2) => Kind2> + (F: Applicative1): ( + f: (i: I, a: A) => Kind + ) => (ta: Kind2) => Kind> + (F: Applicative): (f: (i: I, a: A) => HKT) => (ta: Kind2) => HKT> +} +``` + +Added in v2.6.3 + ## TraversableWithIndex (interface) **Signature** diff --git a/docs/modules/Tree.ts.md b/docs/modules/Tree.ts.md index 7fc154234..42106da71 100644 --- a/docs/modules/Tree.ts.md +++ b/docs/modules/Tree.ts.md @@ -58,6 +58,8 @@ Added in v2.0.0 - [drawForest](#drawforest) - [drawTree](#drawtree) - [elem](#elem) + - [sequence](#sequence) + - [traverse](#traverse) --- @@ -210,7 +212,7 @@ Added in v2.0.0 **Signature** ```ts -export declare function make
(value: A, forest: Forest = empty): Tree +export declare function make(value: A, forest: Forest = A.empty): Tree ``` Added in v2.0.0 @@ -462,3 +464,23 @@ export declare function elem(E: Eq): (a: A, fa: Tree) => boolean ``` Added in v2.0.0 + +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence1<'Tree'> +``` + +Added in v2.6.3 + +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse1<'Tree'> +``` + +Added in v2.6.3 diff --git a/docs/modules/Tuple.ts.md b/docs/modules/Tuple.ts.md index 91aaf2d4e..8120d39c6 100644 --- a/docs/modules/Tuple.ts.md +++ b/docs/modules/Tuple.ts.md @@ -43,6 +43,9 @@ Added in v2.0.0 - [model](#model) - [URI](#uri) - [URI (type alias)](#uri-type-alias) +- [utils](#utils) + - [sequence](#sequence) + - [traverse](#traverse) --- @@ -279,3 +282,25 @@ export type URI = typeof URI ``` Added in v2.0.0 + +# utils + +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence2<'Tuple'> +``` + +Added in v2.6.3 + +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse2<'Tuple'> +``` + +Added in v2.6.3 diff --git a/docs/modules/Writer.ts.md b/docs/modules/Writer.ts.md index 0343428d2..8821f4466 100644 --- a/docs/modules/Writer.ts.md +++ b/docs/modules/Writer.ts.md @@ -14,6 +14,12 @@ Added in v2.0.0 - [Functor](#functor) - [map](#map) +- [combinators](#combinators) + - [censor](#censor) + - [listen](#listen) + - [listens](#listens) + - [pass](#pass) + - [tell](#tell) - [instances](#instances) - [getMonad](#getmonad) - [writer](#writer) @@ -22,13 +28,8 @@ Added in v2.0.0 - [URI (type alias)](#uri-type-alias) - [Writer (interface)](#writer-interface) - [utils](#utils) - - [censor](#censor) - [evalWriter](#evalwriter) - [execWriter](#execwriter) - - [listen](#listen) - - [listens](#listens) - - [pass](#pass) - - [tell](#tell) --- @@ -44,140 +45,142 @@ export declare const map: (f: (a: A) => B) => (fa: Writer) => Wri Added in v2.0.0 -# instances +# combinators -## getMonad +## censor + +Modify the final accumulator value by applying a function **Signature** ```ts -export declare function getMonad(M: Monoid): Monad2C +export declare const censor: (f: (w: W) => W) => (fa: Writer) => Writer ``` Added in v2.0.0 -## writer +## listen + +Modifies the result to include the changes to the accumulator **Signature** ```ts -export declare const writer: Functor2<'Writer'> +export declare const listen: (fa: Writer) => Writer ``` Added in v2.0.0 -# model +## listens -## URI +Projects a value from modifications made to the accumulator during an action **Signature** ```ts -export declare const URI: 'Writer' +export declare const listens: (f: (w: W) => B) => (fa: Writer) => Writer ``` Added in v2.0.0 -## URI (type alias) +## pass + +Applies the returned function to the accumulator **Signature** ```ts -export type URI = typeof URI +export declare const pass: (fa: Writer W]>) => Writer ``` Added in v2.0.0 -## Writer (interface) +## tell + +Appends a value to the accumulator **Signature** ```ts -export interface Writer { - (): [A, W] -} +export declare const tell: (w: W) => Writer ``` Added in v2.0.0 -# utils - -## censor +# instances -Modify the final accumulator value by applying a function +## getMonad **Signature** ```ts -export declare function censor(f: (w: W) => W): (fa: Writer) => Writer +export declare function getMonad(M: Monoid): Monad2C ``` Added in v2.0.0 -## evalWriter +## writer **Signature** ```ts -export declare const evalWriter: (fa: Writer) => A +export declare const writer: Functor2<'Writer'> ``` Added in v2.0.0 -## execWriter +# model + +## URI **Signature** ```ts -export declare const execWriter: (fa: Writer) => W +export declare const URI: 'Writer' ``` Added in v2.0.0 -## listen - -Modifies the result to include the changes to the accumulator +## URI (type alias) **Signature** ```ts -export declare const listen: (fa: Writer) => Writer +export type URI = typeof URI ``` Added in v2.0.0 -## listens - -Projects a value from modifications made to the accumulator during an action +## Writer (interface) **Signature** ```ts -export declare function listens(f: (w: W) => B): (fa: Writer) => Writer +export interface Writer { + (): [A, W] +} ``` Added in v2.0.0 -## pass +# utils -Applies the returned function to the accumulator +## evalWriter **Signature** ```ts -export declare const pass: (fa: Writer W]>) => Writer +export declare const evalWriter: (fa: Writer) => A ``` Added in v2.0.0 -## tell - -Appends a value to the accumulator +## execWriter **Signature** ```ts -export declare const tell: (w: W) => Writer +export declare const execWriter: (fa: Writer) => W ``` Added in v2.0.0 diff --git a/docs/modules/function.ts.md b/docs/modules/function.ts.md index 06f7bd7ed..31dbf70b7 100644 --- a/docs/modules/function.ts.md +++ b/docs/modules/function.ts.md @@ -31,6 +31,7 @@ Added in v2.0.0 - [identity](#identity) - [increment](#increment) - [not](#not) + - [pipe](#pipe) - [tuple](#tuple) - [tupled](#tupled) - [unsafeCoerce](#unsafecoerce) @@ -216,7 +217,7 @@ Added in v2.0.0 Performs left-to-right function composition. The first argument may have any arity, the remaining arguments must be unary. -See also [`pipe`](https://gcanti.github.io/fp-ts/modules/pipeable.ts.html#pipe). +See also [`pipe`](#pipe). **Signature** @@ -329,6 +330,89 @@ export declare function not(predicate: Predicate): Predicate Added in v2.0.0 +## pipe + +Pipes the value of an expression into a pipeline of functions. + +See also [`flow`](#flow). + +**Signature** + +```ts +export declare function pipe(a: A): A +export declare function pipe(a: A, ab: (a: A) => B): B +export declare function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C): C +export declare function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D +export declare function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): E +export declare function pipe( + a: A, + ab: (a: A) => B, + bc: (b: B) => C, + cd: (c: C) => D, + de: (d: D) => E, + ef: (e: E) => F +): F +export declare function pipe( + a: A, + ab: (a: A) => B, + bc: (b: B) => C, + cd: (c: C) => D, + de: (d: D) => E, + ef: (e: E) => F, + fg: (f: F) => G +): G +export declare function pipe( + a: A, + ab: (a: A) => B, + bc: (b: B) => C, + cd: (c: C) => D, + de: (d: D) => E, + ef: (e: E) => F, + fg: (f: F) => G, + gh: (g: G) => H +): H +export declare function pipe( + a: A, + ab: (a: A) => B, + bc: (b: B) => C, + cd: (c: C) => D, + de: (d: D) => E, + ef: (e: E) => F, + fg: (f: F) => G, + gh: (g: G) => H, + hi: (h: H) => I +): I +export declare function pipe( + a: A, + ab: (a: A) => B, + bc: (b: B) => C, + cd: (c: C) => D, + de: (d: D) => E, + ef: (e: E) => F, + fg: (f: F) => G, + gh: (g: G) => H, + hi: (h: H) => I, + ij: (i: I) => J +): J +``` + +**Example** + +```ts +import { pipe } from 'fp-ts/lib/pipeable' + +const len = (s: string): number => s.length +const double = (n: number): number => n * 2 + +// without pipe +assert.strictEqual(double(len('aaa')), 6) + +// with pipe +assert.strictEqual(pipe('aaa', len, double), 6) +``` + +Added in v2.6.3 + ## tuple **Signature** diff --git a/docs/modules/pipeable.ts.md b/docs/modules/pipeable.ts.md index f9b6b5964..056730ed5 100644 --- a/docs/modules/pipeable.ts.md +++ b/docs/modules/pipeable.ts.md @@ -1774,83 +1774,12 @@ Added in v2.0.0 ## pipe -Pipes the value of an expression into a pipeline of functions. - -See also [`flow`](https://gcanti.github.io/fp-ts/modules/function.ts.html#flow). - -**Signature** - -```ts -export declare function pipe(a: A): A -export declare function pipe(a: A, ab: (a: A) => B): B -export declare function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C): C -export declare function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D -export declare function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): E -export declare function pipe( - a: A, - ab: (a: A) => B, - bc: (b: B) => C, - cd: (c: C) => D, - de: (d: D) => E, - ef: (e: E) => F -): F -export declare function pipe( - a: A, - ab: (a: A) => B, - bc: (b: B) => C, - cd: (c: C) => D, - de: (d: D) => E, - ef: (e: E) => F, - fg: (f: F) => G -): G -export declare function pipe( - a: A, - ab: (a: A) => B, - bc: (b: B) => C, - cd: (c: C) => D, - de: (d: D) => E, - ef: (e: E) => F, - fg: (f: F) => G, - gh: (g: G) => H -): H -export declare function pipe( - a: A, - ab: (a: A) => B, - bc: (b: B) => C, - cd: (c: C) => D, - de: (d: D) => E, - ef: (e: E) => F, - fg: (f: F) => G, - gh: (g: G) => H, - hi: (h: H) => I -): I -export declare function pipe( - a: A, - ab: (a: A) => B, - bc: (b: B) => C, - cd: (c: C) => D, - de: (d: D) => E, - ef: (e: E) => F, - fg: (f: F) => G, - gh: (g: G) => H, - hi: (h: H) => I, - ij: (i: I) => J -): J -``` - -**Example** - -```ts -import { pipe } from 'fp-ts/lib/pipeable' - -const len = (s: string): number => s.length -const double = (n: number): number => n * 2 - -// without pipe -assert.strictEqual(double(len('aaa')), 6) - -// with pipe -assert.strictEqual(pipe('aaa', len, double), 6) +Use [`pipe`](https://gcanti.github.io/fp-ts/modules/function.ts.html#flow) from `function` module instead. + +**Signature** + +```ts +export declare const pipe: typeof pipeFromFunctionModule ``` Added in v2.0.0 diff --git a/jest.config.js b/jest.config.js index e0498c8ba..02076e514 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,7 +2,15 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', collectCoverage: true, - collectCoverageFrom: ['src/**/*.ts', '!src/pipeable.ts'], + collectCoverageFrom: [ + 'src/**/*.ts', + '!src/pipeable.ts', + '!src/EitherT.ts', + '!src/ReaderT.ts', + '!src/StateT.ts', + '!src/TheseT.ts', + '!src/WriterT.ts' + ], transform: { '^.+\\.tsx?$': 'ts-jest' }, diff --git a/package-lock.json b/package-lock.json index 724a627bc..68c3115e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1773,9 +1773,9 @@ } }, "docs-ts": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/docs-ts/-/docs-ts-0.5.0.tgz", - "integrity": "sha512-UMnWN0X9pAPsPRRTJRz3VVVcRt9Ydg6GAiIUAJ/erGShgg4H5/u2gURZsbGf2g8DWrfBBf3aVbeLR7Q0EYRg5g==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/docs-ts/-/docs-ts-0.5.1.tgz", + "integrity": "sha512-zdBt4P6X7h577/Vku0YHAw/RR1+zpKklK+DOzed1HJltwAAciQG14qy18TzcMbVUFxrnT9OO4Y1K/lQLdX1i/Q==", "dev": true, "requires": { "chalk": "^2.4.2", diff --git a/package.json b/package.json index f50ddee15..3dec0c3f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fp-ts", - "version": "2.6.2", + "version": "2.6.3", "description": "Functional programming in TypeScript", "files": [ "lib", @@ -43,7 +43,7 @@ "@types/node": "^12.6.8", "@types/prettier": "1.10.0", "benchmark": "2.1.4", - "docs-ts": "^0.5.0", + "docs-ts": "^0.5.1", "doctoc": "^1.4.0", "dtslint": "github:gcanti/dtslint", "fast-check": "^1.23.0", diff --git a/src/Applicative.ts b/src/Applicative.ts index 2a522271a..29af9e6ae 100644 --- a/src/Applicative.ts +++ b/src/Applicative.ts @@ -254,7 +254,7 @@ export function getApplicativeComposition( export function getApplicativeComposition(F: Applicative, G: Applicative): ApplicativeComposition export function getApplicativeComposition(F: Applicative, G: Applicative): ApplicativeComposition { return { - ...getFunctorComposition(F, G), + map: getFunctorComposition(F, G).map, of: (a) => F.of(G.of(a)), ap: (fgab: HKT B>>, fga: HKT>): HKT> => F.ap( diff --git a/src/Apply.ts b/src/Apply.ts index 8e6d52fed..59719409f 100644 --- a/src/Apply.ts +++ b/src/Apply.ts @@ -243,3 +243,49 @@ export function sequenceS(F: Apply): (r: Record>) => H } } /* tslint:enable:readonly-array */ + +/** + * @internal + */ +export function apComposition( + F: Apply2, + G: Apply2 +): ( + fga: Kind2> +) => (fgab: Kind2 B>>) => Kind2> +export function apComposition( + F: Apply2, + G: Apply2C +): ( + fga: Kind2> +) => (fgab: Kind2 B>>) => Kind2> +export function apComposition( + F: Apply1, + G: Apply2 +): (fga: Kind>) => (fgab: Kind B>>) => Kind> +export function apComposition( + F: Apply1, + G: Apply2C +): (fga: Kind>) => (fgab: Kind B>>) => Kind> +export function apComposition( + F: Apply1, + G: Apply1 +): (fga: Kind>) => (fgab: Kind B>>) => Kind> +export function apComposition( + F: Apply, + G: Apply2 +): (fga: HKT>) => (fgab: HKT B>>) => HKT> +export function apComposition( + F: Apply, + G: Apply +): (fga: HKT>) => (fgab: HKT B>>) => HKT> +export function apComposition( + F: Apply, + G: Apply +): (fga: HKT>) => (fgab: HKT B>>) => HKT> { + return (fga: HKT>) => (fgab: HKT B>>): HKT> => + F.ap( + F.map(fgab, (h) => (ga: HKT) => G.ap(h, ga)), + fga + ) +} diff --git a/src/Array.ts b/src/Array.ts index c8f00a9e4..199323178 100644 --- a/src/Array.ts +++ b/src/Array.ts @@ -18,9 +18,10 @@ import { Option } from './Option' import { Ord } from './Ord' import * as RA from './ReadonlyArray' import { Show } from './Show' -import { TraversableWithIndex1 } from './TraversableWithIndex' +import { TraversableWithIndex1, PipeableTraverseWithIndex1 } from './TraversableWithIndex' import { Unfoldable1 } from './Unfoldable' import { Witherable1 } from './Witherable' +import { Traversable1, PipeableTraverse1 } from './Traversable' // ------------------------------------------------------------------------------------- // model @@ -28,12 +29,6 @@ import { Witherable1 } from './Witherable' /* tslint:disable:readonly-array */ -declare module './HKT' { - interface URItoKind { - readonly Array: Array - } -} - /** * @category model * @since 2.0.0 @@ -46,6 +41,12 @@ export const URI = 'Array' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: Array + } +} + /** * @category instances * @since 2.0.0 @@ -1157,6 +1158,21 @@ export const reduceRightWithIndex: (b: B, f: (i: number, a: A, b: B) => B) // instances // ------------------------------------------------------------------------------------- +/** + * @since 2.6.3 + */ +export const traverse: PipeableTraverse1 = RA.traverse as any + +/** + * @since 2.6.3 + */ +export const sequence: Traversable1['sequence'] = RA.sequence as any + +/** + * @since 2.6.3 + */ +export const traverseWithIndex: PipeableTraverseWithIndex1 = RA.traverseWithIndex as any + /** * @category instances * @since 2.0.0 @@ -1174,8 +1190,5 @@ export const array: Monad1 & FoldableWithIndex1 = /*#__PURE__*/ (() => { - return { - ...(RA.readonlyArray as any), - URI - } + return Object.assign({}, RA.readonlyArray as any, { URI }) })() diff --git a/src/Bounded.ts b/src/Bounded.ts index aa5a7ff78..09bfa16c5 100644 --- a/src/Bounded.ts +++ b/src/Bounded.ts @@ -23,7 +23,8 @@ export interface Bounded extends Ord { * @since 2.0.0 */ export const boundedNumber: Bounded = { - ...ordNumber, + equals: ordNumber.equals, + compare: ordNumber.compare, top: Infinity, bottom: -Infinity } diff --git a/src/BoundedDistributiveLattice.ts b/src/BoundedDistributiveLattice.ts index d531c6b84..ad0a37f1d 100644 --- a/src/BoundedDistributiveLattice.ts +++ b/src/BoundedDistributiveLattice.ts @@ -18,8 +18,10 @@ export interface BoundedDistributiveLattice extends BoundedLattice, Distri * @since 2.0.0 */ export function getMinMaxBoundedDistributiveLattice(O: Ord): (min: A, max: A) => BoundedDistributiveLattice { + const L = getMinMaxDistributiveLattice(O) return (min, max) => ({ - ...getMinMaxDistributiveLattice(O), + join: L.join, + meet: L.meet, zero: min, one: max }) diff --git a/src/Compactable.ts b/src/Compactable.ts index 8f22de0d2..ec6ca15e9 100644 --- a/src/Compactable.ts +++ b/src/Compactable.ts @@ -261,7 +261,7 @@ export function getCompactableComposition( ): CompactableComposition { const FC = getFunctorComposition(F, G) const CC: CompactableComposition = { - ...FC, + map: FC.map, compact: (fga) => F.map(fga, G.compact), separate: (fge) => { const left = CC.compact(FC.map(fge, getLeft)) diff --git a/src/Const.ts b/src/Const.ts index 3d551940e..d8356d37b 100644 --- a/src/Const.ts +++ b/src/Const.ts @@ -24,12 +24,6 @@ import { Semigroup } from './Semigroup' import { Semiring } from './Semiring' import { Show } from './Show' -declare module './HKT' { - interface URItoKind2 { - readonly Const: Const - } -} - /** * @category model * @since 2.0.0 @@ -42,6 +36,12 @@ export const URI = 'Const' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: Const + } +} + /** * @category model * @since 2.0.0 @@ -136,8 +136,12 @@ export function getApply(S: Semigroup): Apply2C { * @since 2.0.0 */ export function getApplicative(M: Monoid): Applicative2C { + const A = getApply(M) return { - ...getApply(M), + URI, + _E: undefined as any, + map: A.map, + ap: A.ap, of: () => make(M.empty) } } diff --git a/src/Either.ts b/src/Either.ts index 71727e3a4..d3a77b038 100644 --- a/src/Either.ts +++ b/src/Either.ts @@ -11,14 +11,15 @@ */ import { Alt2, Alt2C } from './Alt' -import { Applicative, Applicative2 } from './Applicative' +import { Applicative } from './Applicative' +import { Apply2 } from './Apply' import { Bifunctor2 } from './Bifunctor' -import { ChainRec2, tailRec, ChainRec2C } from './ChainRec' +import { ChainRec2, ChainRec2C, tailRec } from './ChainRec' import { Separated } from './Compactable' import { Eq } from './Eq' import { Extend2 } from './Extend' import { Foldable2 } from './Foldable' -import { Lazy, Predicate, identity, Refinement } from './function' +import { identity, Lazy, Predicate, Refinement } from './function' import { HKT } from './HKT' import { Monad2, Monad2C } from './Monad' import { MonadThrow2, MonadThrow2C } from './MonadThrow' @@ -26,15 +27,9 @@ import { Monoid } from './Monoid' import { Option } from './Option' import { Semigroup } from './Semigroup' import { Show } from './Show' -import { Traversable2 } from './Traversable' +import { PipeableTraverse2, Traversable2 } from './Traversable' import { Witherable2C } from './Witherable' -declare module './HKT' { - interface URItoKind2 { - readonly Either: Either - } -} - /** * @category model * @since 2.0.0 @@ -47,6 +42,12 @@ export const URI = 'Either' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: Either + } +} + /** * @category model * @since 2.0.0 @@ -264,7 +265,7 @@ export function getApplySemigroup(S: Semigroup): Semigroup */ export function getApplyMonoid(M: Monoid): Monoid> { return { - ...getApplySemigroup(M), + concat: getApplySemigroup(M).concat, empty: right(M.empty) } } @@ -469,7 +470,7 @@ export function getWitherable(M: Monoid): Witherable2C { partition, partitionMap, traverse: traverse_, - sequence: sequence_, + sequence, reduce: reduce_, foldMap: foldMap_, reduceRight: reduceRight_, @@ -493,8 +494,21 @@ export function getValidation( ChainRec2C & MonadThrow2C { return { - ...either, + URI, _E: undefined as any, + map: map_, + of, + chain: chain_, + bimap: bimap_, + mapLeft: mapLeft_, + reduce: reduce_, + foldMap: foldMap_, + reduceRight: reduceRight_, + extend: extend_, + traverse: traverse_, + sequence, + chainRec: chainRec_, + throwError: throwError_, ap: (mab, ma) => isLeft(mab) ? isLeft(ma) @@ -545,51 +559,25 @@ export function getValidationMonoid(SE: Semigroup, SA: Monoid): Mono // pipeables // ------------------------------------------------------------------------------------- -const map_: (fa: Either, f: (a: A) => B) => Either = (ma, f) => - isLeft(ma) ? ma : right(f(ma.right)) - -const ap_: (fab: Either B>, fa: Either) => Either = (mab, ma) => - isLeft(mab) ? mab : isLeft(ma) ? ma : right(mab.right(ma.right)) - -const chain_: (fa: Either, f: (a: A) => Either) => Either = (ma, f) => - isLeft(ma) ? ma : f(ma.right) - -const reduce_: (fa: Either, b: B, f: (b: B, a: A) => B) => B = (fa, b, f) => - isLeft(fa) ? b : f(b, fa.right) - -const foldMap_: (M: Monoid) => (fa: Either, f: (a: A) => M) => M = (M) => (fa, f) => - isLeft(fa) ? M.empty : f(fa.right) - -const reduceRight_: (fa: Either, b: B, f: (a: A, b: B) => B) => B = (fa, b, f) => - isLeft(fa) ? b : f(fa.right, b) - -const traverse_ = (F: Applicative) => ( - ma: Either, - f: (a: A) => HKT -): HKT> => { - return isLeft(ma) ? F.of(left(ma.left)) : F.map>(f(ma.right), right) +/** + * @since 2.6.3 + */ +export const traverse: PipeableTraverse2 = ( + F: Applicative +): ((f: (a: A) => HKT) => (ta: Either) => HKT>) => { + const traverseF = traverse_(F) + return (f) => (fa) => traverseF(fa, f) } -const sequence_ = (F: Applicative) => (ma: Either>): HKT> => { +/** + * @since 2.6.3 + */ +export const sequence: Traversable2['sequence'] = (F: Applicative) => ( + ma: Either> +): HKT> => { return isLeft(ma) ? F.of(left(ma.left)) : F.map>(ma.right, right) } -const bimap_: (fea: Either, f: (e: E) => G, g: (a: A) => B) => Either = (fea, f, g) => - isLeft(fea) ? left(f(fea.left)) : right(g(fea.right)) - -const mapLeft_: (fea: Either, f: (e: E) => G) => Either = (fea, f) => - isLeft(fea) ? left(f(fea.left)) : fea - -const alt_: (fx: Either, fy: () => Either) => Either = (fx, fy) => (isLeft(fx) ? fy() : fx) - -const extend_: (wa: Either, f: (wa: Either) => B) => Either = (wa, f) => - isLeft(wa) ? wa : right(f(wa)) - -const chainRec_: (a: A, f: (a: A) => Either>) => Either = (a, f) => - tailRec(f(a), (e) => - isLeft(e) ? right(left(e.left)) : isLeft(e.right) ? left(f(e.right.left)) : right(right(e.right.right)) - ) - /** * @category Alt * @since 2.0.0 @@ -736,23 +724,45 @@ export const filterOrElse: { // instances // ------------------------------------------------------------------------------------- -/** - * @internal - */ -export const applicativeEither: Applicative2 = { - URI, - map: map_, - of: right, - ap: ap_ +const map_: (fa: Either, f: (a: A) => B) => Either = (ma, f) => + isLeft(ma) ? ma : right(f(ma.right)) +const ap_: (fab: Either B>, fa: Either) => Either = (mab, ma) => + isLeft(mab) ? mab : isLeft(ma) ? ma : right(mab.right(ma.right)) +const of = right +const chain_: (fa: Either, f: (a: A) => Either) => Either = (ma, f) => + isLeft(ma) ? ma : f(ma.right) +const reduce_: (fa: Either, b: B, f: (b: B, a: A) => B) => B = (fa, b, f) => + isLeft(fa) ? b : f(b, fa.right) +const foldMap_: (M: Monoid) => (fa: Either, f: (a: A) => M) => M = (M) => (fa, f) => + isLeft(fa) ? M.empty : f(fa.right) +const reduceRight_: (fa: Either, b: B, f: (a: A, b: B) => B) => B = (fa, b, f) => + isLeft(fa) ? b : f(fa.right, b) +const traverse_ = (F: Applicative) => ( + ma: Either, + f: (a: A) => HKT +): HKT> => { + return isLeft(ma) ? F.of(left(ma.left)) : F.map>(f(ma.right), right) } +const bimap_: (fea: Either, f: (e: E) => G, g: (a: A) => B) => Either = (fea, f, g) => + isLeft(fea) ? left(f(fea.left)) : right(g(fea.right)) +const mapLeft_: (fea: Either, f: (e: E) => G) => Either = (fea, f) => + isLeft(fea) ? left(f(fea.left)) : fea +const alt_: (fx: Either, fy: () => Either) => Either = (fx, fy) => (isLeft(fx) ? fy() : fx) +const extend_: (wa: Either, f: (wa: Either) => B) => Either = (wa, f) => + isLeft(wa) ? wa : right(f(wa)) +const chainRec_: (a: A, f: (a: A) => Either>) => Either = (a, f) => + tailRec(f(a), (e) => + isLeft(e) ? right(left(e.left)) : isLeft(e.right) ? left(f(e.right.left)) : right(right(e.right.right)) + ) +const throwError_ = left /** * @internal */ -export const bifunctorEither: Bifunctor2 = { +export const applyEither: Apply2 = { URI, - bimap: bimap_, - mapLeft: mapLeft_ + map: map_, + ap: ap_ } /** @@ -769,18 +779,18 @@ export const either: Monad2 & MonadThrow2 = { URI, map: map_, - of: right, + of, ap: ap_, chain: chain_, reduce: reduce_, foldMap: foldMap_, reduceRight: reduceRight_, traverse: traverse_, - sequence: sequence_, + sequence, bimap: bimap_, mapLeft: mapLeft_, alt: alt_, extend: extend_, chainRec: chainRec_, - throwError: left + throwError: throwError_ } diff --git a/src/EitherT.ts b/src/EitherT.ts index 3157da4e4..3ce522756 100644 --- a/src/EitherT.ts +++ b/src/EitherT.ts @@ -1,16 +1,16 @@ /** * @since 2.0.0 */ -import { - ApplicativeComposition12, - ApplicativeComposition22, - ApplicativeCompositionHKT2, - getApplicativeComposition -} from './Applicative' -import { applicativeEither, bifunctorEither, Either, fold, isLeft, left, right, swap, URI } from './Either' +import { ApplicativeComposition12, ApplicativeComposition22, ApplicativeCompositionHKT2 } from './Applicative' +import { apComposition } from './Apply' +import * as E from './Either' +import { flow, pipe } from './function' import { HKT, Kind, Kind2, URIS, URIS2 } from './HKT' import { Monad, Monad1, Monad2 } from './Monad' +import Either = E.Either +import URI = E.URI + /** * @category model * @since 2.0.0 @@ -98,24 +98,27 @@ export function getEitherM(M: Monad2): EitherM2 export function getEitherM(M: Monad1): EitherM1 export function getEitherM(M: Monad): EitherM export function getEitherM(M: Monad): EitherM { - const A = getApplicativeComposition(M, applicativeEither) + const ap = apComposition(M, E.applyEither) + const of = flow(E.right, M.of) return { - ...A, - chain: (ma, f) => M.chain(ma, (e) => (isLeft(e) ? M.of(left(e.left)) : f(e.right))), - alt: (fx, f) => M.chain(fx, (e) => (isLeft(e) ? f() : A.of(e.right))), - bimap: (ma, f, g) => M.map(ma, (e) => bifunctorEither.bimap(e, f, g)), - mapLeft: (ma, f) => M.map(ma, (e) => bifunctorEither.mapLeft(e, f)), - fold: (ma, onLeft, onRight) => M.chain(ma, fold(onLeft, onRight)), - getOrElse: (ma, onLeft) => M.chain(ma, fold(onLeft, M.of)), + map: (fa, f) => M.map(fa, E.map(f)), + ap: (fab, fa) => pipe(fab, ap(fa)), + of, + chain: (ma, f) => M.chain(ma, (e) => (E.isLeft(e) ? M.of(E.left(e.left)) : f(e.right))), + alt: (fx, f) => M.chain(fx, (e) => (E.isLeft(e) ? f() : of(e.right))), + bimap: (ma, f, g) => M.map(ma, (e) => pipe(e, E.bimap(f, g))), + mapLeft: (ma, f) => M.map(ma, (e) => pipe(e, E.mapLeft(f))), + fold: (ma, onLeft, onRight) => M.chain(ma, E.fold(onLeft, onRight)), + getOrElse: (ma, onLeft) => M.chain(ma, E.fold(onLeft, M.of)), orElse: (ma, f) => M.chain( ma, - fold(f, (a) => A.of(a)) + E.fold(f, (a) => of(a)) ), - swap: (ma) => M.map(ma, swap), - rightM: (ma) => M.map(ma, right), - leftM: (ml) => M.map(ml, left), - left: (e) => M.of(left(e)) + swap: (ma) => M.map(ma, E.swap), + rightM: (ma) => M.map(ma, E.right), + leftM: (ml) => M.map(ml, E.left), + left: (e) => M.of(E.left(e)) } } diff --git a/src/Eq.ts b/src/Eq.ts index 5fa16b2fe..9d5b5f01f 100644 --- a/src/Eq.ts +++ b/src/Eq.ts @@ -13,12 +13,6 @@ import { Contravariant1 } from './Contravariant' import { Monoid } from './Monoid' import { ReadonlyRecord } from './ReadonlyRecord' -declare module './HKT' { - interface URItoKind { - readonly Eq: Eq - } -} - /** * @category model * @since 2.0.0 @@ -31,6 +25,12 @@ export const URI = 'Eq' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: Eq + } +} + /** * @category type classes * @since 2.0.0 diff --git a/src/Filterable.ts b/src/Filterable.ts index 67521ae32..a1eb6dbd9 100644 --- a/src/Filterable.ts +++ b/src/Filterable.ts @@ -481,8 +481,11 @@ export function getFilterableComposition( ): FilterableComposition11 export function getFilterableComposition(F: Functor, G: Filterable): FilterableComposition export function getFilterableComposition(F: Functor, G: Filterable): FilterableComposition { + const CC = getCompactableComposition(F, G) const FC: FilterableComposition = { - ...getCompactableComposition(F, G), + map: CC.map, + compact: CC.compact, + separate: CC.separate, partitionMap: (fga, f) => { const left = FC.filterMap(fga, (a) => getLeft(f(a))) const right = FC.filterMap(fga, (a) => getRight(f(a))) diff --git a/src/FoldableWithIndex.ts b/src/FoldableWithIndex.ts index b744b9483..e52802065 100644 --- a/src/FoldableWithIndex.ts +++ b/src/FoldableWithIndex.ts @@ -241,8 +241,11 @@ export function getFoldableWithIndexComposition( F: FoldableWithIndex, G: FoldableWithIndex ): FoldableWithIndexComposition { + const FC = getFoldableComposition(F, G) return { - ...getFoldableComposition(F, G), + reduce: FC.reduce, + foldMap: FC.foldMap, + reduceRight: FC.reduceRight, reduceWithIndex: (fga, b, f) => F.reduceWithIndex(fga, b, (fi, b, ga) => G.reduceWithIndex(ga, b, (gi, b, a) => f([fi, gi], b, a))), foldMapWithIndex: (M) => { diff --git a/src/FunctorWithIndex.ts b/src/FunctorWithIndex.ts index 529637934..ca2a1394d 100644 --- a/src/FunctorWithIndex.ts +++ b/src/FunctorWithIndex.ts @@ -200,7 +200,7 @@ export function getFunctorWithIndexComposition( G: FunctorWithIndex ): FunctorWithIndexComposition { return { - ...getFunctorComposition(F, G), + map: getFunctorComposition(F, G).map, mapWithIndex: (fga, f) => F.mapWithIndex(fga, (fi, ga) => G.mapWithIndex(ga, (gi, a) => f([fi, gi], a))) } } diff --git a/src/IO.ts b/src/IO.ts index a0427730b..f5bf838e2 100644 --- a/src/IO.ts +++ b/src/IO.ts @@ -11,12 +11,7 @@ import { Monad1 } from './Monad' import { MonadIO1 } from './MonadIO' import { Monoid } from './Monoid' import { Semigroup } from './Semigroup' - -declare module './HKT' { - interface URItoKind { - readonly IO: IO - } -} +import { Apply1 } from './Apply' /** * @category model @@ -30,6 +25,12 @@ export const URI = 'IO' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: IO + } +} + /** * @category model * @since 2.0.0 @@ -130,6 +131,15 @@ export const map: (f: (a: A) => B) => (fa: IO) => IO = (f) => (fa) = // instances // ------------------------------------------------------------------------------------- +/** + * @internal + */ +export const applyIO: Apply1 = { + URI, + map: map_, + ap: ap_ +} + /** * @internal */ diff --git a/src/IOEither.ts b/src/IOEither.ts index e811d2674..790d215d2 100644 --- a/src/IOEither.ts +++ b/src/IOEither.ts @@ -7,10 +7,9 @@ import { Alt2, Alt2C } from './Alt' import { Bifunctor2 } from './Bifunctor' import * as E from './Either' -import { getEitherM } from './EitherT' import { Filterable2C, getFilterableComposition } from './Filterable' -import { identity, Lazy, Predicate, Refinement } from './function' -import { getSemigroup as getIOSemigroup, IO, monadIO } from './IO' +import { identity, Lazy, Predicate, Refinement, pipe, flow } from './function' +import * as I from './IO' import { Monad2, Monad2C } from './Monad' import { MonadIO2, MonadIO2C } from './MonadIO' import { MonadThrow2, MonadThrow2C } from './MonadThrow' @@ -18,16 +17,14 @@ import { Monoid } from './Monoid' import { Option } from './Option' import { Semigroup } from './Semigroup' import { getValidationM } from './ValidationT' +import { apComposition } from './Apply' -import Either = E.Either - -const T = /*#__PURE__*/ getEitherM(monadIO) +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- -declare module './HKT' { - interface URItoKind2 { - readonly IOEither: IOEither - } -} +import Either = E.Either +import IO = I.IO /** * @category model @@ -41,165 +38,123 @@ export const URI = 'IOEither' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: IOEither + } +} + /** * @category model * @since 2.0.0 */ export interface IOEither extends IO> {} +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- + /** * @category constructors * @since 2.0.0 */ -export const left: (l: E) => IOEither = T.left +export const left: (l: E) => IOEither = + /*#__PURE__*/ + flow(E.left, I.of) /** * @category constructors * @since 2.0.0 */ -export const right: (a: A) => IOEither = T.of +export const right: (a: A) => IOEither = + /*#__PURE__*/ + flow(E.right, I.of) /** * @category constructors * @since 2.0.0 */ -export const rightIO: (ma: IO) => IOEither = T.rightM +export const rightIO: (ma: IO) => IOEither = + /*#__PURE__*/ + I.map(E.right) /** * @category constructors * @since 2.0.0 */ -export const leftIO: (me: IO) => IOEither = T.leftM +export const leftIO: (me: IO) => IOEither = + /*#__PURE__*/ + I.map(E.left) /** - * @category destructors + * Constructs a new `IOEither` from a function that performs a side effect and might throw + * + * @category constructors * @since 2.0.0 */ -export function fold(onLeft: (e: E) => IO, onRight: (a: A) => IO): (ma: IOEither) => IO { - return (ma) => T.fold(ma, onLeft, onRight) +export function tryCatch(f: Lazy, onError: (reason: unknown) => E): IOEither { + return () => E.tryCatch(f, onError) } -/** - * @category destructors - * @since 2.0.0 - */ -export function getOrElse(onLeft: (e: E) => IO): (ma: IOEither) => IO { - return (ma) => T.getOrElse(ma, onLeft) -} +// ------------------------------------------------------------------------------------- +// destructors +// ------------------------------------------------------------------------------------- /** * @category destructors - * @since 2.6.0 - */ -export const getOrElseW: (onLeft: (e: E) => IO) => (ma: IOEither) => IO = getOrElse as any - -/** - * @category combinators * @since 2.0.0 */ -export function orElse(onLeft: (e: E) => IOEither): (ma: IOEither) => IOEither { - return (ma) => T.orElse(ma, onLeft) -} +export const fold: (onLeft: (e: E) => IO, onRight: (a: A) => IO) => (ma: IOEither) => IO = + /*#__PURE__*/ + flow(E.fold, I.chain) /** - * @category combinators + * @category destructors * @since 2.0.0 */ -export const swap: (ma: IOEither) => IOEither = T.swap +export const getOrElse: (onLeft: (e: E) => IO) => (ma: IOEither) => IO = (onLeft) => + I.chain(E.fold(onLeft, I.of)) /** - * Semigroup returning the left-most non-`Left` value. If both operands are `Right`s then the inner values are - * appended using the provided `Semigroup` - * - * @category instances - * @since 2.0.0 + * @category destructors + * @since 2.6.0 */ -export function getSemigroup(S: Semigroup): Semigroup> { - return getIOSemigroup(E.getSemigroup(S)) -} +export const getOrElseW: (onLeft: (e: E) => IO) => (ma: IOEither) => IO = getOrElse as any -/** - * Semigroup returning the left-most `Left` value. If both operands are `Right`s then the inner values - * are appended using the provided `Semigroup` - * - * @category instances - * @since 2.0.0 - */ -export function getApplySemigroup(S: Semigroup): Semigroup> { - return getIOSemigroup(E.getApplySemigroup(S)) -} +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- /** - * @category instances + * @category combinators * @since 2.0.0 */ -export function getApplyMonoid(M: Monoid): Monoid> { - return { - concat: getApplySemigroup(M).concat, - empty: right(M.empty) - } -} +export const orElse: (onLeft: (e: E) => IOEither) => (ma: IOEither) => IOEither = (f) => + I.chain(E.fold(f, right)) /** - * Constructs a new `IOEither` from a function that performs a side effect and might throw - * - * @category constructors + * @category combinators * @since 2.0.0 */ -export function tryCatch(f: Lazy, onError: (reason: unknown) => E): IOEither { - return () => E.tryCatch(f, onError) -} +export const swap: (ma: IOEither) => IOEither = + /*#__PURE__*/ + I.map(E.swap) /** - * Make sure that a resource is cleaned up in the event of an exception (*). The release action is called regardless of - * whether the body action throws (*) or returns. - * - * (*) i.e. returns a `Left` - * + * @category combinators * @since 2.0.0 */ -export function bracket( - acquire: IOEither, - use: (a: A) => IOEither, - release: (a: A, e: Either) => IOEither -): IOEither { - return T.chain(acquire, (a) => - T.chain(monadIO.map(use(a), E.right), (e) => - T.chain(release(a, e), () => (E.isLeft(e) ? T.left(e.left) : T.of(e.right))) - ) +export const filterOrElse: { + (refinement: Refinement, onFalse: (a: A) => E): (ma: IOEither) => IOEither + (predicate: Predicate, onFalse: (a: A) => E): (ma: IOEither) => IOEither +} = (predicate: Predicate, onFalse: (a: A) => E) => (ma: IOEither) => + pipe( + ma, + chain((a) => (predicate(a) ? right(a) : left(onFalse(a)))) ) -} - -/** - * @category instances - * @since 2.0.0 - */ -export function getIOValidation( - S: Semigroup -): Monad2C & Bifunctor2 & Alt2C & MonadIO2C & MonadThrow2C { - const T = getValidationM(S, monadIO) - return { - _E: undefined as any, - ...ioEither, - ...T - } -} - -/** - * @category instances - * @since 2.1.0 - */ -export function getFilterable(M: Monoid): Filterable2C { - const F = E.getWitherable(M) - - return { - URI, - _E: undefined as any, - ...getFilterableComposition(monadIO, F) - } -} /** + * @category combinators * @since 2.4.0 */ export function fromEitherK, B>( @@ -209,39 +164,63 @@ export function fromEitherK, B>( } /** - * @category Monad + * @category combinators * @since 2.4.0 */ export function chainEitherK(f: (a: A) => Either): (ma: IOEither) => IOEither { return chain(fromEitherK(f)) } +/** + * @category combinators + * @since 2.6.1 + */ +export const chainEitherKW: ( + f: (a: A) => Either +) => (ma: IOEither) => IOEither = chainEitherK as any + // ------------------------------------------------------------------------------------- // pipeables // ------------------------------------------------------------------------------------- /** - * @category Alt + * @category Functor * @since 2.0.0 */ -export const alt: (that: () => IOEither) => (fa: IOEither) => IOEither = (that) => (fa) => - T.alt(fa, that) +export const map: (f: (a: A) => B) => (fa: IOEither) => IOEither = (f) => I.map(E.map(f)) + +/** + * @category Bifunctor + * @since 2.0.0 + */ +export const bimap: (f: (e: E) => G, g: (a: A) => B) => (fa: IOEither) => IOEither = flow( + E.bimap, + I.map +) + +/** + * @category Bifunctor + * @since 2.0.0 + */ +export const mapLeft: (f: (e: E) => G) => (fa: IOEither) => IOEither = (f) => I.map(E.mapLeft(f)) /** * @category Apply * @since 2.0.0 */ -export const ap: (fa: IOEither) => (fab: IOEither B>) => IOEither = (fa) => (fab) => - T.ap(fab, fa) +export const ap: (fa: IOEither) => (fab: IOEither B>) => IOEither = + /*#__PURE__*/ + apComposition(I.applyIO, E.applyEither) /** * @category Apply * @since 2.0.0 */ export const apFirst: (fb: IOEither) => (fa: IOEither) => IOEither = (fb) => (fa) => - T.ap( - T.map(fa, (a) => () => a), - fb + pipe( + fa, + map((a) => () => a), + ap(fb) ) /** @@ -249,25 +228,30 @@ export const apFirst: (fb: IOEither) => (fa: IOEither) => I * @since 2.0.0 */ export const apSecond = (fb: IOEither) => (fa: IOEither): IOEither => - T.ap( - T.map(fa, () => (b: B) => b), - fb + pipe( + fa, + map(() => (b: B) => b), + ap(fb) ) /** * @category Monad * @since 2.0.0 */ -export const chain: (f: (a: A) => IOEither) => (ma: IOEither) => IOEither = (f) => (ma) => - T.chain(ma, f) +export const chain: (f: (a: A) => IOEither) => (ma: IOEither) => IOEither = (f) => + I.chain(E.fold(left, f)) /** * @category Monad * @since 2.0.0 */ -export const chainFirst: (f: (a: A) => IOEither) => (ma: IOEither) => IOEither = (f) => ( - ma -) => T.chain(ma, (a) => T.map(f(a), () => a)) +export const chainFirst: (f: (a: A) => IOEither) => (ma: IOEither) => IOEither = (f) => + chain((a) => + pipe( + f(a), + map(() => a) + ) + ) /** * @category Monad @@ -277,39 +261,47 @@ export const chainW: ( f: (a: A) => IOEither ) => (ma: IOEither) => IOEither = chain as any -/** - * @since 2.6.1 - */ -export const chainEitherKW: ( - f: (a: A) => Either -) => (ma: IOEither) => IOEither = chainEitherK as any - /** * @category Monad * @since 2.0.0 */ -export const flatten: (mma: IOEither>) => IOEither = (mma) => T.chain(mma, identity) - -/** - * @category Functor - * @since 2.0.0 - */ -export const map: (f: (a: A) => B) => (fa: IOEither) => IOEither = (f) => (fa) => T.map(fa, f) +export const flatten: (mma: IOEither>) => IOEither = chain(identity) /** - * @category Bifunctor + * @category Alt * @since 2.0.0 */ -export const bimap: (f: (e: E) => G, g: (a: A) => B) => (fa: IOEither) => IOEither = (f, g) => ( - fa -) => T.bimap(fa, f, g) +export const alt: (that: () => IOEither) => (fa: IOEither) => IOEither = (that) => + I.chain(E.fold(that, right)) /** - * @category Bifunctor + * Make sure that a resource is cleaned up in the event of an exception (*). The release action is called regardless of + * whether the body action throws (*) or returns. + * + * (*) i.e. returns a `Left` + * + * @category MonadThrow * @since 2.0.0 */ -export const mapLeft: (f: (e: E) => G) => (fa: IOEither) => IOEither = (f) => (fa) => - T.mapLeft(fa, f) +export const bracket = ( + acquire: IOEither, + use: (a: A) => IOEither, + release: (a: A, e: Either) => IOEither +): IOEither => + pipe( + acquire, + chain((a) => + pipe( + pipe(use(a), I.map(E.right)), + chain((e) => + pipe( + release(a, e), + chain(() => (E.isLeft(e) ? left(e.left) : of(e.right))) + ) + ) + ) + ) + ) /** * @category constructors @@ -327,40 +319,123 @@ export const fromPredicate: { (predicate: Predicate, onFalse: (a: A) => E): (a: A) => IOEither } = (predicate: Predicate, onFalse: (a: A) => E) => (a: A) => (predicate(a) ? right(a) : left(onFalse(a))) -/** - * @category combinators - * @since 2.0.0 - */ -export const filterOrElse: { - (refinement: Refinement, onFalse: (a: A) => E): (ma: IOEither) => IOEither - (predicate: Predicate, onFalse: (a: A) => E): (ma: IOEither) => IOEither -} = (predicate: Predicate, onFalse: (a: A) => E) => (ma: IOEither) => - T.chain(ma, (a) => (predicate(a) ? right(a) : left(onFalse(a)))) - /** * @category constructors * @since 2.0.0 */ export const fromEither: (ma: E.Either) => IOEither = (ma) => - ma._tag === 'Left' ? left(ma.left) : right(ma.right) + E.isLeft(ma) ? left(ma.left) : right(ma.right) // ------------------------------------------------------------------------------------- // instances // ------------------------------------------------------------------------------------- +/* istanbul ignore next */ +const map_: Monad2['map'] = (fa, f) => pipe(fa, map(f)) +/* istanbul ignore next */ +const bimap_: Bifunctor2['bimap'] = (fa, f, g) => pipe(fa, bimap(f, g)) +/* istanbul ignore next */ +const mapLeft_: Bifunctor2['mapLeft'] = (fa, f) => pipe(fa, mapLeft(f)) +/* istanbul ignore next */ +const ap_: Monad2['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const of = right +/* istanbul ignore next */ +const chain_: Monad2['chain'] = (ma, f) => pipe(ma, chain(f)) +/* istanbul ignore next */ +const alt_: Alt2['alt'] = (fa, that) => pipe(fa, alt(that)) +const fromIO_ = rightIO +const throwError_ = left + +/** + * Semigroup returning the left-most non-`Left` value. If both operands are `Right`s then the inner values are + * appended using the provided `Semigroup` + * + * @category instances + * @since 2.0.0 + */ +export function getSemigroup(S: Semigroup): Semigroup> { + return I.getSemigroup(E.getSemigroup(S)) +} + +/** + * Semigroup returning the left-most `Left` value. If both operands are `Right`s then the inner values + * are appended using the provided `Semigroup` + * + * @category instances + * @since 2.0.0 + */ +export function getApplySemigroup(S: Semigroup): Semigroup> { + return I.getSemigroup(E.getApplySemigroup(S)) +} + +/** + * @category instances + * @since 2.0.0 + */ +export function getApplyMonoid(M: Monoid): Monoid> { + return { + concat: getApplySemigroup(M).concat, + empty: right(M.empty) + } +} + +/** + * @category instances + * @since 2.0.0 + */ +export function getIOValidation( + S: Semigroup +): Monad2C & Bifunctor2 & Alt2C & MonadIO2C & MonadThrow2C { + const V = getValidationM(S, I.monadIO) + return { + URI, + _E: undefined as any, + map: map_, + ap: V.ap, + of, + chain: chain_, + bimap: bimap_, + mapLeft: mapLeft_, + alt: V.alt, + fromIO: fromIO_, + throwError: throwError_ + } +} + +/** + * @category instances + * @since 2.1.0 + */ +export function getFilterable(M: Monoid): Filterable2C { + const W = E.getWitherable(M) + const F = getFilterableComposition(I.monadIO, W) + + return { + URI, + _E: undefined as any, + map: map_, + compact: F.compact, + separate: F.separate, + filter: F.filter, + filterMap: F.filterMap, + partition: F.partition, + partitionMap: F.partitionMap + } +} + /** * @category instances * @since 2.0.0 */ export const ioEither: Monad2 & Bifunctor2 & Alt2 & MonadIO2 & MonadThrow2 = { URI, - bimap: T.bimap, - mapLeft: T.mapLeft, - map: T.map, - of: right, - ap: T.ap, - chain: T.chain, - alt: T.alt, - fromIO: rightIO, - throwError: left + bimap: bimap_, + mapLeft: mapLeft_, + map: map_, + of, + ap: ap_, + chain: chain_, + alt: alt_, + fromIO: fromIO_, + throwError: throwError_ } diff --git a/src/Identity.ts b/src/Identity.ts index 2327c6c4d..4d133b381 100644 --- a/src/Identity.ts +++ b/src/Identity.ts @@ -12,13 +12,7 @@ import { HKT } from './HKT' import { Monad1 } from './Monad' import { Monoid } from './Monoid' import { Show } from './Show' -import { Traversable1 } from './Traversable' - -declare module './HKT' { - interface URItoKind { - readonly Identity: Identity - } -} +import { Traversable1, PipeableTraverse1 } from './Traversable' /** * @category model @@ -32,6 +26,12 @@ export const URI = 'Identity' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: Identity + } +} + /** * @category model * @since 2.0.0 @@ -74,7 +74,22 @@ const traverse_ = (F: Applicative) => (ta: Identity, f: (a: A) => return F.map(f(ta), id) } -const sequence_ = (F: Applicative) => (ta: Identity>): HKT> => { +/** + * @since 2.6.3 + */ +export const traverse: PipeableTraverse1 = ( + F: Applicative +): ((f: (a: A) => HKT) => (ta: Identity) => HKT>) => { + const traverseF = traverse_(F) + return (f) => (ta) => traverseF(ta, f) +} + +/** + * @since 2.6.3 + */ +export const sequence: Traversable1['sequence'] = (F: Applicative) => ( + ta: Identity> +): HKT> => { return F.map(ta, id) } @@ -180,17 +195,6 @@ export const map: (f: (a: A) => B) => (fa: Identity) => Identity = ( // instances // ------------------------------------------------------------------------------------- -/** - * @internal - */ -export const monadIdentity: Monad1 = { - URI, - map: map_, - of: id, - ap: ap_, - chain: chain_ -} - /** * @category instances * @since 2.0.0 @@ -205,7 +209,7 @@ export const identity: Monad1 & Foldable1 & Traversable1 & Alt1 { - readonly Map: Map - } -} - /** * @category model * @since 2.0.0 @@ -40,6 +34,12 @@ export const URI = 'Map' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: Map + } +} + /** * @category instances * @since 2.0.0 @@ -304,8 +304,5 @@ export const getWitherable: ( export const map_: Filterable2 = /*#__PURE__*/ (() => { - return { - ...(RM.readonlyMap as any), - URI - } + return Object.assign({}, RM.readonlyMap as any, { URI }) })() diff --git a/src/NonEmptyArray.ts b/src/NonEmptyArray.ts index f173642a8..abf4b251e 100644 --- a/src/NonEmptyArray.ts +++ b/src/NonEmptyArray.ts @@ -15,16 +15,11 @@ import { Ord } from './Ord' import * as RNEA from './ReadonlyNonEmptyArray' import { Semigroup } from './Semigroup' import { Show } from './Show' -import { TraversableWithIndex1 } from './TraversableWithIndex' +import { TraversableWithIndex1, PipeableTraverseWithIndex1 } from './TraversableWithIndex' +import { Traversable1, PipeableTraverse1 } from './Traversable' /* tslint:disable:readonly-array */ -declare module './HKT' { - interface URItoKind { - readonly NonEmptyArray: NonEmptyArray - } -} - /** * @category model * @since 2.0.0 @@ -37,6 +32,12 @@ export const URI = 'NonEmptyArray' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: NonEmptyArray + } +} + /* tslint:disable:readonly-keyword */ /** * @category model @@ -437,6 +438,21 @@ export const reduceRightWithIndex: (b: B, f: (i: number, a: A, b: B) => B) // instances // ------------------------------------------------------------------------------------- +/** + * @since 2.6.3 + */ +export const traverse: PipeableTraverse1 = RNEA.traverse as any + +/** + * @since 2.6.3 + */ +export const sequence: Traversable1['sequence'] = RNEA.sequence as any + +/** + * @since 2.6.3 + */ +export const traverseWithIndex: PipeableTraverseWithIndex1 = RNEA.traverseWithIndex as any + /** * @category instances * @since 2.0.0 @@ -449,8 +465,5 @@ export const nonEmptyArray: Monad1 & Alt1 = /*#__PURE__*/ (() => { - return { - ...(RNEA.readonlyNonEmptyArray as any), - URI - } + return Object.assign({}, RNEA.readonlyNonEmptyArray as any, { URI }) })() diff --git a/src/Option.ts b/src/Option.ts index 7f0934f57..6c4e3a081 100644 --- a/src/Option.ts +++ b/src/Option.ts @@ -24,15 +24,9 @@ import { Monoid } from './Monoid' import { Ord } from './Ord' import { Semigroup } from './Semigroup' import { Show } from './Show' -import { Traversable1 } from './Traversable' +import { Traversable1, PipeableTraverse1 } from './Traversable' import { Witherable1 } from './Witherable' -declare module './HKT' { - interface URItoKind { - readonly Option: Option - } -} - /** * @category model * @since 2.0.0 @@ -45,6 +39,12 @@ export const URI = 'Option' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: Option + } +} + /** * @category model * @since 2.0.0 @@ -537,7 +537,7 @@ export function getApplySemigroup(S: Semigroup): Semigroup> { */ export function getApplyMonoid(M: Monoid): Monoid> { return { - ...getApplySemigroup(M), + concat: getApplySemigroup(M).concat, empty: some(M.empty) } } @@ -655,7 +655,23 @@ const reduceRight_: (fa: Option, b: B, f: (a: A, b: B) => B) => B = (fa const traverse_ = (F: Applicative) => (ta: Option, f: (a: A) => HKT): HKT> => { return isNone(ta) ? F.of(none) : F.map(f(ta.value), some) } -const sequence_ = (F: Applicative) => (ta: Option>): HKT> => { + +/** + * @since 2.6.3 + */ +export const traverse: PipeableTraverse1 = ( + F: Applicative +): ((f: (a: A) => HKT) => (ta: Option) => HKT>) => { + const traverseF = traverse_(F) + return (f) => (ta) => traverseF(ta, f) +} + +/** + * @since 2.6.3 + */ +export const sequence: Traversable1['sequence'] = (F: Applicative) => ( + ta: Option> +): HKT> => { return isNone(ta) ? F.of(none) : F.map(ta.value, some) } @@ -885,7 +901,7 @@ export const option: Monad1 & foldMap: foldMap_, reduceRight: reduceRight_, traverse: traverse_, - sequence: sequence_, + sequence, zero: () => none, alt: alt_, extend: extend_, diff --git a/src/OptionT.ts b/src/OptionT.ts index 2f08b1b0f..8033bf2c9 100644 --- a/src/OptionT.ts +++ b/src/OptionT.ts @@ -98,7 +98,9 @@ export function getOptionM(M: Monad): OptionM { const fnone = M.of(none) return { - ...A, + map: A.map, + ap: A.ap, + of: A.of, chain: (ma, f) => M.chain( ma, diff --git a/src/Ord.ts b/src/Ord.ts index 68a4609b7..86e3bb980 100644 --- a/src/Ord.ts +++ b/src/Ord.ts @@ -15,12 +15,6 @@ import { Monoid } from './Monoid' import { monoidOrdering, Ordering } from './Ordering' import { Semigroup } from './Semigroup' -declare module './HKT' { - interface URItoKind { - readonly Ord: Ord - } -} - /** * @category model * @since 2.0.0 @@ -33,6 +27,12 @@ export const URI = 'Ord' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: Ord + } +} + /** * @category type classes * @since 2.0.0 diff --git a/src/Random.ts b/src/Random.ts index 7ea6b2183..aaec62493 100644 --- a/src/Random.ts +++ b/src/Random.ts @@ -1,7 +1,8 @@ /** * @since 2.0.0 */ -import { IO, io } from './IO' +import { IO, map } from './IO' +import { pipe } from './function' /** * Returns a random number between 0 (inclusive) and 1 (exclusive). This is a direct wrapper around JavaScript's @@ -19,7 +20,10 @@ export const random: IO = () => Math.random() * @since 2.0.0 */ export function randomInt(low: number, high: number): IO { - return io.map(random, (n) => Math.floor((high - low + 1) * n + low)) + return pipe( + random, + map((n) => Math.floor((high - low + 1) * n + low)) + ) } /** @@ -29,7 +33,10 @@ export function randomInt(low: number, high: number): IO { * @since 2.0.0 */ export function randomRange(min: number, max: number): IO { - return io.map(random, (n) => (max - min) * n + min) + return pipe( + random, + map((n) => (max - min) * n + min) + ) } /** @@ -37,4 +44,9 @@ export function randomRange(min: number, max: number): IO { * * @since 2.0.0 */ -export const randomBool: IO = io.map(random, (n) => n < 0.5) +export const randomBool: IO = + /*#__PURE__*/ + pipe( + random, + map((n) => n < 0.5) + ) diff --git a/src/Reader.ts b/src/Reader.ts index 7944fb8c5..5bd9a2421 100644 --- a/src/Reader.ts +++ b/src/Reader.ts @@ -4,22 +4,17 @@ import { Category2 } from './Category' import { Choice2 } from './Choice' import * as E from './Either' -import { identity } from './function' -import { monadIdentity } from './Identity' +import * as F from './function' import { Monad2 } from './Monad' import { Monoid } from './Monoid' import { Profunctor2 } from './Profunctor' -import { getReaderM } from './ReaderT' import { Semigroup } from './Semigroup' import { Strong2 } from './Strong' +import { Apply2 } from './Apply' -const T = /*#__PURE__*/ getReaderM(monadIdentity) - -declare module './HKT' { - interface URItoKind2 { - readonly Reader: Reader - } -} +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- /** * @category model @@ -33,6 +28,12 @@ export const URI = 'Reader' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: Reader + } +} + /** * @category model * @since 2.0.0 @@ -41,81 +42,71 @@ export interface Reader { (r: R): A } +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- + /** * Reads the current context * + * @category constructors * @since 2.0.0 */ -export const ask: () => Reader = T.ask +export const ask: () => Reader = () => F.identity /** * Projects a value from the global context in a Reader * + * @category constructors * @since 2.0.0 */ -export const asks: (f: (r: R) => A) => Reader = T.asks +export const asks: (f: (r: R) => A) => Reader = (f) => (r) => f(r) + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- /** * Changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s * `contramap`). * + * @category combinators * @since 2.0.0 */ -export function local(f: (d: Q) => R): (ma: Reader) => Reader { - return (ma) => T.local(ma, f) -} - -/** - * @category instances - * @since 2.0.0 - */ -export function getSemigroup(S: Semigroup): Semigroup> { - return { - concat: (x, y) => (e) => S.concat(x(e), y(e)) - } -} - -/** - * @category instances - * @since 2.0.0 - */ -export function getMonoid(M: Monoid): Monoid> { - return { - concat: getSemigroup(M).concat, - empty: () => M.empty - } -} +export const local: (f: (d: Q) => R) => (ma: Reader) => Reader = (f) => (ma) => (q) => ma(f(q)) /** * @category Applicative * @since 2.0.0 */ -export const of: (a: A) => Reader = T.of +export const of: (a: A) => Reader = (a) => () => a // ------------------------------------------------------------------------------------- // pipeables // ------------------------------------------------------------------------------------- -const compose_: (ab: Reader, la: Reader) => Reader = (ab, la) => (l) => ab(la(l)) - -const promap_: (fbc: Reader, f: (d: D) => E, g: (a: A) => B) => Reader = (mbc, f, g) => (a) => - g(mbc(f(a))) +/** + * @category Functor + * @since 2.0.0 + */ +export const map: (f: (a: A) => B) => (fa: Reader) => Reader = (f) => (fa) => (r) => f(fa(r)) /** * @category Apply * @since 2.0.0 */ -export const ap: (fa: Reader) => (fab: Reader B>) => Reader = (fa) => (fab) => - T.ap(fab, fa) +export const ap: (fa: Reader) => (fab: Reader B>) => Reader = (fa) => (fab) => (r) => + fab(r)(fa(r)) /** * @category Apply * @since 2.0.0 */ export const apFirst = (fb: Reader) => (fa: Reader): Reader => - T.ap( - T.map(fa, (a) => (_: B) => a), - fb + F.pipe( + fa, + map((a) => (_: B) => a), + ap(fb) ) /** @@ -123,24 +114,30 @@ export const apFirst = (fb: Reader) => (fa: Reader): Reader * @since 2.0.0 */ export const apSecond = (fb: Reader) => (fa: Reader): Reader => - T.ap( - T.map(fa, () => (b: B) => b), - fb + F.pipe( + fa, + map(() => (b: B) => b), + ap(fb) ) /** * @category Monad * @since 2.0.0 */ -export const chain: (f: (a: A) => Reader) => (ma: Reader) => Reader = (f) => (ma) => - T.chain(ma, f) +export const chain: (f: (a: A) => Reader) => (ma: Reader) => Reader = (f) => (fa) => (r) => + f(fa(r))(r) /** * @category Monad * @since 2.0.0 */ -export const chainFirst: (f: (a: A) => Reader) => (ma: Reader) => Reader = (f) => (ma) => - T.chain(ma, (a) => T.map(f(a), () => a)) +export const chainFirst: (f: (a: A) => Reader) => (ma: Reader) => Reader = (f) => + chain((a) => + F.pipe( + f(a), + map(() => a) + ) + ) /** * @category Monad @@ -152,13 +149,9 @@ export const chainW: (f: (a: A) => Reader) => (ma: Reader(mma: Reader>) => Reader = (mma) => T.chain(mma, identity) - -/** - * @category Functor - * @since 2.0.0 - */ -export const map: (f: (a: A) => B) => (fa: Reader) => Reader = (f) => (fa) => T.map(fa, f) +export const flatten: (mma: Reader>) => Reader = + /*#__PURE__*/ + chain(F.identity) /** * @category Semigroupoid @@ -179,15 +172,52 @@ export const promap: (f: (d: D) => E, g: (a: A) => B) => (fbc: Reade // instances // ------------------------------------------------------------------------------------- +const map_: Monad2['map'] = (fa, f) => F.pipe(fa, map(f)) +const ap_: Monad2['ap'] = (fab, fa) => F.pipe(fab, ap(fa)) +const chain_: Monad2['chain'] = (ma, f) => F.pipe(ma, chain(f)) +const compose_: (ab: Reader, la: Reader) => Reader = (ab, la) => (l) => ab(la(l)) +const promap_: (fbc: Reader, f: (d: D) => E, g: (a: A) => B) => Reader = (mbc, f, g) => (a) => + g(mbc(f(a))) + +/** + * @internal + */ +export const applyReader: Apply2 = { + URI, + map: map_, + ap: ap_ +} + /** * @internal */ export const monadReader: Monad2 = { URI, - map: T.map, + map: map_, of, - ap: T.ap, - chain: T.chain + ap: ap_, + chain: chain_ +} + +/** + * @category instances + * @since 2.0.0 + */ +export function getSemigroup(S: Semigroup): Semigroup> { + return { + concat: (x, y) => (e) => S.concat(x(e), y(e)) + } +} + +/** + * @category instances + * @since 2.0.0 + */ +export function getMonoid(M: Monoid): Monoid> { + return { + concat: getSemigroup(M).concat, + empty: () => M.empty + } } /** @@ -196,13 +226,13 @@ export const monadReader: Monad2 = { */ export const reader: Monad2 & Profunctor2 & Category2 & Strong2 & Choice2 = { URI, - map: T.map, + map: map_, of, - ap: T.ap, - chain: T.chain, + ap: ap_, + chain: chain_, promap: promap_, compose: compose_, - id: () => identity, + id: () => F.identity, first: (pab) => ([a, c]) => [pab(a), c], second: (pbc) => ([a, b]) => [a, pbc(b)], left: (pab: Reader): Reader, E.Either> => diff --git a/src/ReaderEither.ts b/src/ReaderEither.ts index 27d84a999..c4185a22e 100644 --- a/src/ReaderEither.ts +++ b/src/ReaderEither.ts @@ -2,27 +2,24 @@ * @since 2.0.0 */ import { Alt3, Alt3C } from './Alt' +import { apComposition } from './Apply' import { Bifunctor3 } from './Bifunctor' import * as E from './Either' -import { getEitherM } from './EitherT' -import { identity, Predicate, Refinement } from './function' +import { flow, identity, pipe, Predicate, Refinement } from './function' import { Monad3, Monad3C } from './Monad' import { MonadThrow3, MonadThrow3C } from './MonadThrow' import { Monoid } from './Monoid' import { Option } from './Option' -import { getSemigroup as getReaderSemigroup, Reader, monadReader } from './Reader' +import * as R from './Reader' import { Semigroup } from './Semigroup' import { getValidationM } from './ValidationT' -import Either = E.Either - -const T = /*#__PURE__*/ getEitherM(monadReader) +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- -declare module './HKT' { - interface URItoKind3 { - readonly ReaderEither: ReaderEither - } -} +import Either = E.Either +import Reader = R.Reader /** * @category model @@ -36,127 +33,136 @@ export const URI = 'ReaderEither' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind3 { + readonly [URI]: ReaderEither + } +} + /** * @category model * @since 2.0.0 */ export interface ReaderEither extends Reader> {} +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- + /** * @category constructors * @since 2.0.0 */ -export const left: (e: E) => ReaderEither = T.left +export const left: (e: E) => ReaderEither = flow(E.left, R.of) /** * @category constructors * @since 2.0.0 */ -export const right: (a: A) => ReaderEither = T.of +export const right: (a: A) => ReaderEither = flow(E.right, R.of) /** * @category constructors * @since 2.0.0 */ -export const rightReader: (ma: Reader) => ReaderEither = T.rightM +export const rightReader: (ma: Reader) => ReaderEither = + /*#__PURE__*/ + R.map(E.right) /** * @category constructors * @since 2.0.0 */ -export const leftReader: (me: Reader) => ReaderEither = T.leftM +export const leftReader: (me: Reader) => ReaderEither = + /*#__PURE__*/ + R.map(E.left) /** - * @category destructors + * @category constructors * @since 2.0.0 */ -export function fold( - onLeft: (e: E) => Reader, - onRight: (a: A) => Reader -): (ma: ReaderEither) => Reader { - return (ma) => T.fold(ma, onLeft, onRight) -} +export const ask: () => ReaderEither = () => E.right /** - * @category destructors + * @category constructors * @since 2.0.0 */ -export function getOrElse(onLeft: (e: E) => Reader): (ma: ReaderEither) => Reader { - return (ma) => T.getOrElse(ma, onLeft) -} +export const asks: (f: (r: R) => A) => ReaderEither = (f) => flow(f, E.right) /** - * @category destructors - * @since 2.6.0 + * @category constructors + * @since 2.0.0 */ -export const getOrElseW: ( - onLeft: (e: E) => Reader -) => (ma: ReaderEither) => Reader = getOrElse as any +export const fromEither: (ma: E.Either) => ReaderEither = (ma) => + E.isLeft(ma) ? left(ma.left) : right(ma.right) /** - * @category combinators + * @category constructors * @since 2.0.0 */ -export function orElse( - onLeft: (e: E) => ReaderEither -): (ma: ReaderEither) => ReaderEither { - return (ma) => T.orElse(ma, onLeft) -} +export const fromOption: (onNone: () => E) => (ma: Option) => ReaderEither = (onNone) => (ma) => + ma._tag === 'None' ? left(onNone()) : right(ma.value) /** - * @category combinators + * @category constructors * @since 2.0.0 */ -export const swap: (ma: ReaderEither) => ReaderEither = T.swap +export const fromPredicate: { + (refinement: Refinement, onFalse: (a: A) => E): (a: A) => ReaderEither + (predicate: Predicate, onFalse: (a: A) => E): (a: A) => ReaderEither +} = (predicate: Predicate, onFalse: (a: A) => E) => (a: A) => (predicate(a) ? right(a) : left(onFalse(a))) + +// ------------------------------------------------------------------------------------- +// destructors +// ------------------------------------------------------------------------------------- /** - * Semigroup returning the left-most non-`Left` value. If both operands are `Right`s then the inner values are - * appended using the provided `Semigroup` - * - * @category instances + * @category destructors * @since 2.0.0 */ -export function getSemigroup(S: Semigroup): Semigroup> { - return getReaderSemigroup(E.getSemigroup(S)) -} +export const fold: ( + onLeft: (e: E) => Reader, + onRight: (a: A) => Reader +) => (ma: ReaderEither) => Reader = flow(E.fold, R.chain) /** - * Semigroup returning the left-most `Left` value. If both operands are `Right`s then the inner values - * are appended using the provided `Semigroup` - * - * @category instances + * @category destructors * @since 2.0.0 */ -export function getApplySemigroup(S: Semigroup): Semigroup> { - return getReaderSemigroup(E.getApplySemigroup(S)) -} +export const getOrElse: (onLeft: (e: E) => Reader) => (ma: ReaderEither) => Reader = ( + onLeft +) => R.chain(E.fold(onLeft, R.of)) /** - * @category instances - * @since 2.0.0 + * @category destructors + * @since 2.6.0 */ -export function getApplyMonoid(M: Monoid): Monoid> { - return { - concat: getApplySemigroup(M).concat, - empty: right(M.empty) - } -} +export const getOrElseW: ( + onLeft: (e: E) => Reader +) => (ma: ReaderEither) => Reader = getOrElse as any + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- /** + * @category combinators * @since 2.0.0 */ -export function ask(): ReaderEither { - return E.right -} +export const orElse: ( + onLeft: (e: E) => ReaderEither +) => (ma: ReaderEither) => ReaderEither = (f) => R.chain(E.fold(f, right)) /** + * @category combinators * @since 2.0.0 */ -export function asks(f: (r: R) => A): ReaderEither { - return (r) => E.right(f(r)) -} +export const swap: (ma: ReaderEither) => ReaderEither = + /*#__PURE__*/ + R.map(E.swap) /** + * @category combinators * @since 2.0.0 */ export function local(f: (f: Q) => R): (ma: ReaderEither) => ReaderEither { @@ -164,21 +170,7 @@ export function local(f: (f: Q) => R): (ma: ReaderEither) = } /** - * @category instances - * @since 2.3.0 - */ -export function getReaderValidation( - S: Semigroup -): Monad3C & Bifunctor3 & Alt3C & MonadThrow3C { - const T = getValidationM(S, monadReader) - return { - _E: undefined as any, - ...readerEither, - ...T - } -} - -/** + * @category combinators * @since 2.4.0 */ export function fromEitherK, B>( @@ -188,7 +180,7 @@ export function fromEitherK, B>( } /** - * @category Monad + * @category combinators * @since 2.4.0 */ export function chainEitherK( @@ -197,17 +189,49 @@ export function chainEitherK( return chain(fromEitherK(f)) } +/** + * @category combinators + * @since 2.0.0 + */ +export const filterOrElse: { + (refinement: Refinement, onFalse: (a: A) => E): ( + ma: ReaderEither + ) => ReaderEither + (predicate: Predicate, onFalse: (a: A) => E): (ma: ReaderEither) => ReaderEither +} = (predicate: Predicate, onFalse: (a: A) => E) => (ma: ReaderEither) => + pipe( + ma, + chain((a) => (predicate(a) ? right(a) : left(onFalse(a)))) + ) + // ------------------------------------------------------------------------------------- // pipeables // ------------------------------------------------------------------------------------- /** - * @category Alt + * @category Functor * @since 2.0.0 */ -export const alt: ( - that: () => ReaderEither -) => (fa: ReaderEither) => ReaderEither = (that) => (fa) => T.alt(fa, that) +export const map: (f: (a: A) => B) => (fa: ReaderEither) => ReaderEither = (f) => + R.map(E.map(f)) + +/** + * @category Bifunctor + * @since 2.0.0 + */ +export const mapLeft: (f: (e: E) => G) => (fa: ReaderEither) => ReaderEither = (f) => + R.map(E.mapLeft(f)) + +/** + * @category Bifunctor + * @since 2.0.0 + */ +export const bimap: ( + f: (e: E) => G, + g: (a: A) => B +) => (fa: ReaderEither) => ReaderEither = + /*#__PURE__*/ + flow(E.bimap, R.map) /** * @category Apply @@ -215,7 +239,9 @@ export const alt: ( */ export const ap: ( fa: ReaderEither -) => (fab: ReaderEither B>) => ReaderEither = (fa) => (fab) => T.ap(fab, fa) +) => (fab: ReaderEither B>) => ReaderEither = + /*#__PURE__*/ + apComposition(R.applyReader, E.applyEither) /** * @category Apply @@ -224,9 +250,10 @@ export const ap: ( export const apFirst: ( fb: ReaderEither ) => (fa: ReaderEither) => ReaderEither = (fb) => (fa) => - T.ap( - T.map(fa, (a) => () => a), - fb + pipe( + fa, + map((a) => () => a), + ap(fb) ) /** @@ -234,27 +261,19 @@ export const apFirst: ( * @since 2.0.0 */ export const apSecond = (fb: ReaderEither) => (fa: ReaderEither): ReaderEither => - T.ap( - T.map(fa, () => (b: B) => b), - fb + pipe( + fa, + map(() => (b: B) => b), + ap(fb) ) -/** - * @category Bifunctor - * @since 2.0.0 - */ -export const bimap: ( - f: (e: E) => G, - g: (a: A) => B -) => (fa: ReaderEither) => ReaderEither = (f, g) => (fa) => T.bimap(fa, f, g) - /** * @category Monad * @since 2.0.0 */ export const chain: ( f: (a: A) => ReaderEither -) => (ma: ReaderEither) => ReaderEither = (f) => (ma) => T.chain(ma, f) +) => (ma: ReaderEither) => ReaderEither = (f) => R.chain(E.fold(left, f)) /** * @category Monad @@ -278,68 +297,103 @@ export const chainEitherKW: ( */ export const chainFirst: ( f: (a: A) => ReaderEither -) => (ma: ReaderEither) => ReaderEither = (f) => (ma) => T.chain(ma, (a) => T.map(f(a), () => a)) +) => (ma: ReaderEither) => ReaderEither = (f) => + chain((a) => + pipe( + f(a), + map(() => a) + ) + ) /** * @category Monad * @since 2.0.0 */ -export const flatten: (mma: ReaderEither>) => ReaderEither = (mma) => - T.chain(mma, identity) +export const flatten: (mma: ReaderEither>) => ReaderEither = + /*#__PURE__*/ + chain(identity) /** - * @category Functor + * @category Alt * @since 2.0.0 */ -export const map: (f: (a: A) => B) => (fa: ReaderEither) => ReaderEither = (f) => (fa) => - T.map(fa, f) +export const alt: ( + that: () => ReaderEither +) => (fa: ReaderEither) => ReaderEither = (that) => R.chain(E.fold(that, right)) -/** - * @category Bifunctor - * @since 2.0.0 - */ -export const mapLeft: (f: (e: E) => G) => (fa: ReaderEither) => ReaderEither = (f) => ( - fa -) => T.mapLeft(fa, f) +// ------------------------------------------------------------------------------------- +// instances +// ------------------------------------------------------------------------------------- + +/* istanbul ignore next */ +const map_: Monad3['map'] = (fa, f) => pipe(fa, map(f)) +/* istanbul ignore next */ +const bimap_: Bifunctor3['bimap'] = (fa, f, g) => pipe(fa, bimap(f, g)) +/* istanbul ignore next */ +const mapLeft_: Bifunctor3['mapLeft'] = (fa, f) => pipe(fa, mapLeft(f)) +/* istanbul ignore next */ +const ap_: Monad3['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const of = right +/* istanbul ignore next */ +const chain_: Monad3['chain'] = (ma, f) => pipe(ma, chain(f)) +/* istanbul ignore next */ +const alt_: Alt3['alt'] = (fa, that) => pipe(fa, alt(that)) +const throwError_ = left /** - * @category constructors + * Semigroup returning the left-most non-`Left` value. If both operands are `Right`s then the inner values are + * appended using the provided `Semigroup` + * + * @category instances * @since 2.0.0 */ -export const fromEither: (ma: E.Either) => ReaderEither = (ma) => - E.isLeft(ma) ? left(ma.left) : right(ma.right) +export function getSemigroup(S: Semigroup): Semigroup> { + return R.getSemigroup(E.getSemigroup(S)) +} /** - * @category constructors + * Semigroup returning the left-most `Left` value. If both operands are `Right`s then the inner values + * are appended using the provided `Semigroup` + * + * @category instances * @since 2.0.0 */ -export const fromOption: (onNone: () => E) => (ma: Option) => ReaderEither = (onNone) => (ma) => - ma._tag === 'None' ? left(onNone()) : right(ma.value) +export function getApplySemigroup(S: Semigroup): Semigroup> { + return R.getSemigroup(E.getApplySemigroup(S)) +} /** - * @category constructors + * @category instances * @since 2.0.0 */ -export const fromPredicate: { - (refinement: Refinement, onFalse: (a: A) => E): (a: A) => ReaderEither - (predicate: Predicate, onFalse: (a: A) => E): (a: A) => ReaderEither -} = (predicate: Predicate, onFalse: (a: A) => E) => (a: A) => (predicate(a) ? right(a) : left(onFalse(a))) +export function getApplyMonoid(M: Monoid): Monoid> { + return { + concat: getApplySemigroup(M).concat, + empty: right(M.empty) + } +} /** - * @category combinators - * @since 2.0.0 + * @category instances + * @since 2.3.0 */ -export const filterOrElse: { - (refinement: Refinement, onFalse: (a: A) => E): ( - ma: ReaderEither - ) => ReaderEither - (predicate: Predicate, onFalse: (a: A) => E): (ma: ReaderEither) => ReaderEither -} = (predicate: Predicate, onFalse: (a: A) => E) => (ma: ReaderEither) => - T.chain(ma, (a) => (predicate(a) ? right(a) : left(onFalse(a)))) - -// ------------------------------------------------------------------------------------- -// instances -// ------------------------------------------------------------------------------------- +export function getReaderValidation( + S: Semigroup +): Monad3C & Bifunctor3 & Alt3C & MonadThrow3C { + const V = getValidationM(S, R.monadReader) + return { + URI, + _E: undefined as any, + map: map_, + ap: V.ap, + of, + chain: chain_, + bimap: bimap_, + mapLeft: mapLeft_, + alt: V.alt, + throwError: throwError_ + } +} /** * @category instances @@ -347,12 +401,12 @@ export const filterOrElse: { */ export const readerEither: Monad3 & Bifunctor3 & Alt3 & MonadThrow3 = { URI, - bimap: T.bimap, - mapLeft: T.mapLeft, - map: T.map, - of: right, - ap: T.ap, - chain: T.chain, - alt: T.alt, + bimap: bimap_, + mapLeft: mapLeft_, + map: map_, + of, + ap: ap_, + chain: chain_, + alt: alt_, throwError: left } diff --git a/src/ReaderTask.ts b/src/ReaderTask.ts index 5971602ae..b4a55f8ea 100644 --- a/src/ReaderTask.ts +++ b/src/ReaderTask.ts @@ -1,25 +1,21 @@ /** * @since 2.3.0 */ -import { identity } from './function' +import { identity, flow, pipe } from './function' import { IO } from './IO' import { Monad2 } from './Monad' import { MonadTask2 } from './MonadTask' import { Monoid } from './Monoid' -import { getSemigroup as getReaderSemigroup, Reader } from './Reader' -import { getReaderM } from './ReaderT' +import * as R from './Reader' import { Semigroup } from './Semigroup' -import * as TA from './Task' +import * as T from './Task' -import Task = TA.Task - -const T = /*#__PURE__*/ getReaderM(TA.monadTask) +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- -declare module './HKT' { - interface URItoKind2 { - readonly ReaderTask: ReaderTask - } -} +import Task = T.Task +import Reader = R.Reader /** * @category model @@ -33,6 +29,12 @@ export const URI = 'ReaderTask' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: ReaderTask + } +} + /** * @category model * @since 2.3.0 @@ -41,76 +43,56 @@ export interface ReaderTask { (r: R): Task } -/** - * @since 2.4.0 - */ -export function run(ma: ReaderTask, r: R): Promise { - return ma(r)() -} +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- /** * @category constructors * @since 2.3.0 */ -export const fromTask: (ma: Task) => ReaderTask = T.fromM +export const fromTask: (ma: Task) => ReaderTask = + /*#__PURE__*/ + R.of /** * @category constructors * @since 2.3.0 */ -export const fromReader: (ma: Reader) => ReaderTask = T.fromReader +export const fromReader: (ma: Reader) => ReaderTask = (ma) => flow(ma, T.of) /** * @category constructors * @since 2.3.0 */ -export function fromIO(ma: IO): ReaderTask { - return fromTask(TA.fromIO(ma)) -} - -/** - * @category Applicative - * @since 2.3.0 - */ -export const of: (a: A) => ReaderTask = T.of +export const fromIO: (ma: IO) => ReaderTask = + /*#__PURE__*/ + flow(T.fromIO, fromTask) /** - * @category instances + * @category constructors * @since 2.3.0 */ -export function getSemigroup(S: Semigroup): Semigroup> { - return getReaderSemigroup(TA.getSemigroup(S)) -} - -/** - * @category instances - * @since 2.3.0 - */ -export function getMonoid(M: Monoid): Monoid> { - return { - concat: getSemigroup(M).concat, - empty: of(M.empty) - } -} +export const ask: () => ReaderTask = () => T.of /** + * @category constructors * @since 2.3.0 */ -export const ask: () => ReaderTask = T.ask +export const asks: (f: (r: R) => A) => ReaderTask = (f) => (r) => pipe(T.of(r), T.map(f)) -/** - * @since 2.3.0 - */ -export const asks: (f: (r: R) => A) => ReaderTask = T.asks +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- /** + * @category combinators * @since 2.3.0 */ -export function local(f: (f: Q) => R): (ma: ReaderTask) => ReaderTask { - return (ma) => T.local(ma, f) -} +export const local: (f: (f: Q) => R) => (ma: ReaderTask) => ReaderTask = R.local /** + * @category combinators * @since 2.4.0 */ export function fromIOK, B>(f: (...a: A) => IO): (...a: A) => ReaderTask { @@ -118,14 +100,14 @@ export function fromIOK, B>(f: (...a: A) => IO< } /** - * @category Monad + * @category combinators * @since 2.4.0 */ -export function chainIOK(f: (a: A) => IO): (ma: ReaderTask) => ReaderTask { - return chain(fromIOK(f)) -} +export const chainIOK: (f: (a: A) => IO) => (ma: ReaderTask) => ReaderTask = (f) => + chain((a) => fromIO(f(a))) /** + * @category combinators * @since 2.4.0 */ export function fromTaskK, B>( @@ -135,33 +117,40 @@ export function fromTaskK, B>( } /** - * @category Monad + * @category combinators * @since 2.4.0 */ -export function chainTaskK(f: (a: A) => Task): (ma: ReaderTask) => ReaderTask { - return chain(fromTaskK(f)) -} +export const chainTaskK: (f: (a: A) => Task) => (ma: ReaderTask) => ReaderTask = (f) => + chain((a) => fromTask(f(a))) // ------------------------------------------------------------------------------------- // pipeables // ------------------------------------------------------------------------------------- +/** + * @category Functor + * @since 2.3.0 + */ +export const map: (f: (a: A) => B) => (fa: ReaderTask) => ReaderTask = (f) => (fa) => + flow(fa, T.map(f)) + /** * @category Apply * @since 2.3.0 */ export const ap: (fa: ReaderTask) => (fab: ReaderTask B>) => ReaderTask = (fa) => ( fab -) => T.ap(fab, fa) +) => (r) => pipe(fab(r), T.ap(fa(r))) /** * @category Apply * @since 2.3.0 */ export const apFirst = (fb: ReaderTask) => (fa: ReaderTask): ReaderTask => - T.ap( - T.map(fa, (a) => (_: B) => a), - fb + pipe( + fa, + map((a) => (_: B) => a), + ap(fb) ) /** @@ -169,52 +158,86 @@ export const apFirst = (fb: ReaderTask) => (fa: ReaderTask) * @since 2.3.0 */ export const apSecond = (fb: ReaderTask) => (fa: ReaderTask): ReaderTask => - T.ap( - T.map(fa, () => (b) => b), - fb + pipe( + fa, + map(() => (b: B) => b), + ap(fb) ) /** - * @category Monad + * @category Applicative * @since 2.3.0 */ -export const chain: (f: (a: A) => ReaderTask) => (ma: ReaderTask) => ReaderTask = (f) => ( - ma -) => T.chain(ma, f) +export const of: (a: A) => ReaderTask = (a) => () => T.of(a) /** * @category Monad * @since 2.3.0 */ -export const chainFirst: (f: (a: A) => ReaderTask) => (ma: ReaderTask) => ReaderTask = ( - f -) => (ma) => T.chain(ma, (a) => T.map(f(a), () => a)) +export const chain: (f: (a: A) => ReaderTask) => (ma: ReaderTask) => ReaderTask = (f) => ( + fa +) => (r) => + pipe( + fa(r), + T.chain((a) => f(a)(r)) + ) /** * @category Monad * @since 2.3.0 */ -export const flatten: (mma: ReaderTask>) => ReaderTask = (mma) => T.chain(mma, identity) +export const chainFirst: (f: (a: A) => ReaderTask) => (ma: ReaderTask) => ReaderTask = (f) => + chain((a) => + pipe( + f(a), + map(() => a) + ) + ) /** - * @category Functor + * @category Monad * @since 2.3.0 */ -export const map: (f: (a: A) => B) => (fa: ReaderTask) => ReaderTask = (f) => (fa) => T.map(fa, f) +export const flatten: (mma: ReaderTask>) => ReaderTask = + /*#__PURE__*/ + chain(identity) // ------------------------------------------------------------------------------------- // instances // ------------------------------------------------------------------------------------- +const map_: Monad2['map'] = (fa, f) => pipe(fa, map(f)) +const ap_: Monad2['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const chain_: Monad2['chain'] = (ma, f) => pipe(ma, chain(f)) + /** * @internal */ export const monadReaderTask: Monad2 = { URI, - map: T.map, + map: map_, of, - ap: T.ap, - chain: T.chain + ap: ap_, + chain: chain_ +} + +/** + * @category instances + * @since 2.3.0 + */ +export function getSemigroup(S: Semigroup): Semigroup> { + return R.getSemigroup(T.getSemigroup(S)) +} + +/** + * @category instances + * @since 2.3.0 + */ +export function getMonoid(M: Monoid): Monoid> { + return { + concat: getSemigroup(M).concat, + empty: of(M.empty) + } } /** @@ -223,10 +246,10 @@ export const monadReaderTask: Monad2 = { */ export const readerTask: Monad2 & MonadTask2 = { URI, - map: T.map, + map: map_, of, - ap: T.ap, - chain: T.chain, + ap: ap_, + chain: chain_, fromIO, fromTask } @@ -237,11 +260,27 @@ export const readerTask: Monad2 & MonadTask2 = { * @category instances * @since 2.3.0 */ -export const readerTaskSeq: typeof readerTask = - /*#__PURE__*/ - ((): typeof readerTask => { - return { - ...readerTask, - ap: (mab, ma) => T.chain(mab, (f) => T.map(ma, f)) - } - })() +export const readerTaskSeq: typeof readerTask = { + URI, + map: map_, + of, + ap: (fab, fa) => + pipe( + fab, + chain((f) => pipe(fa, map(f))) + ), + chain: chain_, + fromIO, + fromTask +} + +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/** + * @since 2.4.0 + */ +export function run(ma: ReaderTask, r: R): Promise { + return ma(r)() +} diff --git a/src/ReaderTaskEither.ts b/src/ReaderTaskEither.ts index a5f5001c8..4ad549dfb 100644 --- a/src/ReaderTaskEither.ts +++ b/src/ReaderTaskEither.ts @@ -4,7 +4,7 @@ import { Alt3, Alt3C } from './Alt' import { Bifunctor3 } from './Bifunctor' import { Either } from './Either' -import { identity, Predicate, Refinement } from './function' +import { identity, pipe, Predicate, Refinement, flow } from './function' import { IO } from './IO' import { IOEither } from './IOEither' import { Monad3, Monad3C } from './Monad' @@ -12,25 +12,20 @@ import { MonadTask3, MonadTask3C } from './MonadTask' import { MonadThrow3, MonadThrow3C } from './MonadThrow' import { Monoid } from './Monoid' import { Option } from './Option' -import { pipe } from './pipeable' -import { getSemigroup as getReaderSemigroup, Reader } from './Reader' +import * as R from './Reader' import { ReaderEither } from './ReaderEither' -import { getReaderM } from './ReaderT' import { monadReaderTask, ReaderTask } from './ReaderTask' import { Semigroup } from './Semigroup' import { Task } from './Task' import * as TE from './TaskEither' import { getValidationM } from './ValidationT' -import TaskEither = TE.TaskEither - -const T = /*#__PURE__*/ getReaderM(TE.monadTaskEither) +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- -declare module './HKT' { - interface URItoKind3 { - readonly ReaderTaskEither: ReaderTaskEither - } -} +import TaskEither = TE.TaskEither +import Reader = R.Reader /** * @category model @@ -44,6 +39,12 @@ export const URI = 'ReaderTaskEither' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind3 { + readonly [URI]: ReaderTaskEither + } +} + /** * @category model * @since 2.0.0 @@ -52,12 +53,9 @@ export interface ReaderTaskEither { (r: R): TaskEither } -/** - * @since 2.0.0 - */ -export function run(ma: ReaderTaskEither, r: R): Promise> { - return ma(r)() -} +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- /** * @category constructors @@ -71,7 +69,7 @@ export function left(e: E): ReaderTaskEither { * @category constructors * @since 2.0.0 */ -export const right: (a: A) => ReaderTaskEither = T.of +export const right: (a: A) => ReaderTaskEither = (a) => () => TE.right(a) /** * @category constructors @@ -93,13 +91,16 @@ export function leftTask(me: Task): ReaderTaskEither * @category constructors * @since 2.0.0 */ -export const fromTaskEither: (ma: TaskEither) => ReaderTaskEither = T.fromM +export const fromTaskEither: (ma: TaskEither) => ReaderTaskEither = + /*#__PURE__*/ + R.of /** * @category constructors * @since 2.0.0 */ -export const rightReader: (ma: Reader) => ReaderTaskEither = T.fromReader +export const rightReader: (ma: Reader) => ReaderTaskEither = (ma) => (r) => + TE.right(ma(r)) /** * @category constructors @@ -157,6 +158,47 @@ export function leftIO(me: IO): ReaderTaskEither() => ReaderTaskEither = () => TE.right + +/** + * @category constructors + * @since 2.0.0 + */ +export const asks: (f: (r: R) => A) => ReaderTaskEither = (f) => (r) => + pipe(TE.right(r), TE.map(f)) + +/** + * @category constructors + * @since 2.0.0 + */ +export const fromEither: (ma: Either) => ReaderTaskEither = (ma) => + ma._tag === 'Left' ? left(ma.left) : right(ma.right) + +/** + * @category constructors + * @since 2.0.0 + */ +export const fromOption: (onNone: () => E) => (ma: Option) => ReaderTaskEither = (onNone) => ( + ma +) => (ma._tag === 'None' ? left(onNone()) : right(ma.value)) + +/** + * @category constructors + * @since 2.0.0 + */ +export const fromPredicate: { + (refinement: Refinement, onFalse: (a: A) => E): (a: A) => ReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): (a: A) => ReaderTaskEither +} = (predicate: Predicate, onFalse: (a: A) => E) => (a: A) => (predicate(a) ? right(a) : left(onFalse(a))) + +// ------------------------------------------------------------------------------------- +// destructors +// ------------------------------------------------------------------------------------- + /** * @category destructors * @since 2.0.0 @@ -193,6 +235,10 @@ export const getOrElseW: ( onLeft: (e: E) => ReaderTask ) => (ma: ReaderTaskEither) => ReaderTask = getOrElse as any +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- + /** * @category combinators * @since 2.0.0 @@ -212,92 +258,29 @@ export function swap(ma: ReaderTaskEither): ReaderTaskEither(S: Semigroup): Semigroup> { - return getReaderSemigroup(TE.getSemigroup(S)) -} - -/** - * Semigroup returning the left-most `Left` value. If both operands are `Right`s then the inner values - * are appended using the provided `Semigroup` - * - * @category instances - * @since 2.0.0 - */ -export function getApplySemigroup(S: Semigroup): Semigroup> { - return getReaderSemigroup(TE.getApplySemigroup(S)) -} - -/** - * @category instances - * @since 2.0.0 - */ -export function getApplyMonoid(M: Monoid): Monoid> { - return { - concat: getApplySemigroup(M).concat, - empty: right(M.empty) - } -} - -/** - * @since 2.0.0 - */ -export const ask: () => ReaderTaskEither = T.ask - -/** + * @category combinators * @since 2.0.0 */ -export const asks: (f: (r: R) => A) => ReaderTaskEither = T.asks +export const local: (f: (f: Q) => R) => (ma: ReaderTaskEither) => ReaderTaskEither = + R.local /** + * @category combinators * @since 2.0.0 */ -export function local(f: (f: Q) => R): (ma: ReaderTaskEither) => ReaderTaskEither { - return (ma) => T.local(ma, f) -} - -/** - * Make sure that a resource is cleaned up in the event of an exception (*). The release action is called regardless of - * whether the body action throws (*) or returns. - * - * (*) i.e. returns a `Left` - * - * @since 2.0.4 - */ -export function bracket( - aquire: ReaderTaskEither, - use: (a: A) => ReaderTaskEither, - release: (a: A, e: Either) => ReaderTaskEither -): ReaderTaskEither { - return (r) => - TE.bracket( - aquire(r), - (a) => use(a)(r), - (a, e) => release(a, e)(r) - ) -} - -/** - * @category instances - * @since 2.3.0 - */ -export function getReaderTaskValidation( - S: Semigroup -): Monad3C & Bifunctor3 & Alt3C & MonadTask3C & MonadThrow3C { - const T = getValidationM(S, monadReaderTask) - return { - _E: undefined as any, - ...readerTaskEither, - ...T - } -} +export const filterOrElse: { + (refinement: Refinement, onFalse: (a: A) => E): ( + ma: ReaderTaskEither + ) => ReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): (ma: ReaderTaskEither) => ReaderTaskEither +} = (predicate: Predicate, onFalse: (a: A) => E) => (ma: ReaderTaskEither) => + pipe( + ma, + chain((a) => (predicate(a) ? right(a) : left(onFalse(a)))) + ) /** + * @category combinators * @since 2.4.0 */ export function fromEitherK, B>( @@ -307,7 +290,7 @@ export function fromEitherK, B>( } /** - * @category Monad + * @category combinators * @since 2.4.0 */ export function chainEitherK( @@ -317,6 +300,7 @@ export function chainEitherK( } /** + * @category combinators * @since 2.4.0 */ export function fromIOEitherK, B>( @@ -326,7 +310,7 @@ export function fromIOEitherK, B>( } /** - * @category Monad + * @category combinators * @since 2.4.0 */ export function chainIOEitherK( @@ -336,6 +320,7 @@ export function chainIOEitherK( } /** + * @category combinators * @since 2.4.0 */ export function fromTaskEitherK, B>( @@ -345,7 +330,7 @@ export function fromTaskEitherK, B>( } /** - * @category Monad + * @category combinators * @since 2.4.0 */ export function chainTaskEitherK( @@ -358,32 +343,30 @@ export function chainTaskEitherK( // pipeables // ------------------------------------------------------------------------------------- -const alt_: ( - fx: ReaderTaskEither, - fy: () => ReaderTaskEither -) => ReaderTaskEither = (fx, fy) => (r) => - pipe( - fx(r), - TE.alt(() => fy()(r)) - ) +/** + * @category Functor + * @since 2.0.0 + */ +export const map: (f: (a: A) => B) => (fa: ReaderTaskEither) => ReaderTaskEither = ( + f +) => (fa) => flow(fa, TE.map(f)) -const bimap_: ( - fea: ReaderTaskEither, +/** + * @category Bifunctor + * @since 2.0.0 + */ +export const bimap: ( f: (e: E) => G, g: (a: A) => B -) => ReaderTaskEither = (ma, f, g) => (e) => pipe(ma(e), TE.bimap(f, g)) - -const mapLeft_: (fea: ReaderTaskEither, f: (e: E) => G) => ReaderTaskEither = (ma, f) => ( - e -) => pipe(ma(e), TE.mapLeft(f)) +) => (fa: ReaderTaskEither) => ReaderTaskEither = (f, g) => (fa) => bimap_(fa, f, g) /** - * @category Alt + * @category Bifunctor * @since 2.0.0 */ -export const alt: ( - that: () => ReaderTaskEither -) => (fa: ReaderTaskEither) => ReaderTaskEither = (that) => (fa) => alt_(fa, that) +export const mapLeft: (f: (e: E) => G) => (fa: ReaderTaskEither) => ReaderTaskEither = ( + f +) => (fa) => mapLeft_(fa, f) /** * @category Apply @@ -391,49 +374,46 @@ export const alt: ( */ export const ap: ( fa: ReaderTaskEither -) => (fab: ReaderTaskEither B>) => ReaderTaskEither = (fa) => (fab) => T.ap(fab, fa) +) => (fab: ReaderTaskEither B>) => ReaderTaskEither = (fa) => (fab) => (r) => + pipe(fab(r), TE.ap(fa(r))) /** * @category Apply * @since 2.0.0 */ - export const apFirst: ( fb: ReaderTaskEither ) => (fa: ReaderTaskEither) => ReaderTaskEither = (fb) => (fa) => - T.ap( - T.map(fa, (a) => () => a), - fb + pipe( + fa, + map((a) => () => a), + ap(fb) ) /** * @category Apply * @since 2.0.0 */ -export const apSecond: ( - fb: ReaderTaskEither -) => (fa: ReaderTaskEither) => ReaderTaskEither = (fb) => (fa) => - T.ap( - T.map(fa, () => (b) => b), - fb +export const apSecond = (fb: ReaderTaskEither) => ( + fa: ReaderTaskEither +): ReaderTaskEither => + pipe( + fa, + map(() => (b: B) => b), + ap(fb) ) -/** - * @category Bifunctor - * @since 2.0.0 - */ -export const bimap: ( - f: (e: E) => G, - g: (a: A) => B -) => (fa: ReaderTaskEither) => ReaderTaskEither = (f, g) => (fa) => bimap_(fa, f, g) - /** * @category Monad * @since 2.0.0 */ export const chain: ( f: (a: A) => ReaderTaskEither -) => (ma: ReaderTaskEither) => ReaderTaskEither = (f) => (ma) => T.chain(ma, f) +) => (ma: ReaderTaskEither) => ReaderTaskEither = (f) => (fa) => (r) => + pipe( + fa(r), + TE.chain((a) => f(a)(r)) + ) /** * @category Monad @@ -441,82 +421,146 @@ export const chain: ( */ export const chainFirst: ( f: (a: A) => ReaderTaskEither -) => (ma: ReaderTaskEither) => ReaderTaskEither = (f) => (ma) => - T.chain(ma, (a) => T.map(f(a), () => a)) +) => (ma: ReaderTaskEither) => ReaderTaskEither = (f) => + chain((a) => + pipe( + f(a), + map(() => a) + ) + ) /** * @category Monad * @since 2.0.0 */ -export const flatten: (mma: ReaderTaskEither>) => ReaderTaskEither = ( - mma -) => T.chain(mma, identity) +export const flatten: (mma: ReaderTaskEither>) => ReaderTaskEither = + /*#__PURE__*/ + chain(identity) /** - * @category Functor + * @category Alt * @since 2.0.0 */ -export const map: (f: (a: A) => B) => (fa: ReaderTaskEither) => ReaderTaskEither = ( - f -) => (fa) => T.map(fa, f) +export const alt: ( + that: () => ReaderTaskEither +) => (fa: ReaderTaskEither) => ReaderTaskEither = (that) => (fa) => alt_(fa, that) /** - * @category Bifunctor - * @since 2.0.0 + * Make sure that a resource is cleaned up in the event of an exception (*). The release action is called regardless of + * whether the body action throws (*) or returns. + * + * (*) i.e. returns a `Left` + * + * @MonadThrow + * @since 2.0.4 */ -export const mapLeft: (f: (e: E) => G) => (fa: ReaderTaskEither) => ReaderTaskEither = ( - f -) => (fa) => mapLeft_(fa, f) +export function bracket( + aquire: ReaderTaskEither, + use: (a: A) => ReaderTaskEither, + release: (a: A, e: Either) => ReaderTaskEither +): ReaderTaskEither { + return (r) => + TE.bracket( + aquire(r), + (a) => use(a)(r), + (a, e) => release(a, e)(r) + ) +} + +// ------------------------------------------------------------------------------------- +// instances +// ------------------------------------------------------------------------------------- + +const map_: Monad3['map'] = (fa, f) => pipe(fa, map(f)) +const ap_: Monad3['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const of = right +const chain_: Monad3['chain'] = (ma, f) => pipe(ma, chain(f)) +const alt_: ( + fx: ReaderTaskEither, + fy: () => ReaderTaskEither +) => ReaderTaskEither = (fx, fy) => (r) => + pipe( + fx(r), + TE.alt(() => fy()(r)) + ) +const bimap_: ( + fea: ReaderTaskEither, + f: (e: E) => G, + g: (a: A) => B +) => ReaderTaskEither = (ma, f, g) => (e) => pipe(ma(e), TE.bimap(f, g)) +const mapLeft_: (fea: ReaderTaskEither, f: (e: E) => G) => ReaderTaskEither = (ma, f) => ( + e +) => pipe(ma(e), TE.mapLeft(f)) +const fromIO_ = rightIO +const fromTask_ = rightTask +const throwError_ = left /** - * @category constructors - * @since 2.0.0 + * @internal */ -export const fromEither: (ma: Either) => ReaderTaskEither = (ma) => - ma._tag === 'Left' ? left(ma.left) : right(ma.right) +export const monadReaderTaskEither: Monad3 = { + URI, + map: map_, + of, + ap: ap_, + chain: chain_ +} /** - * @category constructors + * Semigroup returning the left-most non-`Left` value. If both operands are `Right`s then the inner values are + * appended using the provided `Semigroup` + * + * @category instances * @since 2.0.0 */ -export const fromOption: (onNone: () => E) => (ma: Option) => ReaderTaskEither = (onNone) => ( - ma -) => (ma._tag === 'None' ? left(onNone()) : right(ma.value)) +export function getSemigroup(S: Semigroup): Semigroup> { + return R.getSemigroup(TE.getSemigroup(S)) +} /** - * @category constructors + * Semigroup returning the left-most `Left` value. If both operands are `Right`s then the inner values + * are appended using the provided `Semigroup` + * + * @category instances * @since 2.0.0 */ -export const fromPredicate: { - (refinement: Refinement, onFalse: (a: A) => E): (a: A) => ReaderTaskEither - (predicate: Predicate, onFalse: (a: A) => E): (a: A) => ReaderTaskEither -} = (predicate: Predicate, onFalse: (a: A) => E) => (a: A) => (predicate(a) ? right(a) : left(onFalse(a))) +export function getApplySemigroup(S: Semigroup): Semigroup> { + return R.getSemigroup(TE.getApplySemigroup(S)) +} /** - * @category combinators + * @category instances * @since 2.0.0 */ -export const filterOrElse: { - (refinement: Refinement, onFalse: (a: A) => E): ( - ma: ReaderTaskEither - ) => ReaderTaskEither - (predicate: Predicate, onFalse: (a: A) => E): (ma: ReaderTaskEither) => ReaderTaskEither -} = (predicate: Predicate, onFalse: (a: A) => E) => (ma: ReaderTaskEither) => - T.chain(ma, (a) => (predicate(a) ? right(a) : left(onFalse(a)))) - -// ------------------------------------------------------------------------------------- -// instances -// ------------------------------------------------------------------------------------- +export function getApplyMonoid(M: Monoid): Monoid> { + return { + concat: getApplySemigroup(M).concat, + empty: right(M.empty) + } +} /** - * @internal + * @category instances + * @since 2.3.0 */ -export const monadReaderTaskEither: Monad3 = { - URI, - map: T.map, - of: right, - ap: T.ap, - chain: T.chain +export function getReaderTaskValidation( + S: Semigroup +): Monad3C & Bifunctor3 & Alt3C & MonadTask3C & MonadThrow3C { + const V = getValidationM(S, monadReaderTask) + return { + URI, + _E: undefined as any, + map: map_, + of, + chain: chain_, + bimap: bimap_, + mapLeft: mapLeft_, + ap: V.ap, + alt: V.alt, + fromIO: fromIO_, + fromTask: fromTask_, + throwError: throwError_ + } } /** @@ -525,16 +569,16 @@ export const monadReaderTaskEither: Monad3 = { */ export const readerTaskEither: Monad3 & Bifunctor3 & Alt3 & MonadTask3 & MonadThrow3 = { URI, - map: T.map, - of: right, - ap: T.ap, - chain: T.chain, + map: map_, + of, + ap: ap_, + chain: chain_, alt: alt_, bimap: bimap_, mapLeft: mapLeft_, - fromIO: rightIO, - fromTask: rightTask, - throwError: left + fromIO: fromIO_, + fromTask: fromTask_, + throwError: throwError_ } /** @@ -543,14 +587,23 @@ export const readerTaskEither: Monad3 & Bifunctor3 & Alt3 & Monad * @category instances * @since 2.0.0 */ -export const readerTaskEitherSeq: typeof readerTaskEither = - /*#__PURE__*/ - ((): typeof readerTaskEither => { - return { - ...readerTaskEither, - ap: (mab, ma) => T.chain(mab, (f) => T.map(ma, f)) - } - })() +export const readerTaskEitherSeq: typeof readerTaskEither = { + URI, + map: map_, + of, + ap: (fab, fa) => + pipe( + fab, + chain((f) => pipe(fa, map(f))) + ), + chain: chain_, + alt: alt_, + bimap: bimap_, + mapLeft: mapLeft_, + fromIO: fromIO_, + fromTask: fromTask_, + throwError: throwError_ +} /** * @category Monad @@ -583,3 +636,14 @@ export const chainTaskEitherKW: ( export const chainIOEitherKW: ( f: (a: A) => IOEither ) => (ma: ReaderTaskEither) => ReaderTaskEither = chainIOEitherK as any + +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/** + * @since 2.0.0 + */ +export function run(ma: ReaderTaskEither, r: R): Promise> { + return ma(r)() +} diff --git a/src/ReadonlyArray.ts b/src/ReadonlyArray.ts index 6e80acc97..f0968a36c 100644 --- a/src/ReadonlyArray.ts +++ b/src/ReadonlyArray.ts @@ -24,15 +24,10 @@ import { isSome, none, Option, some } from './Option' import { fromCompare, getMonoid as getOrdMonoid, Ord, ordNumber } from './Ord' import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' import { Show } from './Show' -import { TraversableWithIndex1 } from './TraversableWithIndex' +import { TraversableWithIndex1, PipeableTraverseWithIndex1 } from './TraversableWithIndex' import { Unfoldable1 } from './Unfoldable' import { Witherable1 } from './Witherable' - -declare module './HKT' { - interface URItoKind { - readonly ReadonlyArray: ReadonlyArray - } -} +import { Traversable1, PipeableTraverse1 } from './Traversable' /** * @category model @@ -46,6 +41,12 @@ export const URI = 'ReadonlyArray' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: ReadonlyArray + } +} + /** * @category constructors * @since 2.5.0 @@ -836,7 +837,7 @@ export function findLastIndex(predicate: Predicate): (as: ReadonlyArray */ export function unsafeInsertAt(i: number, a: A, as: ReadonlyArray): ReadonlyArray { // tslint:disable-next-line: readonly-array - const xs = [...as] + const xs = as.slice() xs.splice(i, 0, a) return xs } @@ -865,7 +866,7 @@ export function unsafeUpdateAt(i: number, a: A, as: ReadonlyArray): Readon return as } else { // tslint:disable-next-line: readonly-array - const xs = [...as] + const xs = as.slice() xs[i] = a return xs } @@ -893,7 +894,7 @@ export function updateAt(i: number, a: A): (as: ReadonlyArray) => Option(i: number, as: ReadonlyArray): ReadonlyArray { // tslint:disable-next-line: readonly-array - const xs = [...as] + const xs = as.slice() xs.splice(i, 1) return xs } @@ -944,7 +945,7 @@ export function modifyAt(i: number, f: (a: A) => A): (as: ReadonlyArray) = * @since 2.5.0 */ export function reverse(as: ReadonlyArray): ReadonlyArray { - return [...as].reverse() + return as.slice().reverse() } /** @@ -1009,7 +1010,7 @@ export function lefts(as: ReadonlyArray>): ReadonlyArray { * @since 2.5.0 */ export function sort(O: Ord): (as: ReadonlyArray) => ReadonlyArray { - return (as) => [...as].sort(O.compare) + return (as) => as.slice().sort(O.compare) } /** @@ -1558,15 +1559,6 @@ const traverse_ = ( return (ta, f) => traverseWithIndexF(ta, (_, a) => f(a)) } -const sequence_ = (F: Applicative) => (ta: ReadonlyArray>): HKT> => { - return reduce_(ta, F.of(zero_()), (fas, fa) => - F.ap( - F.map(fas, (as) => (a: A) => snoc(as, a)), - fa - ) - ) -} - const traverseWithIndex_ = (F: Applicative) => ( ta: ReadonlyArray, f: (i: number, a: A) => HKT @@ -1833,6 +1825,40 @@ export const reduceRightWithIndex: (b: B, f: (i: number, a: A, b: B) => B) // instances // ------------------------------------------------------------------------------------- +/** + * @since 2.6.3 + */ +export const traverse: PipeableTraverse1 = ( + F: Applicative +): ((f: (a: A) => HKT) => (ta: ReadonlyArray) => HKT>) => { + const traverseF = traverse_(F) + return (f) => (ta) => traverseF(ta, f) +} + +/** + * @since 2.6.3 + */ +export const sequence: Traversable1['sequence'] = (F: Applicative) => ( + ta: ReadonlyArray> +): HKT> => { + return reduce_(ta, F.of(zero_()), (fas, fa) => + F.ap( + F.map(fas, (as) => (a: A) => snoc(as, a)), + fa + ) + ) +} + +/** + * @since 2.6.3 + */ +export const traverseWithIndex: PipeableTraverseWithIndex1 = ( + F: Applicative +): ((f: (i: number, a: A) => HKT) => (ta: ReadonlyArray) => HKT>) => { + const traverseWithIndexF = traverseWithIndex_(F) + return (f) => (ta) => traverseWithIndexF(ta, f) +} + /** * @category instances * @since 2.5.0 @@ -1870,7 +1896,7 @@ export const readonlyArray: Monad1 & foldMap: foldMap_, reduceRight: reduceRight_, traverse: traverse_, - sequence: sequence_, + sequence, reduceWithIndex: reduceWithIndex_, foldMapWithIndex: foldMapWithIndex_, reduceRightWithIndex: reduceRightWithIndex_, diff --git a/src/ReadonlyMap.ts b/src/ReadonlyMap.ts index 01a4084ef..318db8f42 100644 --- a/src/ReadonlyMap.ts +++ b/src/ReadonlyMap.ts @@ -8,11 +8,11 @@ import { Eq, fromEquals } from './Eq' import { Filterable2 } from './Filterable' import { FilterableWithIndex2C } from './FilterableWithIndex' import { Foldable, Foldable1, Foldable2, Foldable3 } from './Foldable' -import { Predicate, Refinement } from './function' +import { Predicate, Refinement, pipe } from './function' import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT' import { Magma } from './Magma' import { Monoid } from './Monoid' -import { isNone, isSome, none, Option, option, some } from './Option' +import * as O from './Option' import { Ord } from './Ord' import { Semigroup } from './Semigroup' import { Show } from './Show' @@ -20,11 +20,7 @@ import { TraversableWithIndex2C } from './TraversableWithIndex' import { Unfoldable, Unfoldable1 } from './Unfoldable' import { Witherable2C } from './Witherable' -declare module './HKT' { - interface URItoKind2 { - readonly ReadonlyMap: ReadonlyMap - } -} +import Option = O.Option /** * @category model @@ -38,6 +34,12 @@ export const URI = 'ReadonlyMap' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: ReadonlyMap + } +} + /** * @category constructors * @since 2.5.0 @@ -98,7 +100,7 @@ export function isEmpty(d: ReadonlyMap): boolean { */ export function member(E: Eq): (k: K, m: ReadonlyMap) => boolean { const lookupE = lookup(E) - return (k, m) => isSome(lookupE(k, m)) + return (k, m) => O.isSome(lookupE(k, m)) } interface Next { @@ -177,16 +179,19 @@ export function toReadonlyArray(O: Ord): (m: ReadonlyMap) => Read * @since 2.5.0 */ export function toUnfoldable( - O: Ord, + ord: Ord, U: Unfoldable1 ): (d: ReadonlyMap) => Kind -export function toUnfoldable(O: Ord, U: Unfoldable): (d: ReadonlyMap) => HKT -export function toUnfoldable(O: Ord, U: Unfoldable): (d: ReadonlyMap) => HKT { - const toArrayO = toReadonlyArray(O) +export function toUnfoldable(ord: Ord, U: Unfoldable): (d: ReadonlyMap) => HKT +export function toUnfoldable( + ord: Ord, + U: Unfoldable +): (d: ReadonlyMap) => HKT { + const toArrayO = toReadonlyArray(ord) return (d) => { const arr = toArrayO(d) const len = arr.length - return U.unfold(0, (b) => (b < len ? some([arr[b], b + 1]) : none)) + return U.unfold(0, (b) => (b < len ? O.some([arr[b], b + 1]) : O.none)) } } @@ -200,7 +205,7 @@ export function insertAt(E: Eq): (k: K, a: A) => (m: ReadonlyMap) const lookupWithKeyE = lookupWithKey(E) return (k, a) => (m) => { const found = lookupWithKeyE(k, m) - if (isNone(found)) { + if (O.isNone(found)) { const r = new Map(m) r.set(k, a) return r @@ -223,7 +228,7 @@ export function deleteAt(E: Eq): (k: K) => (m: ReadonlyMap) => Re const lookupWithKeyE = lookupWithKey(E) return (k) => (m) => { const found = lookupWithKeyE(k, m) - if (isSome(found)) { + if (O.isSome(found)) { const r = new Map(m) r.delete(found.value[0]) return r @@ -239,12 +244,12 @@ export function updateAt(E: Eq): (k: K, a: A) => (m: ReadonlyMap) const lookupWithKeyE = lookupWithKey(E) return (k, a) => (m) => { const found = lookupWithKeyE(k, m) - if (isNone(found)) { - return none + if (O.isNone(found)) { + return O.none } const r = new Map(m) r.set(found.value[0], a) - return some(r) + return O.some(r) } } @@ -257,12 +262,12 @@ export function modifyAt( const lookupWithKeyE = lookupWithKey(E) return (k, f) => (m) => { const found = lookupWithKeyE(k, m) - if (isNone(found)) { - return none + if (O.isNone(found)) { + return O.none } const r = new Map(m) r.set(found.value[0], f(found.value[1])) - return some(r) + return O.some(r) } } @@ -276,7 +281,11 @@ export function pop(E: Eq): (k: K) => (m: ReadonlyMap) => Option< const deleteAtE = deleteAt(E) return (k) => { const deleteAtEk = deleteAtE(k) - return (m) => option.map(lookupE(k, m), (a) => [a, deleteAtEk(m)]) + return (m) => + pipe( + lookupE(k, m), + O.map((a) => [a, deleteAtEk(m)]) + ) } } @@ -294,10 +303,10 @@ export function lookupWithKey(E: Eq): (k: K, m: ReadonlyMap) => O while (!(e = entries.next()).done) { const [ka, a] = e.value if (E.equals(ka, k)) { - return some([ka, a]) + return O.some([ka, a]) } } - return none + return O.none } } @@ -308,7 +317,11 @@ export function lookupWithKey(E: Eq): (k: K, m: ReadonlyMap) => O */ export function lookup(E: Eq): (k: K, m: ReadonlyMap) => Option { const lookupWithKeyE = lookupWithKey(E) - return (k, m) => option.map(lookupWithKeyE(k, m), ([_, a]) => a) + return (k, m) => + pipe( + lookupWithKeyE(k, m), + O.map(([_, a]) => a) + ) } /** @@ -325,7 +338,7 @@ export function isSubmap(SK: Eq, SA: Eq): (d1: ReadonlyMap, d2 while (!(e = entries.next()).done) { const [k, a] = e.value const d2OptA = lookupWithKeyS(k, d2) - if (isNone(d2OptA) || !SK.equals(k, d2OptA.value[0]) || !SA.equals(a, d2OptA.value[1])) { + if (O.isNone(d2OptA) || !SK.equals(k, d2OptA.value[0]) || !SA.equals(a, d2OptA.value[1])) { return false } } @@ -370,7 +383,7 @@ export function getMonoid(SK: Eq, SA: Semigroup): Monoid( const lookupWithKeyE = lookupWithKey(E) return F.reduce>(fka, new Map(), (b, [k, a]) => { const bOpt = lookupWithKeyE(k, b) - if (isSome(bOpt)) { + if (O.isSome(bOpt)) { b.set(bOpt.value[0], M.concat(bOpt.value[1], a)) } else { b.set(k, a) @@ -505,7 +518,7 @@ const filterMapWithIndex_ = (fa: ReadonlyMap, f: (k: K, a: A) => while (!(e = entries.next()).done) { const [k, a] = e.value const o = f(k, a) - if (isSome(o)) { + if (O.isSome(o)) { m.set(k, o.value) } } @@ -560,7 +573,7 @@ export const compact = (fa: ReadonlyMap>): ReadonlyMap // tslint:disable-next-line: strict-boolean-expressions while (!(e = entries.next()).done) { const [k, oa] = e.value - if (isSome(oa)) { + if (O.isSome(oa)) { m.set(k, oa.value) } } @@ -645,9 +658,16 @@ export const separate = ( */ export function getFilterableWithIndex(): FilterableWithIndex2C { return { - ...readonlyMap, + URI, _E: undefined as any, + map: map_, mapWithIndex: mapWithIndex_, + compact, + separate, + filter: filter_, + filterMap: filterMap_, + partition: partition_, + partitionMap: partitionMap_, partitionMapWithIndex: partitionMapWithIndex_, partitionWithIndex: partitionWithIndex_, filterMapWithIndex: filterMapWithIndex_, @@ -727,8 +747,15 @@ export function getWitherable(O: Ord): Witherable2C & TraversableW } return { - ...readonlyMap, + URI, _E: undefined as any, + map: map_, + compact, + separate, + filter: filter_, + filterMap: filterMap_, + partition: partition_, + partitionMap: partitionMap_, reduce: (fa, b, f) => reduceWithIndex(fa, b, (_, b, a) => f(b, a)), foldMap: (M) => { const foldMapWithIndexM = foldMapWithIndex(M) diff --git a/src/ReadonlyNonEmptyArray.ts b/src/ReadonlyNonEmptyArray.ts index 7ab7ed4f2..890a13115 100644 --- a/src/ReadonlyNonEmptyArray.ts +++ b/src/ReadonlyNonEmptyArray.ts @@ -17,13 +17,8 @@ import * as RA from './ReadonlyArray' import { ReadonlyRecord } from './ReadonlyRecord' import { getJoinSemigroup, getMeetSemigroup, Semigroup } from './Semigroup' import { Show } from './Show' -import { TraversableWithIndex1 } from './TraversableWithIndex' - -declare module './HKT' { - interface URItoKind { - readonly ReadonlyNonEmptyArray: ReadonlyNonEmptyArray - } -} +import { TraversableWithIndex1, PipeableTraverseWithIndex1 } from './TraversableWithIndex' +import { Traversable1, PipeableTraverse1 } from './Traversable' /** * @category model @@ -37,11 +32,17 @@ export const URI = 'ReadonlyNonEmptyArray' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: ReadonlyNonEmptyArray + } +} + /** * @category model * @since 2.5.0 */ -export interface ReadonlyNonEmptyArray extends ReadonlyArray { +export type ReadonlyNonEmptyArray = ReadonlyArray & { readonly 0: A } @@ -517,6 +518,21 @@ export const reduceRightWithIndex: ( // instances // ------------------------------------------------------------------------------------- +/** + * @since 2.6.3 + */ +export const traverse: PipeableTraverse1 = RA.traverse as any + +/** + * @since 2.6.3 + */ +export const sequence: Traversable1['sequence'] = RA.sequence as any + +/** + * @since 2.6.3 + */ +export const traverseWithIndex: PipeableTraverseWithIndex1 = RA.traverseWithIndex as any + /** * @category instances * @since 2.5.0 @@ -539,7 +555,7 @@ export const readonlyNonEmptyArray: Monad1 & foldMap: RA.readonlyArray.foldMap, reduceRight: RA.readonlyArray.reduceRight, traverse: RA.readonlyArray.traverse as any, - sequence: RA.readonlyArray.sequence as any, + sequence, reduceWithIndex: RA.readonlyArray.reduceWithIndex, foldMapWithIndex: RA.readonlyArray.foldMapWithIndex, reduceRightWithIndex: RA.readonlyArray.reduceRightWithIndex, diff --git a/src/ReadonlyRecord.ts b/src/ReadonlyRecord.ts index 89afcdcc9..79fa4e7b5 100644 --- a/src/ReadonlyRecord.ts +++ b/src/ReadonlyRecord.ts @@ -26,12 +26,6 @@ import { Witherable1 } from './Witherable' */ export type ReadonlyRecord = Readonly> -declare module './HKT' { - interface URItoKind { - readonly ReadonlyRecord: ReadonlyRecord - } -} - /** * @category model * @since 2.5.0 @@ -44,6 +38,12 @@ export const URI = 'ReadonlyRecord' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: ReadonlyRecord + } +} + /** * @category constructors * @since 2.5.0 diff --git a/src/ReadonlyTuple.ts b/src/ReadonlyTuple.ts index 3e13aa01f..adff80e80 100644 --- a/src/ReadonlyTuple.ts +++ b/src/ReadonlyTuple.ts @@ -15,13 +15,7 @@ import { Monad2C } from './Monad' import { Monoid } from './Monoid' import { Semigroup } from './Semigroup' import { Semigroupoid2 } from './Semigroupoid' -import { Traversable2 } from './Traversable' - -declare module './HKT' { - interface URItoKind2 { - readonly ReadonlyTuple: readonly [A, E] - } -} +import { Traversable2, PipeableTraverse2 } from './Traversable' /** * @category model @@ -35,6 +29,12 @@ export const URI = 'ReadonlyTuple' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: readonly [A, E] + } +} + /** * @category destructors * @since 2.5.0 @@ -81,8 +81,12 @@ const of = (M: Monoid) => (a: A): readonly [A, S] => { * @since 2.5.0 */ export function getApplicative(M: Monoid): Applicative2C { + const A = getApply(M) return { - ...getApply(M), + URI, + _E: undefined as any, + map: A.map, + ap: A.ap, of: of(M) } } @@ -92,8 +96,12 @@ export function getApplicative(M: Monoid): Applicative2C { * @since 2.5.0 */ export function getChain(S: Semigroup): Chain2C { + const A = getApply(S) return { - ...getApply(S), + URI, + _E: undefined as any, + map: A.map, + ap: A.ap, chain: (fa, f) => { const [b, s] = f(fst(fa)) return [b, S.concat(snd(fa), s)] @@ -106,8 +114,13 @@ export function getChain(S: Semigroup): Chain2C { * @since 2.5.0 */ export function getMonad(M: Monoid): Monad2C { + const C = getChain(M) return { - ...getChain(M), + URI, + _E: undefined as any, + map: C.map, + ap: C.ap, + chain: C.chain, of: of(M) } } @@ -129,8 +142,13 @@ export function getChainRec(M: Monoid): ChainRec2C { return [s.right, M.concat(acc, snd(result))] } + const C = getChain(M) return { - ...getChain(M), + URI, + _E: undefined as any, + map: C.map, + ap: C.ap, + chain: C.chain, chainRec } } @@ -237,6 +255,31 @@ export const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: readonly // instances // ------------------------------------------------------------------------------------- +const traverse_ = (F: Applicative) => ( + as: readonly [A, S], + f: (a: A) => HKT +): HKT => { + return F.map(f(fst(as)), (b) => [b, snd(as)]) +} + +/** + * @since 2.6.3 + */ +export const traverse: PipeableTraverse2 = ( + F: Applicative +): ((f: (a: A) => HKT) => (as: readonly [A, S]) => HKT) => { + return (f) => (ta) => traverse_(F)(ta, f) +} + +/** + * @since 2.6.3 + */ +export const sequence: Traversable2['sequence'] = (F: Applicative) => ( + fas: readonly [HKT, S] +): HKT => { + return F.map(fst(fas), (a) => [a, snd(fas)]) +} + /** * @category instances * @since 2.5.0 @@ -256,13 +299,6 @@ export const readonlyTuple: Semigroupoid2 & reduce: reduce_, foldMap: foldMap_, reduceRight: reduceRight_, - traverse: (F: Applicative) => ( - as: readonly [A, S], - f: (a: A) => HKT - ): HKT => { - return F.map(f(fst(as)), (b) => [b, snd(as)]) - }, - sequence: (F: Applicative) => (fas: readonly [HKT, S]): HKT => { - return F.map(fst(fas), (a) => [a, snd(fas)]) - } + traverse: traverse_, + sequence } diff --git a/src/Record.ts b/src/Record.ts index fe5ab2d9d..fee3ca2d6 100644 --- a/src/Record.ts +++ b/src/Record.ts @@ -23,12 +23,6 @@ import { Witherable1 } from './Witherable' /* tslint:disable:readonly-array */ -declare module './HKT' { - interface URItoKind { - readonly Record: Record - } -} - /** * @category model * @since 2.0.0 @@ -41,6 +35,12 @@ export const URI = 'Record' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: Record + } +} + /** * @since 2.0.0 */ @@ -566,8 +566,5 @@ export const record: FunctorWithIndex1 & FoldableWithIndex1 = /*#__PURE__*/ (() => { - return { - ...(RR.readonlyRecord as any), - URI - } + return Object.assign({}, RR.readonlyRecord as any, { URI }) })() diff --git a/src/Ring.ts b/src/Ring.ts index 21f3f3f17..1638a6947 100644 --- a/src/Ring.ts +++ b/src/Ring.ts @@ -24,8 +24,12 @@ export interface Ring extends Semiring { * @since 2.0.0 */ export function getFunctionRing(ring: Ring): Ring<(a: A) => B> { + const S = getFunctionSemiring(ring) return { - ...getFunctionSemiring(ring), + add: S.add, + mul: S.mul, + one: S.one, + zero: S.zero, sub: (f, g) => (x) => ring.sub(f(x), g(x)) } } diff --git a/src/State.ts b/src/State.ts index 81e085fc8..7b7aebbe5 100644 --- a/src/State.ts +++ b/src/State.ts @@ -1,18 +1,12 @@ /** * @since 2.0.0 */ -import { monadIdentity } from './Identity' import { Monad2 } from './Monad' -import { getStateM } from './StateT' -import { identity } from './function' +import { identity, pipe } from './function' -const T = /*#__PURE__*/ getStateM(monadIdentity) - -declare module './HKT' { - interface URItoKind2 { - readonly State: State - } -} +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- /** * @category model @@ -26,6 +20,12 @@ export const URI = 'State' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: State + } +} + /* tslint:disable:readonly-array */ /** * @category model @@ -36,123 +36,159 @@ export interface State { } /* tslint:enable:readonly-array */ -/** - * Run a computation in the `State` monad, discarding the final state - * - * @since 2.0.0 - */ -export const evalState: (ma: State, s: S) => A = T.evalState - -/** - * Run a computation in the `State` monad discarding the result - * - * @since 2.0.0 - */ -export const execState: (ma: State, s: S) => S = T.execState +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- /** * Get the current state * + * @category constructors * @since 2.0.0 */ -export const get: () => State = T.get +export const get: () => State = () => (s) => [s, s] /** * Set the state * + * @category constructors * @since 2.0.0 */ -export const put: (s: S) => State = T.put +export const put: (s: S) => State = (s) => () => [undefined, s] /** * Modify the state by applying a function to the current state * + * @category constructors * @since 2.0.0 */ -export const modify: (f: (s: S) => S) => State = T.modify +export const modify: (f: (s: S) => S) => State = (f) => (s) => [undefined, f(s)] /** * Get a value which depends on the current state * + * @category constructors * @since 2.0.0 */ -export const gets: (f: (s: S) => A) => State = T.gets - -/** - * @category Applicative - * @since 2.0.0 - */ -export const of: (a: A) => State = T.of +export const gets: (f: (s: S) => A) => State = (f) => (s) => [f(s), s] // ------------------------------------------------------------------------------------- // pipeables // ------------------------------------------------------------------------------------- +/** + * @category Functor + * @since 2.0.0 + */ +export const map: (f: (a: A) => B) => (fa: State) => State = (f) => (fa) => (s1) => { + const [a, s2] = fa(s1) + return [f(a), s2] +} + /** * @category Apply * @since 2.0.0 */ -export const ap: (fa: State) => (fab: State B>) => State = (fa) => (fab) => - T.ap(fab, fa) +export const ap: (fa: State) => (fab: State B>) => State = (fa) => (fab) => (s1) => { + const [f, s2] = fab(s1) + const [a, s3] = fa(s2) + return [f(a), s3] +} /** * @category Apply * @since 2.0.0 */ export const apFirst = (fb: State) => (fa: State): State => - T.ap( - T.map(fa, (a) => (_: B) => a), - fb + pipe( + fa, + map((a) => (_: B) => a), + ap(fb) ) /** * @category Apply * @since 2.0.0 */ -export const apSecond: (fb: State) => (fa: State) => State = (fb) => (fa) => - T.ap( - T.map(fa, () => (b) => b), - fb +export const apSecond = (fb: State) => (fa: State): State => + pipe( + fa, + map(() => (b: B) => b), + ap(fb) ) /** - * @category Monad + * @category Applicative * @since 2.0.0 */ -export const chain: (f: (a: A) => State) => (ma: State) => State = (f) => (ma) => - T.chain(ma, f) +export const of: (a: A) => State = (a) => (s) => [a, s] /** * @category Monad * @since 2.0.0 */ -export const chainFirst: (f: (a: A) => State) => (ma: State) => State = (f) => (ma) => - T.chain(ma, (a) => T.map(f(a), () => a)) +export const chain: (f: (a: A) => State) => (ma: State) => State = (f) => (ma) => (s1) => { + const [a, s2] = ma(s1) + return f(a)(s2) +} /** * @category Monad * @since 2.0.0 */ -export const flatten: (mma: State>) => State = (mma) => T.chain(mma, identity) +export const chainFirst: (f: (a: A) => State) => (ma: State) => State = (f) => + chain((a) => + pipe( + f(a), + map(() => a) + ) + ) /** - * @category Functor + * @category Monad * @since 2.0.0 */ -export const map: (f: (a: A) => B) => (fa: State) => State = (f) => (fa) => T.map(fa, f) +export const flatten: (mma: State>) => State = + /*#__PURE__*/ + chain(identity) // ------------------------------------------------------------------------------------- // instances // ------------------------------------------------------------------------------------- +/* istanbul ignore next */ +const map_: Monad2['map'] = (fa, f) => pipe(fa, map(f)) +/* istanbul ignore next */ +const ap_: Monad2['ap'] = (fab, fa) => pipe(fab, ap(fa)) +/* istanbul ignore next */ +const chain_: Monad2['chain'] = (ma, f) => pipe(ma, chain(f)) + /** * @category instances * @since 2.0.0 */ export const state: Monad2 = { URI, - map: T.map, + map: map_, of, - ap: T.ap, - chain: T.chain + ap: ap_, + chain: chain_ } + +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/** + * Run a computation in the `State` monad, discarding the final state + * + * @since 2.0.0 + */ +export const evalState: (ma: State, s: S) => A = (ma, s) => ma(s)[0] + +/** + * Run a computation in the `State` monad discarding the result + * + * @since 2.0.0 + */ +export const execState: (ma: State, s: S) => S = (ma, s) => ma(s)[1] diff --git a/src/StateReaderTaskEither.ts b/src/StateReaderTaskEither.ts index 4eb5576ff..ce4f8d034 100644 --- a/src/StateReaderTaskEither.ts +++ b/src/StateReaderTaskEither.ts @@ -4,7 +4,7 @@ import { Alt4 } from './Alt' import { Bifunctor4 } from './Bifunctor' import { Either } from './Either' -import { identity, Predicate, Refinement } from './function' +import { identity, pipe, Predicate, Refinement } from './function' import { IO } from './IO' import { IOEither } from './IOEither' import { Monad4 } from './Monad' @@ -15,20 +15,14 @@ import { Reader } from './Reader' import { ReaderEither } from './ReaderEither' import * as RTE from './ReaderTaskEither' import { State } from './State' -import { getStateM } from './StateT' import { Task } from './Task' import { TaskEither } from './TaskEither' -import ReaderTaskEither = RTE.ReaderTaskEither -import { pipe } from './pipeable' - -const T = /*#__PURE__*/ getStateM(RTE.monadReaderTaskEither) +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- -declare module './HKT' { - interface URItoKind4 { - readonly StateReaderTaskEither: StateReaderTaskEither - } -} +import ReaderTaskEither = RTE.ReaderTaskEither /** * @category model @@ -42,6 +36,12 @@ export const URI = 'StateReaderTaskEither' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind4 { + readonly [URI]: StateReaderTaskEither + } +} + /* tslint:disable:readonly-array */ /** * @category model @@ -52,32 +52,12 @@ export interface StateReaderTaskEither { } /* tslint:enable:readonly-array */ -/* tslint:disable:readonly-array */ -/** - * @since 2.0.0 - */ -export function run(ma: StateReaderTaskEither, s: S, r: R): Promise> { - return ma(s)(r)() -} -/* tslint:enable:readonly-array */ - -/** - * Run a computation in the `StateReaderTaskEither` monad, discarding the final state - * - * @since 2.0.0 - */ -export const evalState: (ma: StateReaderTaskEither, s: S) => ReaderTaskEither = - T.evalState - -/** - * Run a computation in the `StateReaderTaskEither` monad discarding the result - * - * @since 2.0.0 - */ -export const execState: (ma: StateReaderTaskEither, s: S) => ReaderTaskEither = - T.execState +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- /** + * @category constructors * @since 2.0.0 */ export function left(e: E): StateReaderTaskEither { @@ -85,11 +65,14 @@ export function left(e: E): StateReaderTaskEither(a: A) => StateReaderTaskEither = T.of +export const right: (a: A) => StateReaderTaskEither = (a) => (s) => + RTE.right([a, s]) /** + * @category constructors * @since 2.0.0 */ export function rightTask(ma: Task): StateReaderTaskEither { @@ -97,6 +80,7 @@ export function rightTask(ma: Task): StateReaderT } /** + * @category constructors * @since 2.0.0 */ export function leftTask(me: Task): StateReaderTaskEither { @@ -104,6 +88,7 @@ export function leftTask(me: Task): StateReaderTa } /** + * @category constructors * @since 2.0.0 */ export function fromTaskEither(ma: TaskEither): StateReaderTaskEither { @@ -111,6 +96,7 @@ export function fromTaskEither(ma: TaskEither): StateReaderTas } /** + * @category constructors * @since 2.0.0 */ export function rightReader(ma: Reader): StateReaderTaskEither { @@ -118,6 +104,7 @@ export function rightReader(ma: Reader): State } /** + * @category constructors * @since 2.0.0 */ export function leftReader(me: Reader): StateReaderTaskEither { @@ -125,6 +112,7 @@ export function leftReader(me: Reader): StateR } /** + * @category constructors * @since 2.0.0 */ export function fromIOEither(ma: IOEither): StateReaderTaskEither { @@ -132,6 +120,7 @@ export function fromIOEither(ma: IOEither): StateReaderTaskEit } /** + * @category constructors * @since 2.0.0 */ export function fromReaderEither(ma: ReaderEither): StateReaderTaskEither { @@ -139,6 +128,7 @@ export function fromReaderEither(ma: ReaderEither): StateRe } /** + * @category constructors * @since 2.0.0 */ export function rightIO(ma: IO): StateReaderTaskEither { @@ -146,6 +136,7 @@ export function rightIO(ma: IO): StateReaderTaskE } /** + * @category constructors * @since 2.0.0 */ export function leftIO(me: IO): StateReaderTaskEither { @@ -153,12 +144,15 @@ export function leftIO(me: IO): StateReaderTaskEi } /** + * @category constructors * @since 2.0.0 */ -export const rightState: (ma: State) => StateReaderTaskEither = - T.fromState +export const rightState: (ma: State) => StateReaderTaskEither = (sa) => ( + s +) => RTE.right(sa(s)) /** + * @category constructors * @since 2.0.0 */ export function leftState(me: State): StateReaderTaskEither { @@ -166,40 +160,85 @@ export function leftState(me: State): StateRea } /** + * @category constructors * @since 2.0.0 */ -export const fromReaderTaskEither: (ma: ReaderTaskEither) => StateReaderTaskEither = - T.fromM +export const fromReaderTaskEither: (ma: ReaderTaskEither) => StateReaderTaskEither = ( + fa +) => (s) => + pipe( + fa, + RTE.map((a) => [a, s]) + ) /** * Get the current state * + * @category constructors * @since 2.0.0 */ -export const get: () => StateReaderTaskEither = T.get +export const get: () => StateReaderTaskEither = () => (s) => RTE.right([s, s]) /** * Set the state * + * @category constructors * @since 2.0.0 */ -export const put: (s: S) => StateReaderTaskEither = T.put +export const put: (s: S) => StateReaderTaskEither = (s) => () => + RTE.right([undefined, s]) /** * Modify the state by applying a function to the current state * + * @category constructors * @since 2.0.0 */ -export const modify: (f: (s: S) => S) => StateReaderTaskEither = T.modify +export const modify: (f: (s: S) => S) => StateReaderTaskEither = (f) => (s) => + RTE.right([undefined, f(s)]) /** * Get a value which depends on the current state * + * @category constructors * @since 2.0.0 */ -export const gets: (f: (s: S) => A) => StateReaderTaskEither = T.gets +export const gets: (f: (s: S) => A) => StateReaderTaskEither = (f) => (s) => + RTE.right([f(s), s]) /** + * @category constructors + * @since 2.0.0 + */ +export const fromEither: (ma: Either) => StateReaderTaskEither = (ma) => + ma._tag === 'Left' ? left(ma.left) : right(ma.right) + +/** + * @category constructors + * @since 2.0.0 + */ +export const fromOption: (onNone: () => E) => (ma: Option) => StateReaderTaskEither = ( + onNone +) => (ma) => (ma._tag === 'None' ? left(onNone()) : right(ma.value)) + +/** + * @category constructors + * @since 2.4.4 + */ +export const fromPredicate: { + (refinement: Refinement, onFalse: (a: A) => E): ( + a: A + ) => StateReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): (a: A) => StateReaderTaskEither +} = (predicate: Predicate, onFalse: (a: A) => E) => (a: A): StateReaderTaskEither => + predicate(a) ? right(a) : left(onFalse(a)) + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- + +/** + * @category combinators * @since 2.4.0 */ export function fromEitherK, B>( @@ -209,6 +248,7 @@ export function fromEitherK, B>( } /** + * @category combinators * @since 2.4.0 */ export function chainEitherK( @@ -218,6 +258,7 @@ export function chainEitherK( } /** + * @category combinators * @since 2.4.0 */ export function fromIOEitherK, B>( @@ -227,6 +268,7 @@ export function fromIOEitherK, B>( } /** + * @category combinators * @since 2.4.0 */ export function chainIOEitherK( @@ -236,6 +278,7 @@ export function chainIOEitherK( } /** + * @category combinators * @since 2.4.0 */ export function fromTaskEitherK, B>( @@ -245,6 +288,7 @@ export function fromTaskEitherK, B>( } /** + * @category combinators * @since 2.4.0 */ export function chainTaskEitherK( @@ -254,6 +298,7 @@ export function chainTaskEitherK( } /** + * @category combinators * @since 2.4.0 */ export function fromReaderTaskEitherK, B>( @@ -263,6 +308,7 @@ export function fromReaderTaskEitherK, B> } /** + * @category combinators * @since 2.4.0 */ export function chainReaderTaskEitherK( @@ -271,103 +317,8 @@ export function chainReaderTaskEitherK( return chain(fromReaderTaskEitherK(f)) } -// ------------------------------------------------------------------------------------- -// pipeables -// ------------------------------------------------------------------------------------- - -const alt_: ( - fx: StateReaderTaskEither, - fy: () => StateReaderTaskEither -) => StateReaderTaskEither = (fx, fy) => (s) => - pipe( - fx(s), - RTE.alt(() => fy()(s)) - ) - -const bimap_: ( - fea: StateReaderTaskEither, - f: (e: E) => G, - g: (a: A) => B -) => StateReaderTaskEither = (fea, f, g) => (s) => - pipe( - fea(s), - RTE.bimap(f, ([a, s]) => [g(a), s]) - ) - -const mapLeft_: ( - fea: StateReaderTaskEither, - f: (e: E) => G -) => StateReaderTaskEither = (fea, f) => (s) => pipe(fea(s), RTE.mapLeft(f)) - -/** - * @since 2.6.2 - */ -export const alt: ( - that: () => StateReaderTaskEither -) => (fa: StateReaderTaskEither) => StateReaderTaskEither = (that) => (fa) => alt_(fa, that) - -/** - * @since 2.0.0 - */ -export const ap: ( - fa: StateReaderTaskEither -) => (fab: StateReaderTaskEither B>) => StateReaderTaskEither = (fa) => (fab) => - T.ap(fab, fa) - -/** - * @since 2.0.0 - */ -export const apFirst = (fb: StateReaderTaskEither) => ( - fa: StateReaderTaskEither -): StateReaderTaskEither => - T.ap( - T.map(fa, (a) => (_: B) => a), - fb - ) - -/** - * @since 2.0.0 - */ -export const apSecond: ( - fb: StateReaderTaskEither -) => (fa: StateReaderTaskEither) => StateReaderTaskEither = (fb) => (fa) => - T.ap( - T.map(fa, () => (b) => b), - fb - ) - -/** - * @since 2.6.2 - */ -export const bimap: ( - f: (e: E) => G, - g: (a: A) => B -) => (fa: StateReaderTaskEither) => StateReaderTaskEither = (f, g) => (fa) => - bimap_(fa, f, g) - -/** - * @since 2.0.0 - */ -export const chain: ( - f: (a: A) => StateReaderTaskEither -) => (ma: StateReaderTaskEither) => StateReaderTaskEither = (f) => (ma) => T.chain(ma, f) - -/** - * @since 2.0.0 - */ -export const chainFirst: ( - f: (a: A) => StateReaderTaskEither -) => (ma: StateReaderTaskEither) => StateReaderTaskEither = (f) => (ma) => - T.chain(ma, (a) => T.map(f(a), () => a)) - -/** - * @since 2.6.0 - */ -export const chainW: ( - f: (a: A) => StateReaderTaskEither -) => (ma: StateReaderTaskEither) => StateReaderTaskEither = chain as any - /** + * @category combinators * @since 2.6.1 */ export const chainEitherKW: ( @@ -375,6 +326,7 @@ export const chainEitherKW: ( ) => (ma: StateReaderTaskEither) => StateReaderTaskEither = chainEitherK as any /** + * @category combinators * @since 2.6.1 */ export const chainTaskEitherKW: ( @@ -382,6 +334,7 @@ export const chainTaskEitherKW: ( ) => (ma: StateReaderTaskEither) => StateReaderTaskEither = chainTaskEitherK as any /** + * @category combinators * @since 2.6.1 */ export const chainReaderTaskEitherKW: ( @@ -391,6 +344,7 @@ export const chainReaderTaskEitherKW: ( ) => StateReaderTaskEither = chainReaderTaskEitherK as any /** + * @category combinators * @since 2.6.1 */ export const chainIOEitherKW: ( @@ -398,20 +352,52 @@ export const chainIOEitherKW: ( ) => (ma: StateReaderTaskEither) => StateReaderTaskEither = chainIOEitherK as any /** - * @since 2.0.0 + * @category combinators + * @since 2.4.4 */ -export const flatten: ( - mma: StateReaderTaskEither> -) => StateReaderTaskEither = (mma) => T.chain(mma, identity) +export const filterOrElse: { + (refinement: Refinement, onFalse: (a: A) => E): ( + ma: StateReaderTaskEither + ) => StateReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): ( + ma: StateReaderTaskEither + ) => StateReaderTaskEither +} = (predicate: Predicate, onFalse: (a: A) => E) => ( + ma: StateReaderTaskEither +): StateReaderTaskEither => + pipe( + ma, + chain((a) => (predicate(a) ? right(a) : left(onFalse(a)))) + ) + +// ------------------------------------------------------------------------------------- +// pipeables +// ------------------------------------------------------------------------------------- /** + * @category Functor * @since 2.0.0 */ export const map: ( f: (a: A) => B -) => (fa: StateReaderTaskEither) => StateReaderTaskEither = (f) => (fa) => T.map(fa, f) +) => (fa: StateReaderTaskEither) => StateReaderTaskEither = (f) => (fa) => (s1) => + pipe( + fa(s1), + RTE.map(([a, s2]) => [f(a), s2]) + ) /** + * @category Bifunctor + * @since 2.6.2 + */ +export const bimap: ( + f: (e: E) => G, + g: (a: A) => B +) => (fa: StateReaderTaskEither) => StateReaderTaskEither = (f, g) => (fa) => + bimap_(fa, f, g) + +/** + * @category Bifunctor * @since 2.6.2 */ export const mapLeft: ( @@ -420,56 +406,151 @@ export const mapLeft: ( mapLeft_(fa, f) /** + * @category Apply * @since 2.0.0 */ -export const fromEither: (ma: Either) => StateReaderTaskEither = (ma) => - ma._tag === 'Left' ? left(ma.left) : right(ma.right) +export const ap: ( + fa: StateReaderTaskEither +) => (fab: StateReaderTaskEither B>) => StateReaderTaskEither = (fa) => (fab) => ( + s1 +) => + pipe( + fab(s1), + RTE.chain(([f, s2]) => + pipe( + fa(s2), + RTE.map(([a, s3]) => [f(a), s3]) + ) + ) + ) /** + * @category Apply * @since 2.0.0 */ -export const fromOption: (onNone: () => E) => (ma: Option) => StateReaderTaskEither = ( - onNone -) => (ma) => (ma._tag === 'None' ? left(onNone()) : right(ma.value)) +export const apFirst = (fb: StateReaderTaskEither) => ( + fa: StateReaderTaskEither +): StateReaderTaskEither => + pipe( + fa, + map((a) => (_: B) => a), + ap(fb) + ) /** - * @since 2.4.4 + * @category Apply + * @since 2.0.0 */ -export const fromPredicate: { - (refinement: Refinement, onFalse: (a: A) => E): ( - a: A - ) => StateReaderTaskEither - (predicate: Predicate, onFalse: (a: A) => E): (a: A) => StateReaderTaskEither -} = (predicate: Predicate, onFalse: (a: A) => E) => (a: A): StateReaderTaskEither => - predicate(a) ? right(a) : left(onFalse(a)) +export const apSecond = (fb: StateReaderTaskEither) => ( + fa: StateReaderTaskEither +): StateReaderTaskEither => + pipe( + fa, + map(() => (b: B) => b), + ap(fb) + ) /** - * @since 2.4.4 + * @category Monad + * @since 2.0.0 */ -export const filterOrElse: { - (refinement: Refinement, onFalse: (a: A) => E): ( - ma: StateReaderTaskEither - ) => StateReaderTaskEither - (predicate: Predicate, onFalse: (a: A) => E): ( - ma: StateReaderTaskEither - ) => StateReaderTaskEither -} = (predicate: Predicate, onFalse: (a: A) => E) => ( - ma: StateReaderTaskEither -): StateReaderTaskEither => T.chain(ma, (a) => (predicate(a) ? right(a) : left(onFalse(a)))) +export const chain: ( + f: (a: A) => StateReaderTaskEither +) => (ma: StateReaderTaskEither) => StateReaderTaskEither = (f) => (ma) => (s1) => + pipe( + ma(s1), + RTE.chain(([a, s2]) => f(a)(s2)) + ) + +/** + * @category Monad + * @since 2.6.0 + */ +export const chainW: ( + f: (a: A) => StateReaderTaskEither +) => (ma: StateReaderTaskEither) => StateReaderTaskEither = chain as any + +/** + * @category Monad + * @since 2.0.0 + */ +export const chainFirst: ( + f: (a: A) => StateReaderTaskEither +) => (ma: StateReaderTaskEither) => StateReaderTaskEither = (f) => + chain((a) => + pipe( + f(a), + map(() => a) + ) + ) + +/** + * @category Monad + * @since 2.0.0 + */ +export const flatten: ( + mma: StateReaderTaskEither> +) => StateReaderTaskEither = + /*#__PURE__*/ + chain(identity) + +/** + * @category Alt + * @since 2.6.2 + */ +export const alt: ( + that: () => StateReaderTaskEither +) => (fa: StateReaderTaskEither) => StateReaderTaskEither = (that) => (fa) => (s) => + pipe( + fa(s), + RTE.alt(() => that()(s)) + ) // ------------------------------------------------------------------------------------- // instances // ------------------------------------------------------------------------------------- +/* istanbul ignore next */ +const map_: Monad4['map'] = (fa, f) => pipe(fa, map(f)) +/* istanbul ignore next */ +const ap_: Monad4['ap'] = (fab, fa) => pipe(fab, ap(fa)) +/* istanbul ignore next */ +const chain_: Monad4['chain'] = (ma, f) => pipe(ma, chain(f)) +const of = right +/* istanbul ignore next */ +const alt_: ( + fx: StateReaderTaskEither, + fy: () => StateReaderTaskEither +) => StateReaderTaskEither = (fx, fy) => (s) => + pipe( + fx(s), + RTE.alt(() => fy()(s)) + ) + +const bimap_: ( + fea: StateReaderTaskEither, + f: (e: E) => G, + g: (a: A) => B +) => StateReaderTaskEither = (fea, f, g) => (s) => + pipe( + fea(s), + RTE.bimap(f, ([a, s]) => [g(a), s]) + ) + +const mapLeft_: ( + fea: StateReaderTaskEither, + f: (e: E) => G +) => StateReaderTaskEither = (fea, f) => (s) => pipe(fea(s), RTE.mapLeft(f)) + /** * @since 2.0.0 */ export const stateReaderTaskEither: Monad4 & Bifunctor4 & Alt4 & MonadTask4 & MonadThrow4 = { URI, - map: T.map, - of: right, - ap: T.ap, - chain: T.chain, + map: map_, + of, + ap: ap_, + chain: chain_, bimap: bimap_, mapLeft: mapLeft_, alt: alt_, @@ -482,11 +563,61 @@ export const stateReaderTaskEither: Monad4 & Bifunctor4 & Alt4 & * Like `stateReaderTaskEither` but `ap` is sequential * @since 2.0.0 */ -export const stateReaderTaskEitherSeq: typeof stateReaderTaskEither = - /*#__PURE__*/ - ((): typeof stateReaderTaskEither => { - return { - ...stateReaderTaskEither, - ap: (mab, ma) => T.chain(mab, (f) => T.map(ma, f)) - } - })() +export const stateReaderTaskEitherSeq: typeof stateReaderTaskEither = { + URI, + map: map_, + of, + ap: (fab, fa) => + pipe( + fab, + chain((f) => pipe(fa, map(f))) + ), + chain: chain_, + bimap: bimap_, + mapLeft: mapLeft_, + alt: alt_, + fromIO: rightIO, + fromTask: rightTask, + throwError: left +} + +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/* tslint:disable:readonly-array */ +/** + * @since 2.0.0 + */ +export function run(ma: StateReaderTaskEither, s: S, r: R): Promise> { + return ma(s)(r)() +} +/* tslint:enable:readonly-array */ + +/** + * Run a computation in the `StateReaderTaskEither` monad, discarding the final state + * + * @since 2.0.0 + */ +export const evalState: (ma: StateReaderTaskEither, s: S) => ReaderTaskEither = ( + fsa, + s +) => + pipe( + fsa(s), + RTE.map(([a]) => a) + ) + +/** + * Run a computation in the `StateReaderTaskEither` monad discarding the result + * + * @since 2.0.0 + */ +export const execState: (ma: StateReaderTaskEither, s: S) => ReaderTaskEither = ( + fsa, + s +) => + pipe( + fsa(s), + RTE.map(([_, s]) => s) + ) diff --git a/src/Store.ts b/src/Store.ts index 05d5cbd95..b04dcac97 100644 --- a/src/Store.ts +++ b/src/Store.ts @@ -6,12 +6,6 @@ import { Endomorphism, identity } from './function' import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor3C } from './Functor' import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT' -declare module './HKT' { - interface URItoKind2 { - readonly Store: Store - } -} - /** * @category model * @since 2.0.0 @@ -24,6 +18,12 @@ export const URI = 'Store' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: Store + } +} + /** * @category model * @since 2.0.0 diff --git a/src/Task.ts b/src/Task.ts index 64b3014cc..6824eeef8 100644 --- a/src/Task.ts +++ b/src/Task.ts @@ -10,12 +10,7 @@ import { Monad1 } from './Monad' import { MonadTask1 } from './MonadTask' import { Monoid } from './Monoid' import { Semigroup } from './Semigroup' - -declare module './HKT' { - interface URItoKind { - readonly Task: Task - } -} +import { Apply1 } from './Apply' /** * @category model @@ -29,6 +24,12 @@ export const URI = 'Task' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: Task + } +} + /** * @category model * @since 2.0.0 @@ -187,6 +188,15 @@ export const map: (f: (a: A) => B) => (fa: Task) => Task = (f) => (f // instances // ------------------------------------------------------------------------------------- +/** + * @internal + */ +export const applyTask: Apply1 = { + URI, + map: map_, + ap: ap_ +} + /** * @internal */ @@ -218,11 +228,12 @@ export const task: Monad1 & MonadTask1 = { * @category instances * @since 2.0.0 */ -export const taskSeq: typeof task = - /*#__PURE__*/ - ((): typeof task => { - return { - ...task, - ap: (mab, ma) => () => mab().then((f) => ma().then((a) => f(a))) - } - })() +export const taskSeq: typeof task = { + URI, + map: map_, + of, + ap: (mab, ma) => () => mab().then((f) => ma().then((a) => f(a))), + chain: chain_, + fromIO, + fromTask: identity +} diff --git a/src/TaskEither.ts b/src/TaskEither.ts index a6e8347c4..089df5aaa 100644 --- a/src/TaskEither.ts +++ b/src/TaskEither.ts @@ -5,11 +5,11 @@ * @since 2.0.0 */ import { Alt2, Alt2C } from './Alt' +import { apComposition } from './Apply' import { Bifunctor2 } from './Bifunctor' import * as E from './Either' -import { getEitherM } from './EitherT' import { Filterable2C, getFilterableComposition } from './Filterable' -import { identity, Lazy, Predicate, Refinement } from './function' +import { flow, identity, Lazy, pipe, Predicate, Refinement } from './function' import { IO } from './IO' import { IOEither } from './IOEither' import { Monad2, Monad2C } from './Monad' @@ -18,18 +18,15 @@ import { MonadThrow2, MonadThrow2C } from './MonadThrow' import { Monoid } from './Monoid' import { Option } from './Option' import { Semigroup } from './Semigroup' -import { getSemigroup as getTaskSemigroup, Task, monadTask, fromIO as fromIOTask } from './Task' +import * as T from './Task' import { getValidationM } from './ValidationT' -import Either = E.Either - -const T = /*#__PURE__*/ getEitherM(monadTask) +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- -declare module './HKT' { - interface URItoKind2 { - readonly TaskEither: TaskEither - } -} +import Either = E.Either +import Task = T.Task /** * @category model @@ -43,131 +40,94 @@ export const URI = 'TaskEither' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: TaskEither + } +} + /** * @category model * @since 2.0.0 */ export interface TaskEither extends Task> {} -/** - * @category constructors - * @since 2.0.0 - */ -export const left: (e: E) => TaskEither = T.left +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- /** * @category constructors * @since 2.0.0 */ -export const right: (a: A) => TaskEither = T.of +export const left: (e: E) => TaskEither = + /*#__PURE__*/ + flow(E.left, T.of) /** * @category constructors * @since 2.0.0 */ -export function rightIO(ma: IO): TaskEither { - return rightTask(fromIOTask(ma)) -} +export const right: (a: A) => TaskEither = + /*#__PURE__*/ + flow(E.right, T.of) /** * @category constructors * @since 2.0.0 */ -export function leftIO(me: IO): TaskEither { - return leftTask(fromIOTask(me)) -} +export const rightIO = (ma: IO): TaskEither => rightTask(T.fromIO(ma)) /** * @category constructors * @since 2.0.0 */ -export const rightTask: (ma: Task) => TaskEither = T.rightM +export const leftIO = (me: IO): TaskEither => leftTask(T.fromIO(me)) /** * @category constructors * @since 2.0.0 */ -export const leftTask: (me: Task) => TaskEither = T.leftM +export const rightTask: (ma: Task) => TaskEither = + /*#__PURE__*/ + T.map(E.right) /** * @category constructors * @since 2.0.0 */ -export const fromIOEither: (fa: IOEither) => TaskEither = fromIOTask - -/** - * @category destructors - * @since 2.0.0 - */ -export function fold( - onLeft: (e: E) => Task, - onRight: (a: A) => Task -): (ma: TaskEither) => Task { - return (ma) => T.fold(ma, onLeft, onRight) -} - -/** - * @category destructors - * @since 2.0.0 - */ -export function getOrElse(onLeft: (e: E) => Task): (ma: TaskEither) => Task { - return (ma) => T.getOrElse(ma, onLeft) -} - -/** - * @category destructors - * @since 2.6.0 - */ -export const getOrElseW: ( - onLeft: (e: E) => Task -) => (ma: TaskEither) => Task = getOrElse as any - -/** - * @category combinators - * @since 2.0.0 - */ -export function orElse(onLeft: (e: E) => TaskEither): (ma: TaskEither) => TaskEither { - return (ma) => T.orElse(ma, onLeft) -} +export const leftTask: (me: Task) => TaskEither = + /*#__PURE__*/ + T.map(E.left) /** - * @category combinators + * @category constructors * @since 2.0.0 */ -export const swap: (ma: TaskEither) => TaskEither = T.swap +export const fromIOEither: (fa: IOEither) => TaskEither = T.fromIO /** - * Semigroup returning the left-most non-`Left` value. If both operands are `Right`s then the inner values are - * appended using the provided `Semigroup` - * - * @category instances + * @category constructors * @since 2.0.0 */ -export function getSemigroup(S: Semigroup): Semigroup> { - return getTaskSemigroup(E.getSemigroup(S)) -} +export const fromEither: (ma: E.Either) => TaskEither = (ma) => + E.isLeft(ma) ? left(ma.left) : right(ma.right) /** - * Semigroup returning the left-most `Left` value. If both operands are `Right`s then the inner values - * are appended using the provided `Semigroup` - * - * @category instances + * @category constructors * @since 2.0.0 */ -export function getApplySemigroup(S: Semigroup): Semigroup> { - return getTaskSemigroup(E.getApplySemigroup(S)) -} +export const fromOption: (onNone: () => E) => (ma: Option) => TaskEither = (onNone) => (ma) => + ma._tag === 'None' ? left(onNone()) : right(ma.value) /** - * @category instances + * @category constructors * @since 2.0.0 */ -export function getApplyMonoid(M: Monoid): Monoid> { - return { - concat: getApplySemigroup(M).concat, - empty: right(M.empty) - } -} +export const fromPredicate: { + (refinement: Refinement, onFalse: (a: A) => E): (a: A) => TaskEither + (predicate: Predicate, onFalse: (a: A) => E): (a: A) => TaskEither +} = (predicate: Predicate, onFalse: (a: A) => E) => (a: A) => (predicate(a) ? right(a) : left(onFalse(a))) /** * Transforms a `Promise` that may reject to a `Promise` that never rejects and returns an `Either` instead. @@ -192,26 +152,6 @@ export function tryCatch(f: Lazy>, onRejected: (reason: unknown return () => f().then(E.right, (reason) => E.left(onRejected(reason))) } -/** - * Make sure that a resource is cleaned up in the event of an exception (*). The release action is called regardless of - * whether the body action throws (*) or returns. - * - * (*) i.e. returns a `Left` - * - * @since 2.0.0 - */ -export function bracket( - acquire: TaskEither, - use: (a: A) => TaskEither, - release: (a: A, e: Either) => TaskEither -): TaskEither { - return T.chain(acquire, (a) => - T.chain(monadTask.map(use(a), E.right), (e) => - T.chain(release(a, e), () => (E.isLeft(e) ? T.left(e.left) : T.of(e.right))) - ) - ) -} - /** * Convert a node style callback function to one returning a `TaskEither` * @@ -267,36 +207,84 @@ export function taskify(f: Function): () => TaskEither { } } +// ------------------------------------------------------------------------------------- +// destructors +// ------------------------------------------------------------------------------------- + /** - * @category instances + * @category destructors * @since 2.0.0 */ -export function getTaskValidation( - S: Semigroup -): Monad2C & Bifunctor2 & Alt2C & MonadTask2C & MonadThrow2C { - const T = getValidationM(S, monadTask) - return { - _E: undefined as any, - ...taskEither, - ...T - } -} +export const fold: ( + onLeft: (e: E) => Task, + onRight: (a: A) => Task +) => (ma: TaskEither) => Task = + /*#__PURE__*/ + flow(E.fold, T.chain) /** - * @category instances - * @since 2.1.0 + * @category destructors + * @since 2.0.0 */ -export function getFilterable(M: Monoid): Filterable2C { - const F = E.getWitherable(M) +export const getOrElse: (onLeft: (e: E) => Task) => (ma: TaskEither) => Task = (onLeft) => + T.chain(E.fold(onLeft, T.of)) - return { - URI, - _E: undefined as any, - ...getFilterableComposition(monadTask, F) - } +/** + * @category destructors + * @since 2.6.0 + */ +export const getOrElseW: ( + onLeft: (e: E) => Task +) => (ma: TaskEither) => Task = getOrElse as any + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- + +/** + * @category combinators + * @since 2.0.0 + */ +export const orElse: (onLeft: (e: E) => TaskEither) => (ma: TaskEither) => TaskEither = ( + f +) => T.chain(E.fold(f, right)) + +/** + * @category combinators + * @since 2.0.0 + */ +export const swap: (ma: TaskEither) => TaskEither = + /*#__PURE__*/ + T.map(E.swap) + +/** + * @category combinators + * @since 2.0.0 + */ +export const filterOrElse: { + (refinement: Refinement, onFalse: (a: A) => E): (ma: TaskEither) => TaskEither + (predicate: Predicate, onFalse: (a: A) => E): (ma: TaskEither) => TaskEither +} = (predicate: Predicate, onFalse: (a: A) => E) => (ma: TaskEither) => + pipe( + ma, + chain((a) => (predicate(a) ? right(a) : left(onFalse(a)))) + ) + +/** + * Converts a function returning a `Promise` to one returning a `TaskEither`. + * + * @category combinators + * @since 2.5.0 + */ +export function tryCatchK, B>( + f: (...a: A) => Promise, + onRejected: (reason: unknown) => E +): (...a: A) => TaskEither { + return (...a) => tryCatch(() => f(...a), onRejected) } /** + * @category combinators * @since 2.4.0 */ export function fromEitherK, B>( @@ -306,24 +294,33 @@ export function fromEitherK, B>( } /** - * @category Monad + * @category combinators * @since 2.4.0 */ -export function chainEitherK(f: (a: A) => Either): (ma: TaskEither) => TaskEither { - return chain(fromEitherK(f)) +export function fromIOEitherK, B>( + f: (...a: A) => IOEither +): (...a: A) => TaskEither { + return (...a) => fromIOEither(f(...a)) } /** + * @category combinators * @since 2.4.0 */ -export function fromIOEitherK, B>( - f: (...a: A) => IOEither -): (...a: A) => TaskEither { - return (...a) => fromIOEither(f(...a)) +export function chainEitherK(f: (a: A) => Either): (ma: TaskEither) => TaskEither { + return chain(fromEitherK(f)) } /** - * @category Monad + * @category combinators + * @since 2.6.1 + */ +export const chainEitherKW: ( + f: (a: A) => Either +) => (ma: TaskEither) => TaskEither = chainEitherK as any + +/** + * @category combinators * @since 2.4.0 */ export function chainIOEitherK(f: (a: A) => IOEither): (ma: TaskEither) => TaskEither { @@ -331,72 +328,74 @@ export function chainIOEitherK(f: (a: A) => IOEither): (ma: TaskE } /** - * Converts a function returning a `Promise` to one returning a `TaskEither`. - * - * @since 2.5.0 + * @category combinators + * @since 2.6.1 */ -export function tryCatchK, B>( - f: (...a: A) => Promise, - onRejected: (reason: unknown) => E -): (...a: A) => TaskEither { - return (...a) => tryCatch(() => f(...a), onRejected) -} +export const chainIOEitherKW: ( + f: (a: A) => IOEither +) => (ma: TaskEither) => TaskEither = chainIOEitherK as any // ------------------------------------------------------------------------------------- // pipeables // ------------------------------------------------------------------------------------- /** - * @category Alt + * @category Functor * @since 2.0.0 */ -export const alt: (that: () => TaskEither) => (fa: TaskEither) => TaskEither = (that) => (fa) => - T.alt(fa, that) +export const map: (f: (a: A) => B) => (fa: TaskEither) => TaskEither = (f) => T.map(E.map(f)) /** - * @category Apply + * @category Bifunctor * @since 2.0.0 */ -export const ap: (fa: TaskEither) => (fab: TaskEither B>) => TaskEither = (fa) => ( - fab -) => T.ap(fab, fa) +export const bimap: (f: (e: E) => G, g: (a: A) => B) => (fa: TaskEither) => TaskEither = + /*#__PURE__*/ + flow(E.bimap, T.map) + +/** + * @category Bifunctor + * @since 2.0.0 + */ +export const mapLeft: (f: (e: E) => G) => (fa: TaskEither) => TaskEither = (f) => + T.map(E.mapLeft(f)) /** * @category Apply * @since 2.0.0 */ -export const apFirst: (fb: TaskEither) => (fa: TaskEither) => TaskEither = (fb) => (fa) => - T.ap( - T.map(fa, (a) => () => a), - fb - ) +export const ap: (fa: TaskEither) => (fab: TaskEither B>) => TaskEither = + /*#__PURE__*/ + apComposition(T.applyTask, E.applyEither) /** * @category Apply * @since 2.0.0 */ -export const apSecond = (fb: TaskEither) => (fa: TaskEither): TaskEither => - T.ap( - T.map(fa, () => (b: B) => b), - fb +export const apFirst: (fb: TaskEither) => (fa: TaskEither) => TaskEither = (fb) => (fa) => + pipe( + fa, + map((a) => () => a), + ap(fb) ) /** - * @category Bifunctor + * @category Apply * @since 2.0.0 */ -export const bimap: (f: (e: E) => G, g: (a: A) => B) => (fa: TaskEither) => TaskEither = ( - f, - g -) => (fa) => T.bimap(fa, f, g) +export const apSecond = (fb: TaskEither) => (fa: TaskEither): TaskEither => + pipe( + fa, + map(() => (b: B) => b), + ap(fb) + ) /** * @category Monad * @since 2.0.0 */ -export const chain: (f: (a: A) => TaskEither) => (ma: TaskEither) => TaskEither = (f) => ( - ma -) => T.chain(ma, f) +export const chain: (f: (a: A) => TaskEither) => (ma: TaskEither) => TaskEither = (f) => + T.chain(E.fold(left, f)) /** * @category Monad @@ -406,95 +405,156 @@ export const chainW: ( f: (a: A) => TaskEither ) => (ma: TaskEither) => TaskEither = chain as any -/** - * @category Monad - * @since 2.6.1 - */ -export const chainEitherKW: ( - f: (a: A) => Either -) => (ma: TaskEither) => TaskEither = chainEitherK as any - -/** - * @category Monad - * @since 2.6.1 - */ -export const chainIOEitherKW: ( - f: (a: A) => IOEither -) => (ma: TaskEither) => TaskEither = chainIOEitherK as any - /** * @category Monad * @since 2.0.0 */ -export const chainFirst: (f: (a: A) => TaskEither) => (ma: TaskEither) => TaskEither = ( - f -) => (ma) => T.chain(ma, (a) => T.map(f(a), () => a)) +export const chainFirst: (f: (a: A) => TaskEither) => (ma: TaskEither) => TaskEither = (f) => + chain((a) => + pipe( + f(a), + map(() => a) + ) + ) /** * @category Monad * @since 2.0.0 */ -export const flatten: (mma: TaskEither>) => TaskEither = (mma) => T.chain(mma, identity) +export const flatten: (mma: TaskEither>) => TaskEither = + /*#__PURE__*/ + chain(identity) /** - * @category Functor + * @category Alt * @since 2.0.0 */ -export const map: (f: (a: A) => B) => (fa: TaskEither) => TaskEither = (f) => (fa) => T.map(fa, f) +export const alt: (that: () => TaskEither) => (fa: TaskEither) => TaskEither = (that) => + T.chain(E.fold(that, right)) /** - * @category Bifunctor + * Make sure that a resource is cleaned up in the event of an exception (*). The release action is called regardless of + * whether the body action throws (*) or returns. + * + * (*) i.e. returns a `Left` + * + * @category MonadThrow * @since 2.0.0 */ -export const mapLeft: (f: (e: E) => G) => (fa: TaskEither) => TaskEither = (f) => (fa) => - T.mapLeft(fa, f) +export const bracket = ( + acquire: TaskEither, + use: (a: A) => TaskEither, + release: (a: A, e: Either) => TaskEither +): TaskEither => + pipe( + acquire, + chain((a) => + pipe( + pipe(use(a), T.map(E.right)), + chain((e) => + pipe( + release(a, e), + chain(() => (E.isLeft(e) ? left(e.left) : of(e.right))) + ) + ) + ) + ) + ) + +// ------------------------------------------------------------------------------------- +// instances +// ------------------------------------------------------------------------------------- + +const map_: Monad2['map'] = (fa, f) => pipe(fa, map(f)) +/* istanbul ignore next */ +const bimap_: Bifunctor2['bimap'] = (fa, f, g) => pipe(fa, bimap(f, g)) +/* istanbul ignore next */ +const mapLeft_: Bifunctor2['mapLeft'] = (fa, f) => pipe(fa, mapLeft(f)) +const ap_: Monad2['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const of = right +const chain_: Monad2['chain'] = (ma, f) => pipe(ma, chain(f)) +/* istanbul ignore next */ +const alt_: Alt2['alt'] = (fa, that) => pipe(fa, alt(that)) +const fromIO_ = rightIO +const fromTask_ = rightTask +const throwError_ = left /** - * @category constructors + * Semigroup returning the left-most non-`Left` value. If both operands are `Right`s then the inner values are + * appended using the provided `Semigroup` + * + * @category instances * @since 2.0.0 */ -export const fromEither: (ma: E.Either) => TaskEither = (ma) => - E.isLeft(ma) ? left(ma.left) : right(ma.right) +export function getSemigroup(S: Semigroup): Semigroup> { + return T.getSemigroup(E.getSemigroup(S)) +} /** - * @category constructors + * Semigroup returning the left-most `Left` value. If both operands are `Right`s then the inner values + * are appended using the provided `Semigroup` + * + * @category instances * @since 2.0.0 */ -export const fromOption: (onNone: () => E) => (ma: Option) => TaskEither = (onNone) => (ma) => - ma._tag === 'None' ? left(onNone()) : right(ma.value) +export function getApplySemigroup(S: Semigroup): Semigroup> { + return T.getSemigroup(E.getApplySemigroup(S)) +} /** - * @category constructors + * @category instances * @since 2.0.0 */ -export const fromPredicate: { - (refinement: Refinement, onFalse: (a: A) => E): (a: A) => TaskEither - (predicate: Predicate, onFalse: (a: A) => E): (a: A) => TaskEither -} = (predicate: Predicate, onFalse: (a: A) => E) => (a: A) => (predicate(a) ? right(a) : left(onFalse(a))) +export function getApplyMonoid(M: Monoid): Monoid> { + return { + concat: getApplySemigroup(M).concat, + empty: right(M.empty) + } +} /** - * @category combinators + * @category instances * @since 2.0.0 */ -export const filterOrElse: { - (refinement: Refinement, onFalse: (a: A) => E): (ma: TaskEither) => TaskEither - (predicate: Predicate, onFalse: (a: A) => E): (ma: TaskEither) => TaskEither -} = (predicate: Predicate, onFalse: (a: A) => E) => (ma: TaskEither) => - T.chain(ma, (a) => (predicate(a) ? right(a) : left(onFalse(a)))) - -// ------------------------------------------------------------------------------------- -// instances -// ------------------------------------------------------------------------------------- +export function getTaskValidation( + S: Semigroup +): Monad2C & Bifunctor2 & Alt2C & MonadTask2C & MonadThrow2C { + const V = getValidationM(S, T.monadTask) + return { + URI, + _E: undefined as any, + map: map_, + ap: V.ap, + of, + chain: chain_, + bimap: bimap_, + mapLeft: mapLeft_, + alt: V.alt, + fromIO: fromIO_, + fromTask: fromTask_, + throwError: throwError_ + } +} /** - * @internal + * @category instances + * @since 2.1.0 */ -export const monadTaskEither: Monad2 = { - URI, - map: T.map, - of: T.of, - ap: T.ap, - chain: T.chain +export function getFilterable(M: Monoid): Filterable2C { + const W = E.getWitherable(M) + const F = getFilterableComposition(T.monadTask, W) + + return { + URI, + _E: undefined as any, + map: map_, + compact: F.compact, + separate: F.separate, + filter: F.filter, + filterMap: F.filterMap, + partition: F.partition, + partitionMap: F.partitionMap + } } /** @@ -503,16 +563,16 @@ export const monadTaskEither: Monad2 = { */ export const taskEither: Monad2 & Bifunctor2 & Alt2 & MonadTask2 & MonadThrow2 = { URI, - bimap: T.bimap, - mapLeft: T.mapLeft, - map: T.map, - of: T.of, - ap: T.ap, - chain: T.chain, - alt: T.alt, - fromIO: rightIO, - fromTask: rightTask, - throwError: left + bimap: bimap_, + mapLeft: mapLeft_, + map: map_, + of: of, + ap: ap_, + chain: chain_, + alt: alt_, + fromIO: fromIO_, + fromTask: fromTask_, + throwError: throwError_ } /** @@ -521,11 +581,16 @@ export const taskEither: Monad2 & Bifunctor2 & Alt2 & MonadTask2< * @category instances * @since 2.0.0 */ -export const taskEitherSeq: typeof taskEither = - /*#__PURE__*/ - ((): typeof taskEither => { - return { - ...taskEither, - ap: (mab, ma) => T.chain(mab, (f) => T.map(ma, f)) - } - })() +export const taskEitherSeq: typeof taskEither = { + URI, + bimap: bimap_, + mapLeft: mapLeft_, + map: map_, + of, + ap: (mab, ma) => chain_(mab, (f) => map_(ma, f)), + chain: chain_, + alt: alt_, + fromIO: fromIO_, + fromTask: fromTask_, + throwError: throwError_ +} diff --git a/src/TaskThese.ts b/src/TaskThese.ts index 681574546..22ffb2612 100644 --- a/src/TaskThese.ts +++ b/src/TaskThese.ts @@ -1,26 +1,24 @@ /** * @since 2.4.0 */ +import { apComposition } from './Apply' import { Bifunctor2 } from './Bifunctor' +import { flow, pipe } from './function' import { Functor2 } from './Functor' import { IO } from './IO' import { IOEither } from './IOEither' import { Monad2C } from './Monad' import { MonadTask2C } from './MonadTask' import { Semigroup } from './Semigroup' -import { getSemigroup as getTaskSemigroup, Task, monadTask, fromIO as fromIOTask } from './Task' +import * as T from './Task' import * as TH from './These' -import { getTheseM } from './TheseT' -import These = TH.These - -const T = /*#__PURE__*/ getTheseM(monadTask) +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- -declare module './HKT' { - interface URItoKind2 { - readonly TaskThese: TaskThese - } -} +import These = TH.These +import Task = T.Task /** * @category model @@ -34,6 +32,12 @@ export const URI = 'TaskThese' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: TaskThese + } +} + /** * @category model * @since 2.4.0 @@ -44,140 +48,188 @@ export interface TaskThese extends Task> {} * @category constructors * @since 2.4.0 */ -export const left: (e: E) => TaskThese = T.left +export const left: (e: E) => TaskThese = + /*#__PURE__*/ + flow(TH.left, T.of) /** * @category constructors * @since 2.4.0 */ -export const right: (a: A) => TaskThese = T.right +export const right: (a: A) => TaskThese = + /*#__PURE__*/ + flow(TH.right, T.of) /** * @category constructors * @since 2.4.0 */ -export const both: (e: E, a: A) => TaskThese = T.both +export const both: (e: E, a: A) => TaskThese = + /*#__PURE__*/ + flow(TH.both, T.of) /** * @category constructors * @since 2.4.0 */ -export function rightIO(ma: IO): TaskThese { - return rightTask(fromIOTask(ma)) -} +export const rightTask: (ma: Task) => TaskThese = + /*#__PURE__*/ + T.map(TH.right) /** * @category constructors * @since 2.4.0 */ -export function leftIO(me: IO): TaskThese { - return leftTask(fromIOTask(me)) -} +export const leftTask: (me: Task) => TaskThese = + /*#__PURE__*/ + T.map(TH.left) /** * @category constructors * @since 2.4.0 */ -export const leftTask: (me: Task) => TaskThese = T.leftM +export const rightIO: (ma: IO) => TaskThese = + /*#__PURE__*/ + flow(T.fromIO, rightTask) /** * @category constructors * @since 2.4.0 */ -export const rightTask: (ma: Task) => TaskThese = T.rightM +export const leftIO: (me: IO) => TaskThese = + /*#__PURE__*/ + flow(T.fromIO, leftTask) /** * @category constructors * @since 2.4.0 */ -export const fromIOEither: (fa: IOEither) => TaskThese = fromIOTask +export const fromIOEither: (fa: IOEither) => TaskThese = + /*#__PURE__*/ + T.fromIO + +// ------------------------------------------------------------------------------------- +// destructors +// ------------------------------------------------------------------------------------- /** * @category destructors * @since 2.4.0 */ -export function fold( +export const fold: ( onLeft: (e: E) => Task, onRight: (a: A) => Task, onBoth: (e: E, a: A) => Task -): (fa: TaskThese) => Task { - return (fa) => T.fold(fa, onLeft, onRight, onBoth) -} - -/** - * @category combinators - * @since 2.4.0 - */ -export const swap: (fa: TaskThese) => TaskThese = T.swap +) => (fa: TaskThese) => Task = + /*#__PURE__*/ + flow(TH.fold, T.chain) +/* tslint:disable:readonly-array */ /** - * @category instances + * @category destructors * @since 2.4.0 */ -export function getSemigroup(SE: Semigroup, SA: Semigroup): Semigroup> { - return getTaskSemigroup(TH.getSemigroup(SE, SA)) -} +export const toTuple: (e: E, a: A) => (fa: TaskThese) => Task<[E, A]> = + /*#__PURE__*/ + flow(TH.toTuple, T.map) +/* tslint:enable:readonly-array */ -/** - * @category instances - * @since 2.4.0 - */ -export function getMonad(S: Semigroup): Monad2C & MonadTask2C { - return { - URI, - ...T.getMonad(S), - fromIO: rightIO, - fromTask: rightTask - } -} +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- -/* tslint:disable:readonly-array */ /** - * @category destructors + * @category combinators * @since 2.4.0 */ -export function toTuple(e: E, a: A): (fa: TaskThese) => Task<[E, A]> { - return (fa) => T.toTuple(fa, e, a) -} -/* tslint:enable:readonly-array */ +export const swap: (fa: TaskThese) => TaskThese = + /*#__PURE__*/ + T.map(TH.swap) // ------------------------------------------------------------------------------------- // pipeables // ------------------------------------------------------------------------------------- /** - * @category Bifunctor + * @category Functor * @since 2.4.0 */ -export const bimap: (f: (e: E) => G, g: (a: A) => B) => (fa: TaskThese) => TaskThese = ( - f, - g -) => (fa) => T.bimap(fa, f, g) +export const map: (f: (a: A) => B) => (fa: TaskThese) => TaskThese = (f) => T.map(TH.map(f)) /** - * @category Functor + * @category Bifunctor * @since 2.4.0 */ -export const map: (f: (a: A) => B) => (fa: TaskThese) => TaskThese = (f) => (fa) => T.map(fa, f) +export const bimap: (f: (e: E) => G, g: (a: A) => B) => (fa: TaskThese) => TaskThese = (f, g) => + T.map(TH.bimap(f, g)) /** * @category Bifunctor * @since 2.4.0 */ -export const mapLeft: (f: (e: E) => G) => (fa: TaskThese) => TaskThese = (f) => (fa) => - T.mapLeft(fa, f) +export const mapLeft: (f: (e: E) => G) => (fa: TaskThese) => TaskThese = (f) => + T.map(TH.mapLeft(f)) // ------------------------------------------------------------------------------------- // instances // ------------------------------------------------------------------------------------- +const map_: Functor2['map'] = (fa, f) => pipe(fa, map(f)) +/* istanbul ignore next */ +const bimap_: Bifunctor2['bimap'] = (fa, f, g) => pipe(fa, bimap(f, g)) +/* istanbul ignore next */ +const mapLeft_: Bifunctor2['mapLeft'] = (fa, f) => pipe(fa, mapLeft(f)) + +/** + * @category instances + * @since 2.4.0 + */ +export function getSemigroup(SE: Semigroup, SA: Semigroup): Semigroup> { + return T.getSemigroup(TH.getSemigroup(SE, SA)) +} + +/** + * @category instances + * @since 2.4.0 + */ +export function getMonad(S: Semigroup): Monad2C & MonadTask2C { + const ap = apComposition(T.applyTask, TH.getMonad(S)) + return { + URI, + _E: undefined as any, + map: map_, + ap: (fab, fa) => pipe(fab, ap(fa)), + of: right, + chain: (ma, f) => + pipe( + ma, + T.chain( + TH.fold(left, f, (e1, a) => + pipe( + f(a), + T.map( + TH.fold( + (e2) => TH.left(S.concat(e1, e2)), + TH.right, + (e2, b) => TH.both(S.concat(e1, e2), b) + ) + ) + ) + ) + ) + ), + fromIO: rightIO, + fromTask: rightTask + } +} + /** * @category instances * @since 2.4.0 */ export const taskThese: Functor2 & Bifunctor2 = { URI, - map: T.map, - bimap: T.bimap, - mapLeft: T.mapLeft + map: map_, + bimap: bimap_, + mapLeft: mapLeft_ } diff --git a/src/These.ts b/src/These.ts index 395d42f2e..de5041c81 100644 --- a/src/These.ts +++ b/src/These.ts @@ -32,13 +32,7 @@ import { Monoid } from './Monoid' import { isNone, none, Option, some } from './Option' import { Semigroup } from './Semigroup' import { Show } from './Show' -import { Traversable2 } from './Traversable' - -declare module './HKT' { - interface URItoKind2 { - readonly These: These - } -} +import { Traversable2, PipeableTraverse2 } from './Traversable' /** * @category model @@ -52,6 +46,12 @@ export const URI = 'These' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: These + } +} + /** * @category model * @since 2.0.0 @@ -447,6 +447,29 @@ export const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: These(F: Applicative) => (ta: These, f: (a: A) => HKT): HKT> => { + return isLeft(ta) ? F.of(ta) : isRight(ta) ? F.map(f(ta.right), right) : F.map(f(ta.right), (b) => both(ta.left, b)) +} + +/** + * @since 2.6.3 + */ +export const traverse: PipeableTraverse2 = ( + F: Applicative +): ((f: (a: A) => HKT) => (ta: These) => HKT>) => { + const traverseF = traverse_(F) + return (f) => (ta) => traverseF(ta, f) +} + +/** + * @since 2.6.3 + */ +export const sequence: Traversable2['sequence'] = (F: Applicative) => ( + ta: These> +): HKT> => { + return isLeft(ta) ? F.of(ta) : isRight(ta) ? F.map(ta.right, right) : F.map(ta.right, (b) => both(ta.left, b)) +} + /** * @category instances * @since 2.0.0 @@ -459,10 +482,6 @@ export const these: Functor2 & Bifunctor2 & Foldable2 & Traversab reduce: reduce_, foldMap: foldMap_, reduceRight: reduceRight_, - traverse: (F: Applicative) => (ta: These, f: (a: A) => HKT): HKT> => { - return isLeft(ta) ? F.of(ta) : isRight(ta) ? F.map(f(ta.right), right) : F.map(f(ta.right), (b) => both(ta.left, b)) - }, - sequence: (F: Applicative) => (ta: These>): HKT> => { - return isLeft(ta) ? F.of(ta) : isRight(ta) ? F.map(ta.right, right) : F.map(ta.right, (b) => both(ta.left, b)) - } + traverse: traverse_, + sequence } diff --git a/src/Traced.ts b/src/Traced.ts index 20366cead..32eca0dee 100644 --- a/src/Traced.ts +++ b/src/Traced.ts @@ -5,12 +5,6 @@ import { Comonad2C } from './Comonad' import { Functor2 } from './Functor' import { Monoid } from './Monoid' -declare module './HKT' { - interface URItoKind2 { - readonly Traced: Traced - } -} - /** * @category model * @since 2.0.0 @@ -23,6 +17,12 @@ export const URI = 'Traced' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: Traced + } +} + /** * @category model * @since 2.0.0 diff --git a/src/Traversable.ts b/src/Traversable.ts index d4fd2081a..85d0ed4d7 100644 --- a/src/Traversable.ts +++ b/src/Traversable.ts @@ -363,9 +363,12 @@ export function getTraversableComposition( ): TraversableComposition11 export function getTraversableComposition(F: Traversable, G: Traversable): TraversableComposition export function getTraversableComposition(F: Traversable, G: Traversable): TraversableComposition { + const FC = getFoldableComposition(F, G) return { - ...getFunctorComposition(F, G), - ...getFoldableComposition(F, G), + map: getFunctorComposition(F, G).map, + reduce: FC.reduce, + foldMap: FC.foldMap, + reduceRight: FC.reduceRight, traverse: (H) => { const traverseF = F.traverse(H) const traverseG = G.traverse(H) @@ -378,3 +381,46 @@ export function getTraversableComposition(F: Traversable, G: Traversabl } } } + +// +// pipeable `Traverse` +// + +/** + * @since 2.6.3 + */ +export interface PipeableTraverse1 { + (F: Applicative3): ( + f: (a: A) => Kind3 + ) => (ta: Kind) => Kind3> + (F: Applicative3C): ( + f: (a: A) => Kind3 + ) => (ta: Kind) => Kind3> + (F: Applicative2): ( + f: (a: A) => Kind2 + ) => (ta: Kind) => Kind2> + (F: Applicative2C): ( + f: (a: A) => Kind2 + ) => (ta: Kind) => Kind2> + (F: Applicative1): (f: (a: A) => Kind) => (ta: Kind) => Kind> + (F: Applicative): (f: (a: A) => HKT) => (ta: Kind) => HKT> +} + +/** + * @since 2.6.3 + */ +export interface PipeableTraverse2 { + (F: Applicative3): ( + f: (a: A) => Kind3 + ) => (ta: Kind2) => Kind3> + (F: Applicative2): ( + f: (a: A) => Kind2 + ) => (ta: Kind2) => Kind2> + (F: Applicative2C): ( + f: (a: A) => Kind2 + ) => (ta: Kind2) => Kind2> + (F: Applicative1): ( + f: (a: A) => Kind + ) => (ta: Kind2) => Kind> + (F: Applicative): (f: (a: A) => HKT) => (ta: Kind2) => HKT> +} diff --git a/src/TraversableWithIndex.ts b/src/TraversableWithIndex.ts index 8bc81e480..916bab6e6 100644 --- a/src/TraversableWithIndex.ts +++ b/src/TraversableWithIndex.ts @@ -160,3 +160,46 @@ export interface TraverseWithIndex2C { ) => Kind> (F: Applicative): (ta: Kind2, f: (i: I, a: A) => HKT) => HKT> } + +// +// pipeable `TraverseWithIndex` +// + +/** + * @since 2.6.3 + */ +export interface PipeableTraverseWithIndex1 { + (F: Applicative3): ( + f: (i: I, a: A) => Kind3 + ) => (ta: Kind) => Kind3> + (F: Applicative3C): ( + f: (i: I, a: A) => Kind3 + ) => (ta: Kind) => Kind3> + (F: Applicative2): ( + f: (i: I, a: A) => Kind2 + ) => (ta: Kind) => Kind2> + (F: Applicative2C): ( + f: (i: I, a: A) => Kind2 + ) => (ta: Kind) => Kind2> + (F: Applicative1): (f: (i: I, a: A) => Kind) => (ta: Kind) => Kind> + (F: Applicative): (f: (i: I, a: A) => HKT) => (ta: Kind) => HKT> +} + +/** + * @since 2.6.3 + */ +export interface PipeableTraverseWithIndex2 { + (F: Applicative3): ( + f: (i: I, a: A) => Kind3 + ) => (ta: Kind2) => Kind3> + (F: Applicative2): ( + f: (i: I, a: A) => Kind2 + ) => (ta: Kind2) => Kind2> + (F: Applicative2C): ( + f: (i: I, a: A) => Kind2 + ) => (ta: Kind2) => Kind2> + (F: Applicative1): ( + f: (i: I, a: A) => Kind + ) => (ta: Kind2) => Kind> + (F: Applicative): (f: (i: I, a: A) => HKT) => (ta: Kind2) => HKT> +} diff --git a/src/Tree.ts b/src/Tree.ts index e0d607ba4..5465efd31 100644 --- a/src/Tree.ts +++ b/src/Tree.ts @@ -8,25 +8,19 @@ * @since 2.0.0 */ import { Applicative } from './Applicative' -import { array, empty, getEq as getArrayEq, getMonoid } from './Array' +import * as A from './Array' import { Comonad1 } from './Comonad' import { Eq, fromEquals } from './Eq' import { Foldable1 } from './Foldable' -import { identity } from './function' +import { identity, pipe } from './function' import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT' import { Monad, Monad1, Monad2, Monad2C, Monad3, Monad3C } from './Monad' import { Monoid } from './Monoid' import { Show } from './Show' -import { Traversable1 } from './Traversable' +import { Traversable1, PipeableTraverse1 } from './Traversable' // tslint:disable:readonly-array -declare module './HKT' { - interface URItoKind { - readonly Tree: Tree - } -} - /** * @category model * @since 2.0.0 @@ -39,6 +33,12 @@ export const URI = 'Tree' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind { + readonly [URI]: Tree + } +} + /** * @category model * @since 2.0.0 @@ -58,7 +58,7 @@ export interface Tree { * @category constructors * @since 2.0.0 */ -export function make(value: A, forest: Forest = empty): Tree { +export function make(value: A, forest: Forest = A.empty): Tree { return { value, forest @@ -71,7 +71,7 @@ export function make(value: A, forest: Forest = empty): Tree { */ export function getShow(S: Show): Show> { const show = (t: Tree): string => { - return t.forest === empty || t.forest.length === 0 + return t.forest === A.empty || t.forest.length === 0 ? `make(${S.show(t.value)})` : `make(${S.show(t.value)}, [${t.forest.map(show).join(', ')}])` } @@ -87,7 +87,7 @@ export function getShow(S: Show): Show> { export function getEq(E: Eq): Eq> { let SA: Eq>> const R: Eq> = fromEquals((x, y) => E.equals(x.value, y.value) && SA.equals(x.forest, y.forest)) - SA = getArrayEq(R) + SA = A.getEq(R) return R } @@ -214,8 +214,12 @@ export function unfoldForestM( export function unfoldForestM( M: Monad ): (bs: Array, f: (b: B) => HKT]>) => HKT> { - const traverseM = array.traverse(M) - return (bs, f) => traverseM(bs, (b) => unfoldTreeM(M)(b, f)) + const traverseM = A.traverse(M) + return (bs, f) => + pipe( + bs, + traverseM((b) => unfoldTreeM(M)(b, f)) + ) } /** @@ -275,7 +279,7 @@ const ap_: (fab: Tree<(a: A) => B>, fa: Tree) => Tree = (fab, fa) => const chain_ = (fa: Tree, f: (a: A) => Tree): Tree => { const { value, forest } = f(fa.value) - const concat = getMonoid>().concat + const concat = A.getMonoid>().concat return { value, forest: concat( @@ -406,6 +410,42 @@ export const extract: (wa: Tree) => A = (wa) => wa.value // instances // ------------------------------------------------------------------------------------- +const traverse_ = (F: Applicative): ((ta: Tree, f: (a: A) => HKT) => HKT>) => { + const traverseF = A.traverse(F) + const r = (ta: Tree, f: (a: A) => HKT): HKT> => + F.ap( + F.map(f(ta.value), (value: B) => (forest: Forest) => ({ + value, + forest + })), + pipe( + ta.forest, + traverseF((t) => r(t, f)) + ) + ) + return r +} + +/** + * @since 2.6.3 + */ +export const traverse: PipeableTraverse1 = ( + F: Applicative +): ((f: (a: A) => HKT) => (ta: Tree) => HKT>) => { + const traverseF = traverse_(F) + return (f) => (ta) => traverseF(ta, f) +} + +/** + * @since 2.6.3 + */ +export const sequence: Traversable1['sequence'] = ( + F: Applicative +): ((ta: Tree>) => HKT>) => { + const traverseF = traverse_(F) + return (ta) => traverseF(ta, identity) +} + /** * @category instances * @since 2.0.0 @@ -415,29 +455,15 @@ export const tree: Monad1 & Foldable1 & Traversable1 & Comonad1 ({ value: a, - forest: empty + forest: A.empty }), ap: ap_, chain: chain_, reduce: reduce_, foldMap: foldMap_, reduceRight: reduceRight_, - traverse: (F: Applicative): ((ta: Tree, f: (a: A) => HKT) => HKT>) => { - const traverseF = array.traverse(F) - const r = (ta: Tree, f: (a: A) => HKT): HKT> => - F.ap( - F.map(f(ta.value), (value: B) => (forest: Forest) => ({ - value, - forest - })), - traverseF(ta.forest, (t) => r(t, f)) - ) - return r - }, - sequence: (F: Applicative): ((ta: Tree>) => HKT>) => { - const traverseF = tree.traverse(F) - return (ta) => traverseF(ta, identity) - }, + traverse: traverse_, + sequence, extract, extend: extend_ } diff --git a/src/Tuple.ts b/src/Tuple.ts index e8b337615..f540d4c2c 100644 --- a/src/Tuple.ts +++ b/src/Tuple.ts @@ -13,16 +13,10 @@ import { Monoid } from './Monoid' import * as RT from './ReadonlyTuple' import { Semigroup } from './Semigroup' import { Semigroupoid2 } from './Semigroupoid' -import { Traversable2 } from './Traversable' +import { Traversable2, PipeableTraverse2 } from './Traversable' // tslint:disable:readonly-array -declare module './HKT' { - interface URItoKind2 { - readonly Tuple: [A, E] - } -} - /** * @category model * @since 2.0.0 @@ -35,6 +29,12 @@ export const URI = 'Tuple' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: [A, E] + } +} + /** * @category destructors * @since 2.0.0 @@ -151,6 +151,16 @@ export const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: [A, E]) // instances // ------------------------------------------------------------------------------------- +/** + * @since 2.6.3 + */ +export const traverse: PipeableTraverse2 = RT.traverse as any + +/** + * @since 2.6.3 + */ +export const sequence: Traversable2['sequence'] = RT.sequence as any + /** * @category instances * @since 2.0.0 @@ -158,8 +168,5 @@ export const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: [A, E]) export const tuple: Semigroupoid2 & Bifunctor2 & Comonad2 & Foldable2 & Traversable2 = /*#__PURE__*/ (() => { - return { - ...(RT.readonlyTuple as any), - URI - } + return Object.assign({}, RT.readonlyTuple as any, { URI }) })() diff --git a/src/ValidationT.ts b/src/ValidationT.ts index 9f42495af..c3b587b98 100644 --- a/src/ValidationT.ts +++ b/src/ValidationT.ts @@ -64,8 +64,10 @@ export function getValidationM(S: Semigroup, M: Monad): ValidationM< const A = getApplicativeComposition(M, getValidation(S)) return { - ...A, - chain: (ma, f) => M.chain(ma, (e) => (isLeft(e) ? M.of(left(e.left)) : f(e.right))), + map: A.map, + ap: A.ap, + of: A.of, + chain: /* istanbul ignore next */ (ma, f) => M.chain(ma, (e) => (isLeft(e) ? M.of(left(e.left)) : f(e.right))), alt: (fx, f) => M.chain(fx, (e1) => isRight(e1) ? A.of(e1.right) : M.map(f(), (e2) => (isLeft(e2) ? left(S.concat(e1.left, e2.left)) : e2)) diff --git a/src/Writer.ts b/src/Writer.ts index 74ab3915f..4423fe104 100644 --- a/src/Writer.ts +++ b/src/Writer.ts @@ -2,18 +2,13 @@ * @since 2.0.0 */ import { Functor2 } from './Functor' -import { monadIdentity } from './Identity' import { Monad2C } from './Monad' import { Monoid } from './Monoid' -import { getWriterM } from './WriterT' +import { pipe } from './function' -const T = /*#__PURE__*/ getWriterM(monadIdentity) - -declare module './HKT' { - interface URItoKind2 { - readonly Writer: Writer - } -} +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- /** * @category model @@ -27,6 +22,12 @@ export const URI = 'Writer' */ export type URI = typeof URI +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: Writer + } +} + // tslint:disable:readonly-array /** * @category model @@ -37,70 +38,67 @@ export interface Writer { } // tslint:enable:readonly-array -/** - * @since 2.0.0 - */ -export const evalWriter: (fa: Writer) => A = T.evalWriter - -/** - * @since 2.0.0 - */ -export const execWriter: (fa: Writer) => W = T.execWriter +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- /** * Appends a value to the accumulator * + * @category combinators * @since 2.0.0 */ -export const tell: (w: W) => Writer = T.tell +export const tell: (w: W) => Writer = (w) => () => [undefined, w] // tslint:disable:readonly-array /** * Modifies the result to include the changes to the accumulator * + * @category combinators * @since 2.0.0 */ -export const listen: (fa: Writer) => Writer = T.listen +export const listen: (fa: Writer) => Writer = (fa) => () => { + const [a, w] = fa() + return [[a, w], w] +} + // tslint:enable:readonly-array // tslint:disable:readonly-array /** * Applies the returned function to the accumulator * + * @category combinators * @since 2.0.0 */ -export const pass: (fa: Writer W]>) => Writer = T.pass +export const pass: (fa: Writer W]>) => Writer = (fa) => () => { + const [[a, f], w] = fa() + return [a, f(w)] +} // tslint:enable:readonly-array // tslint:disable:readonly-array /** * Projects a value from modifications made to the accumulator during an action * + * @category combinators * @since 2.0.0 */ -export function listens(f: (w: W) => B): (fa: Writer) => Writer { - return (fa) => T.listens(fa, f) +export const listens: (f: (w: W) => B) => (fa: Writer) => Writer = (f) => (fa) => () => { + const [a, w] = fa() + return [[a, f(w)], w] } // tslint:enable:readonly-array /** * Modify the final accumulator value by applying a function * + * @category combinators * @since 2.0.0 */ -export function censor(f: (w: W) => W): (fa: Writer) => Writer { - return (fa) => T.censor(fa, f) -} - -/** - * @category instances - * @since 2.0.0 - */ -export function getMonad(M: Monoid): Monad2C { - return { - URI, - ...T.getMonad(M) - } +export const censor: (f: (w: W) => W) => (fa: Writer) => Writer = (f) => (fa) => () => { + const [a, w] = fa() + return [a, f(w)] } // ------------------------------------------------------------------------------------- @@ -111,17 +109,60 @@ export function getMonad(M: Monoid): Monad2C { * @category Functor * @since 2.0.0 */ -export const map: (f: (a: A) => B) => (fa: Writer) => Writer = (f) => (fa) => T.map(fa, f) +export const map: (f: (a: A) => B) => (fa: Writer) => Writer = (f) => (fa) => () => { + const [a, w] = fa() + return [f(a), w] +} // ------------------------------------------------------------------------------------- // instances // ------------------------------------------------------------------------------------- +/* istanbul ignore next */ +const map_: Functor2['map'] = (fa, f) => pipe(fa, map(f)) + +/** + * @category instances + * @since 2.0.0 + */ +export function getMonad(M: Monoid): Monad2C { + return { + URI, + _E: undefined as any, + map: map_, + ap: (fab, fa) => () => { + const [f, w1] = fab() + const [a, w2] = fa() + return [f(a), M.concat(w1, w2)] + }, + of: (a) => () => [a, M.empty], + chain: (fa, f) => () => { + const [a, w1] = fa() + const [b, w2] = f(a)() + return [b, M.concat(w1, w2)] + } + } +} + /** * @category instances * @since 2.0.0 */ export const writer: Functor2 = { URI, - map: T.map + map: map_ } + +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/** + * @since 2.0.0 + */ +export const evalWriter: (fa: Writer) => A = (fa) => fa()[0] + +/** + * @since 2.0.0 + */ +export const execWriter: (fa: Writer) => W = (fa) => fa()[1] diff --git a/src/function.ts b/src/function.ts index 3e4b493bb..9f33eef1c 100644 --- a/src/function.ts +++ b/src/function.ts @@ -127,7 +127,7 @@ export function flip(f: (a: A, b: B) => C): (b: B, a: A) => C { /** * Performs left-to-right function composition. The first argument may have any arity, the remaining arguments must be unary. * - * See also [`pipe`](https://gcanti.github.io/fp-ts/modules/pipeable.ts.html#pipe). + * See also [`pipe`](#pipe). * * @example * import { flow } from 'fp-ts/lib/function' @@ -301,3 +301,114 @@ export function tupled, B>(f: (...a: A) => B): export function untupled, B>(f: (a: A) => B): (...a: A) => B { return (...a) => f(a) } + +/** + * Pipes the value of an expression into a pipeline of functions. + * + * See also [`flow`](#flow). + * + * @example + * import { pipe } from 'fp-ts/lib/pipeable' + * + * const len = (s: string): number => s.length + * const double = (n: number): number => n * 2 + * + * // without pipe + * assert.strictEqual(double(len('aaa')), 6) + * + * // with pipe + * assert.strictEqual(pipe('aaa', len, double), 6) + * + * @since 2.6.3 + */ +export function pipe(a: A): A +export function pipe(a: A, ab: (a: A) => B): B +export function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C): C +export function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D +export function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): E +export function pipe( + a: A, + ab: (a: A) => B, + bc: (b: B) => C, + cd: (c: C) => D, + de: (d: D) => E, + ef: (e: E) => F +): F +export function pipe( + a: A, + ab: (a: A) => B, + bc: (b: B) => C, + cd: (c: C) => D, + de: (d: D) => E, + ef: (e: E) => F, + fg: (f: F) => G +): G +export function pipe( + a: A, + ab: (a: A) => B, + bc: (b: B) => C, + cd: (c: C) => D, + de: (d: D) => E, + ef: (e: E) => F, + fg: (f: F) => G, + gh: (g: G) => H +): H +export function pipe( + a: A, + ab: (a: A) => B, + bc: (b: B) => C, + cd: (c: C) => D, + de: (d: D) => E, + ef: (e: E) => F, + fg: (f: F) => G, + gh: (g: G) => H, + hi: (h: H) => I +): I +export function pipe( + a: A, + ab: (a: A) => B, + bc: (b: B) => C, + cd: (c: C) => D, + de: (d: D) => E, + ef: (e: E) => F, + fg: (f: F) => G, + gh: (g: G) => H, + hi: (h: H) => I, + ij: (i: I) => J +): J +export function pipe( + a: unknown, + ab?: Function, + bc?: Function, + cd?: Function, + de?: Function, + ef?: Function, + fg?: Function, + gh?: Function, + hi?: Function, + ij?: Function +): unknown { + switch (arguments.length) { + case 1: + return a + case 2: + return ab!(a) + case 3: + return bc!(ab!(a)) + case 4: + return cd!(bc!(ab!(a))) + case 5: + return de!(cd!(bc!(ab!(a)))) + case 6: + return ef!(de!(cd!(bc!(ab!(a))))) + case 7: + return fg!(ef!(de!(cd!(bc!(ab!(a)))))) + case 8: + return gh!(fg!(ef!(de!(cd!(bc!(ab!(a))))))) + case 9: + return hi!(gh!(fg!(ef!(de!(cd!(bc!(ab!(a)))))))) + case 10: + return ij!(hi!(gh!(fg!(ef!(de!(cd!(bc!(ab!(a))))))))) + } + return +} diff --git a/src/pipeable.ts b/src/pipeable.ts index d944474ad..19d4fa986 100644 --- a/src/pipeable.ts +++ b/src/pipeable.ts @@ -56,7 +56,7 @@ import { FoldableWithIndex4, FoldableWithIndex3C } from './FoldableWithIndex' -import { identity, Predicate, Refinement } from './function' +import { identity, pipe as pipeFromFunctionModule, Predicate, Refinement } from './function' import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor4, Functor3C } from './Functor' import { FunctorWithIndex, @@ -90,115 +90,11 @@ import { } from './Semigroupoid' /** - * Pipes the value of an expression into a pipeline of functions. - * - * See also [`flow`](https://gcanti.github.io/fp-ts/modules/function.ts.html#flow). - * - * @example - * import { pipe } from 'fp-ts/lib/pipeable' - * - * const len = (s: string): number => s.length - * const double = (n: number): number => n * 2 - * - * // without pipe - * assert.strictEqual(double(len('aaa')), 6) - * - * // with pipe - * assert.strictEqual(pipe('aaa', len, double), 6) + * Use [`pipe`](https://gcanti.github.io/fp-ts/modules/function.ts.html#flow) from `function` module instead. * * @since 2.0.0 */ -export function pipe(a: A): A -export function pipe(a: A, ab: (a: A) => B): B -export function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C): C -export function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D -export function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): E -export function pipe( - a: A, - ab: (a: A) => B, - bc: (b: B) => C, - cd: (c: C) => D, - de: (d: D) => E, - ef: (e: E) => F -): F -export function pipe( - a: A, - ab: (a: A) => B, - bc: (b: B) => C, - cd: (c: C) => D, - de: (d: D) => E, - ef: (e: E) => F, - fg: (f: F) => G -): G -export function pipe( - a: A, - ab: (a: A) => B, - bc: (b: B) => C, - cd: (c: C) => D, - de: (d: D) => E, - ef: (e: E) => F, - fg: (f: F) => G, - gh: (g: G) => H -): H -export function pipe( - a: A, - ab: (a: A) => B, - bc: (b: B) => C, - cd: (c: C) => D, - de: (d: D) => E, - ef: (e: E) => F, - fg: (f: F) => G, - gh: (g: G) => H, - hi: (h: H) => I -): I -export function pipe( - a: A, - ab: (a: A) => B, - bc: (b: B) => C, - cd: (c: C) => D, - de: (d: D) => E, - ef: (e: E) => F, - fg: (f: F) => G, - gh: (g: G) => H, - hi: (h: H) => I, - ij: (i: I) => J -): J -export function pipe( - a: unknown, - ab?: Function, - bc?: Function, - cd?: Function, - de?: Function, - ef?: Function, - fg?: Function, - gh?: Function, - hi?: Function, - ij?: Function -): unknown { - switch (arguments.length) { - case 1: - return a - case 2: - return ab!(a) - case 3: - return bc!(ab!(a)) - case 4: - return cd!(bc!(ab!(a))) - case 5: - return de!(cd!(bc!(ab!(a)))) - case 6: - return ef!(de!(cd!(bc!(ab!(a))))) - case 7: - return fg!(ef!(de!(cd!(bc!(ab!(a)))))) - case 8: - return gh!(fg!(ef!(de!(cd!(bc!(ab!(a))))))) - case 9: - return hi!(gh!(fg!(ef!(de!(cd!(bc!(ab!(a)))))))) - case 10: - return ij!(hi!(gh!(fg!(ef!(de!(cd!(bc!(ab!(a))))))))) - } - return -} +export const pipe = pipeFromFunctionModule /** * @since 2.0.0 diff --git a/test/Apply.ts b/test/Apply.ts index db75ffc03..2b3647fe6 100644 --- a/test/Apply.ts +++ b/test/Apply.ts @@ -3,7 +3,7 @@ import { sequenceS, sequenceT } from '../src/Apply' import { readonlyArray, getMonoid } from '../src/ReadonlyArray' import { either, getValidation, left, right } from '../src/Either' import { none, option, some } from '../src/Option' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' describe('Apply', () => { it('sequenceT', () => { diff --git a/test/Array.ts b/test/Array.ts index 35a260aa8..0c416f8d3 100644 --- a/test/Array.ts +++ b/test/Array.ts @@ -57,14 +57,17 @@ import { getShow, reverse, getEq, - isNonEmpty + isNonEmpty, + traverseWithIndex, + traverse, + sequence } from '../src/Array' import { left, right } from '../src/Either' import { fold as foldMonoid, monoidSum, monoidString } from '../src/Monoid' import * as O from '../src/Option' import { ord, ordNumber, ordString } from '../src/Ord' import { eq, eqBoolean, eqNumber, eqString, Eq } from '../src/Eq' -import { identity, tuple, Predicate } from '../src/function' +import { identity, tuple, Predicate, pipe } from '../src/function' import * as I from '../src/Identity' import * as C from '../src/Const' import { showString } from '../src/Show' @@ -135,18 +138,14 @@ describe('Array', () => { }) it('traverse', () => { - const tfanone = [1, 2] - const f = (n: number): O.Option => (n % 2 === 0 ? O.none : O.some(n)) - const fasnone = array.traverse(O.option)(tfanone, f) - assert.deepStrictEqual(O.isNone(fasnone), true) - const tfa = [1, 3] - const fas = array.traverse(O.option)(tfa, f) - assert.deepStrictEqual(fas, O.some([1, 3])) + const t = traverse(O.option)((n: number): O.Option => (n % 2 === 0 ? O.none : O.some(n))) + assert.deepStrictEqual(t([1, 2]), O.none) + assert.deepStrictEqual(t([1, 3]), O.some([1, 3])) }) it('sequence', () => { - assert.deepStrictEqual(array.sequence(O.option)([O.some(1), O.some(3)]), O.some([1, 3])) - assert.deepStrictEqual(array.sequence(O.option)([O.some(1), O.none]), O.none) + assert.deepStrictEqual(sequence(O.option)([O.some(1), O.some(3)]), O.some([1, 3])) + assert.deepStrictEqual(sequence(O.option)([O.some(1), O.none]), O.none) }) it('unfold', () => { @@ -802,11 +801,17 @@ describe('Array', () => { it('traverseWithIndex', () => { const ta = ['a', 'bb'] assert.deepStrictEqual( - array.traverseWithIndex(O.option)(ta, (i, s) => (s.length >= 1 ? O.some(s + i) : O.none)), + pipe( + ta, + traverseWithIndex(O.option)((i, s) => (s.length >= 1 ? O.some(s + i) : O.none)) + ), O.some(['a0', 'bb1']) ) assert.deepStrictEqual( - array.traverseWithIndex(O.option)(ta, (i, s) => (s.length > 1 ? O.some(s + i) : O.none)), + pipe( + ta, + traverseWithIndex(O.option)((i, s) => (s.length > 1 ? O.some(s + i) : O.none)) + ), O.none ) @@ -815,13 +820,19 @@ describe('Array', () => { const f = (i: number, s: string): string => s + i assert.deepStrictEqual( array.foldMapWithIndex(M)(ta, f), - array.traverseWithIndex(C.getApplicative(M))(ta, (i, a) => C.make(f(i, a))) + pipe( + ta, + traverseWithIndex(C.getApplicative(M))((i, a) => C.make(f(i, a))) + ) ) // FunctorWithIndex compatibility assert.deepStrictEqual( array.mapWithIndex(ta, f), - array.traverseWithIndex(I.identity)(ta, (i, a) => I.identity.of(f(i, a))) + pipe( + ta, + traverseWithIndex(I.identity)((i, a) => I.identity.of(f(i, a))) + ) ) }) diff --git a/test/Const.ts b/test/Const.ts index d399ce7e2..96e58b29c 100644 --- a/test/Const.ts +++ b/test/Const.ts @@ -4,7 +4,7 @@ import { semigroupString } from '../src/Semigroup' import { eqNumber } from '../src/Eq' import { monoidString } from '../src/Monoid' import { showString } from '../src/Show' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' describe('Const', () => { describe('pipeables', () => { diff --git a/test/Either.ts b/test/Either.ts index c633e536e..06b500098 100644 --- a/test/Either.ts +++ b/test/Either.ts @@ -1,13 +1,12 @@ import * as assert from 'assert' import * as _ from '../src/Either' import { eqNumber, eqString } from '../src/Eq' -import { identity } from '../src/function' +import { identity, pipe } from '../src/function' import * as I from '../src/Identity' import { monoidString, monoidSum } from '../src/Monoid' import { none, option, some } from '../src/Option' import { semigroupSum } from '../src/Semigroup' import { showString } from '../src/Show' -import { pipe } from '../src/pipeable' describe('Either', () => { describe('pipeables', () => { @@ -354,21 +353,30 @@ describe('Either', () => { describe('Traversable', () => { it('traverse', () => { assert.deepStrictEqual( - _.either.traverse(option)(_.left('foo'), (a) => (a >= 2 ? some(a) : none)), + pipe( + _.left('foo'), + _.traverse(option)((a) => (a >= 2 ? some(a) : none)) + ), some(_.left('foo')) ) assert.deepStrictEqual( - _.either.traverse(option)(_.right(1), (a) => (a >= 2 ? some(a) : none)), + pipe( + _.right(1), + _.traverse(option)((a) => (a >= 2 ? some(a) : none)) + ), none ) assert.deepStrictEqual( - _.either.traverse(option)(_.right(3), (a) => (a >= 2 ? some(a) : none)), + pipe( + _.right(3), + _.traverse(option)((a) => (a >= 2 ? some(a) : none)) + ), some(_.right(3)) ) }) it('sequence', () => { - const sequence = _.either.sequence(option) + const sequence = _.sequence(option) assert.deepStrictEqual(sequence(_.right(some('a'))), some(_.right('a'))) assert.deepStrictEqual(sequence(_.left(1)), some(_.left(1))) assert.deepStrictEqual(sequence(_.right(none)), none) diff --git a/test/Eq.ts b/test/Eq.ts index c6f554ca5..086aa2035 100644 --- a/test/Eq.ts +++ b/test/Eq.ts @@ -1,7 +1,7 @@ import * as assert from 'assert' import * as _ from '../src/Eq' import { fold } from '../src/Monoid' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' describe('Eq', () => { describe('pipeables', () => { diff --git a/test/IO.ts b/test/IO.ts index 59edeb0e5..e95496a3d 100644 --- a/test/IO.ts +++ b/test/IO.ts @@ -3,7 +3,7 @@ import * as _ from '../src/IO' import { semigroupSum } from '../src/Semigroup' import { monoidSum } from '../src/Monoid' import * as E from '../src/Either' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' describe('IO', () => { describe('pipeables', () => { diff --git a/test/IOEither.ts b/test/IOEither.ts index 982c7af8f..fd3204151 100644 --- a/test/IOEither.ts +++ b/test/IOEither.ts @@ -1,12 +1,13 @@ import * as assert from 'assert' +import { getMonoid } from '../src/Array' import * as E from '../src/Either' +import { pipe } from '../src/function' import { io } from '../src/IO' import * as _ from '../src/IOEither' import { monoidString } from '../src/Monoid' -import { semigroupSum, semigroupString } from '../src/Semigroup' import { none, some } from '../src/Option' -import { pipe, pipeable } from '../src/pipeable' -import { getMonoid } from '../src/Array' +import { pipeable } from '../src/pipeable' +import { semigroupString, semigroupSum } from '../src/Semigroup' describe('IOEither', () => { describe('pipeables', () => { @@ -149,7 +150,7 @@ describe('IOEither', () => { assert.deepStrictEqual(_.fromOption(() => 'err')(some(1))(), E.right(1)) }) - it('fromOption', () => { + it('fromEither', () => { assert.deepStrictEqual(_.fromEither(E.right('a'))(), E.right('a')) assert.deepStrictEqual(_.fromEither(E.left('a'))(), E.left('a')) }) @@ -174,7 +175,7 @@ describe('IOEither', () => { _.fold( () => io.of('left'), () => io.of('right') - )(_.ioEither.of(1))(), + )(_.right(1))(), 'right' ) assert.deepStrictEqual( @@ -281,18 +282,6 @@ describe('IOEither', () => { describe('getIOValidation', () => { const IV = _.getIOValidation(semigroupString) - it('of', () => { - const e = IV.of(1)() - assert.deepStrictEqual(e, E.right(1)) - }) - - it('map', () => { - const double = (n: number): number => n * 2 - const e1 = IV.map(IV.of(1), double)() - assert.deepStrictEqual(e1, E.right(2)) - const e2 = IV.map(_.left('a'), double)() - assert.deepStrictEqual(e2, E.left('a')) - }) it('ap', () => { const fab = _.left('a') @@ -301,15 +290,6 @@ describe('IOEither', () => { assert.deepStrictEqual(e1, E.left('ab')) }) - it('chain', () => { - const e1 = IV.chain(_.right(3), (a) => (a > 2 ? _.right(a) : _.left('b')))() - assert.deepStrictEqual(e1, E.right(3)) - const e2 = IV.chain(_.right(1), (a) => (a > 2 ? _.right(a) : _.left('b')))() - assert.deepStrictEqual(e2, E.left('b')) - const e3 = IV.chain(_.left('a'), (a) => (a > 2 ? _.right(a) : _.left('b')))() - assert.deepStrictEqual(e3, E.left('a')) - }) - it('alt', () => { const e1 = IV.alt(_.right(1), () => _.right(2))() assert.deepStrictEqual(e1, E.right(1)) diff --git a/test/IORef.ts b/test/IORef.ts index 43edee41f..89475decc 100644 --- a/test/IORef.ts +++ b/test/IORef.ts @@ -1,7 +1,7 @@ import * as assert from 'assert' import { io } from '../src/IO' import { IORef, newIORef } from '../src/IORef' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' describe('IORef', () => { it('read', () => { diff --git a/test/Identity.ts b/test/Identity.ts index f2712ef5a..953b84fa2 100644 --- a/test/Identity.ts +++ b/test/Identity.ts @@ -1,12 +1,11 @@ import * as assert from 'assert' import { left, right } from '../src/Either' -import { identity } from '../src/function' +import { identity, pipe } from '../src/function' import * as _ from '../src/Identity' import { monoidString } from '../src/Monoid' import { none, option, some } from '../src/Option' import { eqNumber } from '../src/Eq' import { showString } from '../src/Show' -import { pipe } from '../src/pipeable' describe('Identity', () => { describe('pipeables', () => { @@ -100,10 +99,14 @@ describe('Identity', () => { }) it('traverse', () => { - const x1 = _.identity.traverse(option)(_.identity.of(1), some) - assert.deepStrictEqual(x1, some(_.identity.of(1))) - const x2 = _.identity.traverse(option)(_.identity.of(1), () => none) - assert.deepStrictEqual(x2, none) + assert.deepStrictEqual(pipe(_.identity.of(1), _.traverse(option)(some)), some(_.identity.of(1))) + assert.deepStrictEqual( + pipe( + _.identity.of(1), + _.traverse(option)(() => none) + ), + none + ) }) it('sequence', () => { diff --git a/test/NonEmptyArray.ts b/test/NonEmptyArray.ts index 0d21081cc..657fcc2fa 100644 --- a/test/NonEmptyArray.ts +++ b/test/NonEmptyArray.ts @@ -1,40 +1,10 @@ import * as assert from 'assert' import * as C from '../src/Const' import { eqNumber } from '../src/Eq' -import { identity } from '../src/function' +import { identity, pipe } from '../src/function' import * as I from '../src/Identity' import * as M from '../src/Monoid' -import { - concat, - cons, - copy, - filter, - filterWithIndex, - fold, - foldMap, - foldMapWithIndex, - fromArray, - getEq, - getSemigroup, - getShow, - group, - groupBy, - groupSort, - head, - init, - insertAt, - last, - max, - min, - modifyAt, - nonEmptyArray, - NonEmptyArray, - reverse, - snoc, - sort, - tail, - updateAt -} from '../src/NonEmptyArray' +import * as _ from '../src/NonEmptyArray' import { isSome, none, option, some } from '../src/Option' import { ordNumber } from '../src/Ord' import { semigroupString, semigroupSum } from '../src/Semigroup' @@ -42,145 +12,156 @@ import { showString } from '../src/Show' describe('NonEmptyArray', () => { it('head', () => { - assert.deepStrictEqual(head([1, 2]), 1) + assert.deepStrictEqual(_.head([1, 2]), 1) }) it('tail', () => { - assert.deepStrictEqual(tail([1, 2]), [2]) + assert.deepStrictEqual(_.tail([1, 2]), [2]) }) it('map', () => { - const double = (n: number) => n * 2 - assert.deepStrictEqual(nonEmptyArray.map([1, 2], double), [2, 4]) + assert.deepStrictEqual( + pipe( + [1, 2], + _.map((n) => n * 2) + ), + [2, 4] + ) }) it('mapWithIndex', () => { const add = (i: number, n: number) => n + i - assert.deepStrictEqual(nonEmptyArray.mapWithIndex([1, 2], add), [1, 3]) + assert.deepStrictEqual(_.nonEmptyArray.mapWithIndex([1, 2], add), [1, 3]) }) it('of', () => { - assert.deepStrictEqual(nonEmptyArray.of(1), [1]) + assert.deepStrictEqual(_.nonEmptyArray.of(1), [1]) }) it('ap', () => { const double = (n: number) => n * 2 - assert.deepStrictEqual(nonEmptyArray.ap([double, double], [1, 2]), [2, 4, 2, 4]) + assert.deepStrictEqual(_.nonEmptyArray.ap([double, double], [1, 2]), [2, 4, 2, 4]) }) it('chain', () => { - const f = (a: number): NonEmptyArray => [a, 4] - assert.deepStrictEqual(nonEmptyArray.chain([1, 2], f), [1, 4, 2, 4]) + const f = (a: number): _.NonEmptyArray => [a, 4] + assert.deepStrictEqual(_.nonEmptyArray.chain([1, 2], f), [1, 4, 2, 4]) }) it('extend', () => { - const sum = fold(M.monoidSum) - assert.deepStrictEqual(nonEmptyArray.extend([1, 2, 3, 4], sum), [10, 9, 7, 4]) + const sum = _.fold(M.monoidSum) + assert.deepStrictEqual(_.nonEmptyArray.extend([1, 2, 3, 4], sum), [10, 9, 7, 4]) }) it('extract', () => { - assert.deepStrictEqual(nonEmptyArray.extract([1, 2, 3]), 1) + assert.deepStrictEqual(_.nonEmptyArray.extract([1, 2, 3]), 1) }) it('traverse', () => { assert.deepStrictEqual( - nonEmptyArray.traverse(option)([1, 2, 3], (n) => (n >= 0 ? some(n) : none)), + pipe( + [1, 2, 3], + _.traverse(option)((n) => (n >= 0 ? some(n) : none)) + ), some([1, 2, 3]) ) assert.deepStrictEqual( - nonEmptyArray.traverse(option)([1, 2, 3], (n) => (n >= 2 ? some(n) : none)), + pipe( + [1, 2, 3], + _.traverse(option)((n) => (n >= 2 ? some(n) : none)) + ), none ) }) it('sequence', () => { - const sequence = nonEmptyArray.sequence(option) + const sequence = _.sequence(option) assert.deepStrictEqual(sequence([some(1), some(2), some(3)]), some([1, 2, 3])) assert.deepStrictEqual(sequence([none, some(2), some(3)]), none) }) it('min', () => { - assert.deepStrictEqual(min(ordNumber)([2, 1, 3]), 1) - assert.deepStrictEqual(min(ordNumber)([3]), 3) + assert.deepStrictEqual(_.min(ordNumber)([2, 1, 3]), 1) + assert.deepStrictEqual(_.min(ordNumber)([3]), 3) }) it('max', () => { - assert.deepStrictEqual(max(ordNumber)([1, 2, 3]), 3) - assert.deepStrictEqual(max(ordNumber)([1]), 1) + assert.deepStrictEqual(_.max(ordNumber)([1, 2, 3]), 3) + assert.deepStrictEqual(_.max(ordNumber)([1]), 1) }) it('reduce', () => { assert.deepStrictEqual( - nonEmptyArray.reduce(['a', 'b'], '', (b, a) => b + a), + _.nonEmptyArray.reduce(['a', 'b'], '', (b, a) => b + a), 'ab' ) }) it('foldMap', () => { - const foldMap = nonEmptyArray.foldMap(M.monoidString) + const foldMap = _.nonEmptyArray.foldMap(M.monoidString) assert.deepStrictEqual(foldMap(['a', 'b', 'c'], identity), 'abc') }) it('reduceRight', () => { - const reduceRight = nonEmptyArray.reduceRight + const reduceRight = _.nonEmptyArray.reduceRight const init1 = '' const f = (a: string, acc: string) => acc + a assert.deepStrictEqual(reduceRight(['a', 'b', 'c'], init1, f), 'cba') }) it('fromArray', () => { - assert.deepStrictEqual(fromArray([]), none) - assert.deepStrictEqual(fromArray([1]), some([1])) - assert.deepStrictEqual(fromArray([1, 2]), some([1, 2])) + assert.deepStrictEqual(_.fromArray([]), none) + assert.deepStrictEqual(_.fromArray([1]), some([1])) + assert.deepStrictEqual(_.fromArray([1, 2]), some([1, 2])) }) it('getSemigroup', () => { - const S = getSemigroup() + const S = _.getSemigroup() assert.deepStrictEqual(S.concat([1], [2]), [1, 2]) assert.deepStrictEqual(S.concat([1, 2], [3, 4]), [1, 2, 3, 4]) }) it('getEq', () => { - const S = getEq(eqNumber) + const S = _.getEq(eqNumber) assert.deepStrictEqual(S.equals([1], [1]), true) assert.deepStrictEqual(S.equals([1], [1, 2]), false) }) it('group', () => { - assert.deepStrictEqual(group(ordNumber)([]), []) + assert.deepStrictEqual(_.group(ordNumber)([]), []) - assert.deepStrictEqual(group(ordNumber)([1, 2, 1, 1]), [[1], [2], [1, 1]]) + assert.deepStrictEqual(_.group(ordNumber)([1, 2, 1, 1]), [[1], [2], [1, 1]]) - assert.deepStrictEqual(group(ordNumber)([1, 2, 1, 1, 3]), [[1], [2], [1, 1], [3]]) + assert.deepStrictEqual(_.group(ordNumber)([1, 2, 1, 1, 3]), [[1], [2], [1, 1], [3]]) }) it('groupSort', () => { - assert.deepStrictEqual(groupSort(ordNumber)([]), []) - assert.deepStrictEqual(groupSort(ordNumber)([1, 2, 1, 1]), [[1, 1, 1], [2]]) + assert.deepStrictEqual(_.groupSort(ordNumber)([]), []) + assert.deepStrictEqual(_.groupSort(ordNumber)([1, 2, 1, 1]), [[1, 1, 1], [2]]) }) it('last', () => { - assert.deepStrictEqual(last([1, 2, 3]), 3) - assert.deepStrictEqual(last([1]), 1) + assert.deepStrictEqual(_.last([1, 2, 3]), 3) + assert.deepStrictEqual(_.last([1]), 1) }) it('init', () => { - assert.deepStrictEqual(init([1, 2, 3]), [1, 2]) - assert.deepStrictEqual(init([1]), []) + assert.deepStrictEqual(_.init([1, 2, 3]), [1, 2]) + assert.deepStrictEqual(_.init([1]), []) }) it('sort', () => { - assert.deepStrictEqual(sort(ordNumber)([3, 2, 1]), [1, 2, 3]) + assert.deepStrictEqual(_.sort(ordNumber)([3, 2, 1]), [1, 2, 3]) }) it('reverse', () => { - assert.deepStrictEqual(reverse([1, 2, 3]), [3, 2, 1]) + assert.deepStrictEqual(_.reverse([1, 2, 3]), [3, 2, 1]) }) it('groupBy', () => { - assert.deepStrictEqual(groupBy((_) => '')([]), {}) - assert.deepStrictEqual(groupBy(String)([1]), { '1': [1] }) - assert.deepStrictEqual(groupBy((s: string) => String(s.length))(['foo', 'bar', 'foobar']), { + assert.deepStrictEqual(_.groupBy((_) => '')([]), {}) + assert.deepStrictEqual(_.groupBy(String)([1]), { '1': [1] }) + assert.deepStrictEqual(_.groupBy((s: string) => String(s.length))(['foo', 'bar', 'foobar']), { '3': ['foo', 'bar'], '6': ['foobar'] }) @@ -192,11 +173,11 @@ describe('NonEmptyArray', () => { const a2 = make(1) const a3 = make(2) const a4 = make(3) - assert.deepStrictEqual(insertAt(0, a4)([a1, a2, a3]), some([a4, a1, a2, a3])) - assert.deepStrictEqual(insertAt(-1, a4)([a1, a2, a3]), none) - assert.deepStrictEqual(insertAt(3, a4)([a1, a2, a3]), some([a1, a2, a3, a4])) - assert.deepStrictEqual(insertAt(1, a4)([a1, a2, a3]), some([a1, a4, a2, a3])) - assert.deepStrictEqual(insertAt(4, a4)([a1, a2, a3]), none) + assert.deepStrictEqual(_.insertAt(0, a4)([a1, a2, a3]), some([a4, a1, a2, a3])) + assert.deepStrictEqual(_.insertAt(-1, a4)([a1, a2, a3]), none) + assert.deepStrictEqual(_.insertAt(3, a4)([a1, a2, a3]), some([a1, a2, a3, a4])) + assert.deepStrictEqual(_.insertAt(1, a4)([a1, a2, a3]), some([a1, a4, a2, a3])) + assert.deepStrictEqual(_.insertAt(4, a4)([a1, a2, a3]), none) }) it('updateAt', () => { @@ -205,19 +186,19 @@ describe('NonEmptyArray', () => { const a2 = make2(1) const a3 = make2(2) const a4 = make2(3) - const arr: NonEmptyArray<{ readonly x: number }> = [a1, a2, a3] - assert.deepStrictEqual(updateAt(0, a4)(arr), some([a4, a2, a3])) - assert.deepStrictEqual(updateAt(-1, a4)(arr), none) - assert.deepStrictEqual(updateAt(3, a4)(arr), none) - assert.deepStrictEqual(updateAt(1, a4)(arr), some([a1, a4, a3])) + const arr: _.NonEmptyArray<{ readonly x: number }> = [a1, a2, a3] + assert.deepStrictEqual(_.updateAt(0, a4)(arr), some([a4, a2, a3])) + assert.deepStrictEqual(_.updateAt(-1, a4)(arr), none) + assert.deepStrictEqual(_.updateAt(3, a4)(arr), none) + assert.deepStrictEqual(_.updateAt(1, a4)(arr), some([a1, a4, a3])) // should return the same reference if nothing changed - const r1 = updateAt(0, a1)(arr) + const r1 = _.updateAt(0, a1)(arr) if (isSome(r1)) { assert.deepStrictEqual(r1.value, arr) } else { assert.fail('is not a Some') } - const r2 = updateAt(2, a3)(arr) + const r2 = _.updateAt(2, a3)(arr) if (isSome(r2)) { assert.deepStrictEqual(r2.value, arr) } else { @@ -227,13 +208,13 @@ describe('NonEmptyArray', () => { it('modifyAt', () => { const double = (n: number): number => n * 2 - assert.deepStrictEqual(modifyAt(1, double)(cons(1, [])), none) - assert.deepStrictEqual(modifyAt(1, double)(cons(1, [2])), some(cons(1, [4]))) + assert.deepStrictEqual(_.modifyAt(1, double)(_.cons(1, [])), none) + assert.deepStrictEqual(_.modifyAt(1, double)(_.cons(1, [2])), some(_.cons(1, [4]))) }) it('copy', () => { - const nea1 = cons(1, []) - const nea2 = copy(nea1) + const nea1 = _.cons(1, []) + const nea2 = _.copy(nea1) assert.deepStrictEqual(nea2, nea1) assert.deepStrictEqual(nea2 === nea1, false) }) @@ -243,109 +224,121 @@ describe('NonEmptyArray', () => { const a1 = make(1) const a2 = make(1) const a3 = make(2) - assert.deepStrictEqual(filter(({ x }) => x !== 1)([a1, a2, a3]), some([a3])) - assert.deepStrictEqual(filter(({ x }) => x !== 2)([a1, a2, a3]), some([a1, a2])) + assert.deepStrictEqual(_.filter(({ x }) => x !== 1)([a1, a2, a3]), some([a3])) + assert.deepStrictEqual(_.filter(({ x }) => x !== 2)([a1, a2, a3]), some([a1, a2])) assert.deepStrictEqual( - filter(({ x }) => { + _.filter(({ x }) => { return !(x === 1 || x === 2) })([a1, a2, a3]), none ) - assert.deepStrictEqual(filter(({ x }) => x !== 10)([a1, a2, a3]), some([a1, a2, a3])) + assert.deepStrictEqual(_.filter(({ x }) => x !== 10)([a1, a2, a3]), some([a1, a2, a3])) // refinements - const actual1 = filter(isSome)([some(3), some(2), some(1)]) + const actual1 = _.filter(isSome)([some(3), some(2), some(1)]) assert.deepStrictEqual(actual1, some([some(3), some(2), some(1)])) - const actual2 = filter(isSome)([some(3), none, some(1)]) + const actual2 = _.filter(isSome)([some(3), none, some(1)]) assert.deepStrictEqual(actual2, some([some(3), some(1)])) }) it('filterWithIndex', () => { - assert.deepStrictEqual(filterWithIndex((i) => i % 2 === 0)([1, 2, 3]), some([1, 3])) - assert.deepStrictEqual(filterWithIndex((i, a: number) => i % 2 === 1 && a > 2)([1, 2, 3]), none) + assert.deepStrictEqual(_.filterWithIndex((i) => i % 2 === 0)([1, 2, 3]), some([1, 3])) + assert.deepStrictEqual(_.filterWithIndex((i, a: number) => i % 2 === 1 && a > 2)([1, 2, 3]), none) }) it('reduceWithIndex', () => { assert.deepStrictEqual( - nonEmptyArray.reduceWithIndex(['a', 'b'], '', (i, b, a) => b + i + a), + _.nonEmptyArray.reduceWithIndex(['a', 'b'], '', (i, b, a) => b + i + a), '0a1b' ) }) it('foldMapWithIndex', () => { assert.deepStrictEqual( - nonEmptyArray.foldMapWithIndex(M.monoidString)(['a', 'b'], (i, a) => i + a), + _.nonEmptyArray.foldMapWithIndex(M.monoidString)(['a', 'b'], (i, a) => i + a), '0a1b' ) }) it('reduceRightWithIndex', () => { assert.deepStrictEqual( - nonEmptyArray.reduceRightWithIndex(['a', 'b'], '', (i, a, b) => b + i + a), + _.nonEmptyArray.reduceRightWithIndex(['a', 'b'], '', (i, a, b) => b + i + a), '1b0a' ) }) it('traverseWithIndex', () => { assert.deepStrictEqual( - nonEmptyArray.traverseWithIndex(option)(['a', 'bb'], (i, s) => (s.length >= 1 ? some(s + i) : none)), + pipe( + ['a', 'bb'], + _.traverseWithIndex(option)((i, s) => (s.length >= 1 ? some(s + i) : none)) + ), some(['a0', 'bb1']) ) assert.deepStrictEqual( - nonEmptyArray.traverseWithIndex(option)(['a', 'bb'], (i, s) => (s.length > 1 ? some(s + i) : none)), + pipe( + ['a', 'bb'], + _.traverseWithIndex(option)((i, s) => (s.length > 1 ? some(s + i) : none)) + ), none ) // FoldableWithIndex compatibility const f = (i: number, s: string): string => s + i assert.deepStrictEqual( - nonEmptyArray.foldMapWithIndex(M.monoidString)(['a', 'bb'], f), - nonEmptyArray.traverseWithIndex(C.getApplicative(M.monoidString))(['a', 'bb'], (i, a) => C.make(f(i, a))) + _.nonEmptyArray.foldMapWithIndex(M.monoidString)(['a', 'bb'], f), + pipe( + ['a', 'bb'], + _.traverseWithIndex(C.getApplicative(M.monoidString))((i, a) => C.make(f(i, a))) + ) ) // FunctorWithIndex compatibility assert.deepStrictEqual( - nonEmptyArray.mapWithIndex(['a', 'bb'], f), - nonEmptyArray.traverseWithIndex(I.identity)(['a', 'bb'], (i, a) => I.identity.of(f(i, a))) + _.nonEmptyArray.mapWithIndex(['a', 'bb'], f), + pipe( + ['a', 'bb'], + _.traverseWithIndex(I.identity)((i, a) => I.identity.of(f(i, a))) + ) ) }) it('cons', () => { - assert.deepStrictEqual(cons(1, [2, 3, 4]), [1, 2, 3, 4]) + assert.deepStrictEqual(_.cons(1, [2, 3, 4]), [1, 2, 3, 4]) }) it('snoc', () => { - assert.deepStrictEqual(snoc([1, 2, 3], 4), [1, 2, 3, 4]) + assert.deepStrictEqual(_.snoc([1, 2, 3], 4), [1, 2, 3, 4]) }) it('getShow', () => { - const S = getShow(showString) + const S = _.getShow(showString) assert.deepStrictEqual(S.show(['a']), `["a"]`) assert.deepStrictEqual(S.show(['a', 'b', 'c']), `["a", "b", "c"]`) }) it('alt / concat', () => { - assert.deepStrictEqual(concat(['a'], []), ['a']) + assert.deepStrictEqual(_.concat(['a'], []), ['a']) assert.deepStrictEqual( - nonEmptyArray.alt(['a'], () => ['b']), + _.nonEmptyArray.alt(['a'], () => ['b']), ['a', 'b'] ) }) it('foldMap', () => { - const f = foldMap(semigroupSum)((s: string) => s.length) + const f = _.foldMap(semigroupSum)((s: string) => s.length) assert.deepStrictEqual(f(['a']), 1) assert.deepStrictEqual(f(['a', 'bb']), 3) }) it('foldMapWithIndex', () => { - const f = foldMapWithIndex(semigroupSum)((i: number, s: string) => s.length + i) + const f = _.foldMapWithIndex(semigroupSum)((i: number, s: string) => s.length + i) assert.deepStrictEqual(f(['a']), 1) assert.deepStrictEqual(f(['a', 'bb']), 4) }) it('fold', () => { - const f = fold(semigroupString) + const f = _.fold(semigroupString) assert.deepStrictEqual(f(['a']), 'a') assert.deepStrictEqual(f(['a', 'bb']), 'abb') }) diff --git a/test/Option.ts b/test/Option.ts index f50ac5741..f0503bc7a 100644 --- a/test/Option.ts +++ b/test/Option.ts @@ -2,14 +2,13 @@ import * as assert from 'assert' import { array } from '../src/Array' import { left, right } from '../src/Either' import { eqNumber } from '../src/Eq' -import { identity } from '../src/function' +import { identity, pipe } from '../src/function' import * as I from '../src/Identity' import { monoidString, monoidSum } from '../src/Monoid' import * as _ from '../src/Option' import { ordString } from '../src/Ord' import { semigroupString, semigroupSum } from '../src/Semigroup' import { showString } from '../src/Show' -import { pipe } from '../src/pipeable' const p = (n: number): boolean => n > 2 @@ -308,15 +307,24 @@ describe('Option', () => { describe('Traversable', () => { it('traverse', () => { assert.deepStrictEqual( - _.option.traverse(array)(_.some('hello'), () => []), + pipe( + _.some('hello'), + _.traverse(array)(() => []) + ), [] ) assert.deepStrictEqual( - _.option.traverse(array)(_.some('hello'), (s) => [s.length]), + pipe( + _.some('hello'), + _.traverse(array)((s) => [s.length]) + ), [_.some(5)] ) assert.deepStrictEqual( - _.option.traverse(array)(_.none, (s) => [s]), + pipe( + _.none, + _.traverse(array)((s) => [s]) + ), [_.none] ) }) diff --git a/test/Ord.ts b/test/Ord.ts index c0074d030..3f23d1be0 100644 --- a/test/Ord.ts +++ b/test/Ord.ts @@ -2,7 +2,7 @@ import * as assert from 'assert' import { sort } from '../src/ReadonlyArray' import * as _ from '../src/Ord' import { fold } from '../src/Monoid' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' describe('Ord', () => { it('getTupleOrd', () => { diff --git a/test/Reader.ts b/test/Reader.ts index 45ac54f29..fa5c0d0fc 100644 --- a/test/Reader.ts +++ b/test/Reader.ts @@ -2,7 +2,7 @@ import * as assert from 'assert' import * as _ from '../src/Reader' import { semigroupSum } from '../src/Semigroup' import { monoidSum } from '../src/Monoid' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' interface Env { readonly count: number diff --git a/test/ReaderEither.ts b/test/ReaderEither.ts index 2a12ddd0d..e4dba74c7 100644 --- a/test/ReaderEither.ts +++ b/test/ReaderEither.ts @@ -2,7 +2,7 @@ import * as assert from 'assert' import * as E from '../src/Either' import { monoidString } from '../src/Monoid' import { none, some } from '../src/Option' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' import { reader } from '../src/Reader' import * as _ from '../src/ReaderEither' import { semigroupSum, semigroupString } from '../src/Semigroup' diff --git a/test/ReaderTask.ts b/test/ReaderTask.ts index 533d1915b..3cf820594 100644 --- a/test/ReaderTask.ts +++ b/test/ReaderTask.ts @@ -1,6 +1,6 @@ import * as assert from 'assert' -import { array } from '../src/Array' -import { pipe } from '../src/pipeable' +import * as A from '../src/Array' +import { pipe } from '../src/function' import { reader } from '../src/Reader' import * as _ from '../src/ReaderTask' import * as T from '../src/Task' @@ -114,7 +114,7 @@ describe('ReaderTask', () => { const append = (message: string): _.ReaderTask<{}, number> => _.fromTask(() => Promise.resolve(log.push(message))) const t1 = _.readerTask.chain(append('start 1'), () => append('end 1')) const t2 = _.readerTask.chain(append('start 2'), () => append('end 2')) - const sequenceParallel = array.sequence(_.readerTask) + const sequenceParallel = A.sequence(_.readerTask) const ns = await sequenceParallel([t1, t2])({})() assert.deepStrictEqual(ns, [3, 4]) assert.deepStrictEqual(log, ['start 1', 'start 2', 'end 1', 'end 2']) @@ -126,7 +126,7 @@ describe('ReaderTask', () => { const append = (message: string): _.ReaderTask<{}, number> => _.fromTask(() => Promise.resolve(log.push(message))) const t1 = _.readerTask.chain(append('start 1'), () => append('end 1')) const t2 = _.readerTask.chain(append('start 2'), () => append('end 2')) - const sequenceSeries = array.sequence(_.readerTaskSeq) + const sequenceSeries = A.sequence(_.readerTaskSeq) const ns = await sequenceSeries([t1, t2])({})() assert.deepStrictEqual(ns, [2, 4]) assert.deepStrictEqual(log, ['start 1', 'end 1', 'start 2', 'end 2']) @@ -150,4 +150,16 @@ describe('ReaderTask', () => { const x = await _.run(pipe(_.of('a'), _.chainTaskK(f)), undefined) assert.deepStrictEqual(x, 1) }) + + it('fromIOK', async () => { + const f = _.fromIOK((s: string) => I.of(s.length)) + const x = await pipe(_.of('a'), _.chain(f))({})() + assert.deepStrictEqual(x, 1) + }) + + it('fromTaskK', async () => { + const f = _.fromTaskK((s: string) => T.of(s.length)) + const x = await pipe(_.of('a'), _.chain(f))({})() + assert.deepStrictEqual(x, 1) + }) }) diff --git a/test/ReaderTaskEither.ts b/test/ReaderTaskEither.ts index 0a6c0473b..88cb80711 100644 --- a/test/ReaderTaskEither.ts +++ b/test/ReaderTaskEither.ts @@ -1,11 +1,11 @@ import * as assert from 'assert' -import { array } from '../src/Array' +import * as A 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 { pipe } from '../src/function' import { reader } from '../src/Reader' import * as RE from '../src/ReaderEither' import * as _ from '../src/ReaderTaskEither' @@ -285,7 +285,7 @@ describe('ReaderTaskEither', () => { _.rightTask(() => Promise.resolve(log.push(message))) const t1 = _.readerTaskEither.chain(append('start 1'), () => append('end 1')) const t2 = _.readerTaskEither.chain(append('start 2'), () => append('end 2')) - const sequenceParallel = array.sequence(_.readerTaskEither) + const sequenceParallel = A.sequence(_.readerTaskEither) const ns = await _.run(sequenceParallel([t1, t2]), {}) assert.deepStrictEqual(ns, E.right([3, 4])) assert.deepStrictEqual(log, ['start 1', 'start 2', 'end 1', 'end 2']) @@ -298,7 +298,7 @@ describe('ReaderTaskEither', () => { _.rightTask(() => Promise.resolve(log.push(message))) const t1 = _.readerTaskEither.chain(append('start 1'), () => append('end 1')) const t2 = _.readerTaskEither.chain(append('start 2'), () => append('end 2')) - const sequenceSeries = array.sequence(_.readerTaskEitherSeq) + const sequenceSeries = A.sequence(_.readerTaskEitherSeq) const ns = await _.run(sequenceSeries([t1, t2]), {}) assert.deepStrictEqual(ns, E.right([2, 4])) assert.deepStrictEqual(log, ['start 1', 'end 1', 'start 2', 'end 2']) @@ -382,11 +382,17 @@ describe('ReaderTaskEither', () => { }) it('traverse', async () => { - const e1 = await array.traverse(RTV)([1, 2, 3], RTV.of)({})() + const e1 = await pipe([1, 2, 3], A.traverse(RTV)(RTV.of))({})() assert.deepStrictEqual(e1, E.right([1, 2, 3])) - const e2 = await array.traverse(RTV)([1, 2, 3], (v) => RTV.throwError(`${v}`))({})() + const e2 = await pipe( + [1, 2, 3], + A.traverse(RTV)((v) => RTV.throwError(`${v}`)) + )({})() assert.deepStrictEqual(e2, E.left('123')) - const e3 = await array.traverse(RTV)([1, 2, 3], (v) => (v % 2 === 1 ? RTV.throwError(`${v}`) : RTV.of(v)))({})() + const e3 = await pipe( + [1, 2, 3], + A.traverse(RTV)((v) => (v % 2 === 1 ? RTV.throwError(`${v}`) : RTV.of(v))) + )({})() assert.deepStrictEqual(e3, E.left('13')) }) }) diff --git a/test/ReadonlyArray.ts b/test/ReadonlyArray.ts index a282fb917..a00fa30f2 100644 --- a/test/ReadonlyArray.ts +++ b/test/ReadonlyArray.ts @@ -11,23 +11,20 @@ import * as O from '../src/Option' import * as Ord from '../src/Ord' import * as _ from '../src/ReadonlyArray' import { showString } from '../src/Show' -import { pipe } from '../src/pipeable' describe('ReadonlyArray', () => { describe('instances', () => { it('traverse', () => { - const tfanone: ReadonlyArray = [1, 2] - const f = (n: number): O.Option => (n % 2 === 0 ? O.none : O.some(n)) - const fasnone = _.readonlyArray.traverse(O.option)(tfanone, f) - assert.deepStrictEqual(O.isNone(fasnone), true) - const tfa: ReadonlyArray = [1, 3] - const fas = _.readonlyArray.traverse(O.option)(tfa, f) - assert.deepStrictEqual(fas, O.some([1, 3])) + const traverse = _.traverse(O.applicativeOption)( + (n: number): O.Option => (n % 2 === 0 ? O.none : O.some(n)) + ) + assert.deepStrictEqual(traverse([1, 2]), O.none) + assert.deepStrictEqual(traverse([1, 3]), O.some([1, 3])) }) it('sequence', () => { - assert.deepStrictEqual(_.readonlyArray.sequence(O.option)([O.some(1), O.some(3)]), O.some([1, 3])) - assert.deepStrictEqual(_.readonlyArray.sequence(O.option)([O.some(1), O.none]), O.none) + assert.deepStrictEqual(_.sequence(O.option)([O.some(1), O.some(3)]), O.some([1, 3])) + assert.deepStrictEqual(_.sequence(O.option)([O.some(1), O.none]), O.none) }) it('unfold', () => { @@ -53,7 +50,7 @@ describe('ReadonlyArray', () => { describe('pipeables', () => { it('map', () => { assert.deepStrictEqual( - pipe( + F.pipe( [1, 2, 3], _.map((n) => n * 2) ), @@ -63,7 +60,7 @@ describe('ReadonlyArray', () => { it('mapWithIndex', () => { assert.deepStrictEqual( - pipe( + F.pipe( [1, 2, 3], _.mapWithIndex((i, n) => n + i) ), @@ -73,7 +70,7 @@ describe('ReadonlyArray', () => { it('alt', () => { assert.deepStrictEqual( - pipe( + F.pipe( [1, 2], _.alt(() => [3, 4]) ), @@ -82,20 +79,20 @@ describe('ReadonlyArray', () => { }) it('ap', () => { - assert.deepStrictEqual(pipe([(x: number) => x * 2, (x: number) => x * 3], _.ap([1, 2, 3])), [2, 4, 6, 3, 6, 9]) + assert.deepStrictEqual(F.pipe([(x: number) => x * 2, (x: number) => x * 3], _.ap([1, 2, 3])), [2, 4, 6, 3, 6, 9]) }) it('apFirst', () => { - assert.deepStrictEqual(pipe([1, 2], _.apFirst(['a', 'b', 'c'])), [1, 1, 1, 2, 2, 2]) + assert.deepStrictEqual(F.pipe([1, 2], _.apFirst(['a', 'b', 'c'])), [1, 1, 1, 2, 2, 2]) }) it('apSecond', () => { - assert.deepStrictEqual(pipe([1, 2], _.apSecond(['a', 'b', 'c'])), ['a', 'b', 'c', 'a', 'b', 'c']) + assert.deepStrictEqual(F.pipe([1, 2], _.apSecond(['a', 'b', 'c'])), ['a', 'b', 'c', 'a', 'b', 'c']) }) it('chain', () => { assert.deepStrictEqual( - pipe( + F.pipe( [1, 2, 3], _.chain((n) => [n, n + 1]) ), @@ -105,7 +102,7 @@ describe('ReadonlyArray', () => { it('chainFirst', () => { assert.deepStrictEqual( - pipe( + F.pipe( [1, 2, 3], _.chainFirst((n) => [n, n + 1]) ), @@ -115,13 +112,13 @@ describe('ReadonlyArray', () => { it('extend', () => { const sum = (as: ReadonlyArray) => M.fold(M.monoidSum)(as) - assert.deepStrictEqual(pipe([1, 2, 3, 4], _.extend(sum)), [10, 9, 7, 4]) - assert.deepStrictEqual(pipe([1, 2, 3, 4], _.extend(F.identity)), [[1, 2, 3, 4], [2, 3, 4], [3, 4], [4]]) + assert.deepStrictEqual(F.pipe([1, 2, 3, 4], _.extend(sum)), [10, 9, 7, 4]) + assert.deepStrictEqual(F.pipe([1, 2, 3, 4], _.extend(F.identity)), [[1, 2, 3, 4], [2, 3, 4], [3, 4], [4]]) }) it('foldMap', () => { - assert.deepStrictEqual(pipe(['a', 'b', 'c'], _.foldMap(M.monoidString)(F.identity)), 'abc') - assert.deepStrictEqual(pipe([], _.foldMap(M.monoidString)(F.identity)), '') + assert.deepStrictEqual(F.pipe(['a', 'b', 'c'], _.foldMap(M.monoidString)(F.identity)), 'abc') + assert.deepStrictEqual(F.pipe([], _.foldMap(M.monoidString)(F.identity)), '') }) it('compact', () => { @@ -137,28 +134,28 @@ describe('ReadonlyArray', () => { it('filter', () => { const g = (n: number) => n % 2 === 1 - assert.deepStrictEqual(pipe([1, 2, 3], _.filter(g)), [1, 3]) + assert.deepStrictEqual(F.pipe([1, 2, 3], _.filter(g)), [1, 3]) assert.deepStrictEqual(_.readonlyArray.filter([1, 2, 3], g), [1, 3]) - const x = pipe([O.some(3), O.some(2), O.some(1)], _.filter(O.isSome)) + const x = F.pipe([O.some(3), O.some(2), O.some(1)], _.filter(O.isSome)) assert.deepStrictEqual(x, [O.some(3), O.some(2), O.some(1)]) - const y = pipe([O.some(3), O.none, O.some(1)], _.filter(O.isSome)) + const y = F.pipe([O.some(3), O.none, O.some(1)], _.filter(O.isSome)) assert.deepStrictEqual(y, [O.some(3), O.some(1)]) }) it('filterWithIndex', () => { const f = (n: number) => n % 2 === 0 - assert.deepStrictEqual(pipe(['a', 'b', 'c'], _.filterWithIndex(f)), ['a', 'c']) + assert.deepStrictEqual(F.pipe(['a', 'b', 'c'], _.filterWithIndex(f)), ['a', 'c']) }) it('filterMap', () => { const f = (n: number) => (n % 2 === 0 ? O.none : O.some(n)) - assert.deepStrictEqual(pipe([1, 2, 3], _.filterMap(f)), [1, 3]) - assert.deepStrictEqual(pipe([], _.filterMap(f)), []) + assert.deepStrictEqual(F.pipe([1, 2, 3], _.filterMap(f)), [1, 3]) + assert.deepStrictEqual(F.pipe([], _.filterMap(f)), []) }) it('foldMapWithIndex', () => { assert.deepStrictEqual( - pipe( + F.pipe( ['a', 'b'], _.foldMapWithIndex(M.monoidString)((i, a) => i + a) ), @@ -168,13 +165,13 @@ describe('ReadonlyArray', () => { it('filterMapWithIndex', () => { const f = (i: number, n: number) => ((i + n) % 2 === 0 ? O.none : O.some(n)) - assert.deepStrictEqual(pipe([1, 2, 4], _.filterMapWithIndex(f)), [1, 2]) - assert.deepStrictEqual(pipe([], _.filterMapWithIndex(f)), []) + assert.deepStrictEqual(F.pipe([1, 2, 4], _.filterMapWithIndex(f)), [1, 2]) + assert.deepStrictEqual(F.pipe([], _.filterMapWithIndex(f)), []) }) it('partitionMap', () => { - assert.deepStrictEqual(pipe([], _.partitionMap(F.identity)), { left: [], right: [] }) - assert.deepStrictEqual(pipe([E.right(1), E.left('foo'), E.right(2)], _.partitionMap(F.identity)), { + assert.deepStrictEqual(F.pipe([], _.partitionMap(F.identity)), { left: [], right: [] }) + assert.deepStrictEqual(F.pipe([E.right(1), E.left('foo'), E.right(2)], _.partitionMap(F.identity)), { left: ['foo'], right: [1, 2] }) @@ -182,14 +179,14 @@ describe('ReadonlyArray', () => { it('partition', () => { assert.deepStrictEqual( - pipe( + F.pipe( [], _.partition((n) => n > 2) ), { left: [], right: [] } ) assert.deepStrictEqual( - pipe( + F.pipe( [1, 3], _.partition((n) => n > 2) ), @@ -198,23 +195,23 @@ describe('ReadonlyArray', () => { // refinements const xs: ReadonlyArray = ['a', 'b', 1] const isNumber = (x: string | number): x is number => typeof x === 'number' - const actual = pipe(xs, _.partition(isNumber)) + const actual = F.pipe(xs, _.partition(isNumber)) assert.deepStrictEqual(actual, { left: ['a', 'b'], right: [1] }) }) it('partitionMapWithIndex', () => { assert.deepStrictEqual( - pipe( + F.pipe( [], _.partitionMapWithIndex((_, a) => a) ), { left: [], right: [] } ) assert.deepStrictEqual( - pipe( + F.pipe( [E.right(1), E.left('foo'), E.right(2)], _.partitionMapWithIndex((i, a) => - pipe( + F.pipe( a, E.filterOrElse( (n) => n > i, @@ -232,14 +229,14 @@ describe('ReadonlyArray', () => { it('partitionWithIndex', () => { assert.deepStrictEqual( - pipe( + F.pipe( [], _.partitionWithIndex((i, n) => i + n > 2) ), { left: [], right: [] } ) assert.deepStrictEqual( - pipe( + F.pipe( [1, 2], _.partitionWithIndex((i, n) => i + n > 2) ), @@ -248,13 +245,13 @@ describe('ReadonlyArray', () => { // refinements const xs: ReadonlyArray = ['a', 'b', 1, 2] const isNumber = (i: number, x: string | number): x is number => typeof x === 'number' && i > 2 - const actual = pipe(xs, _.partitionWithIndex(isNumber)) + const actual = F.pipe(xs, _.partitionWithIndex(isNumber)) assert.deepStrictEqual(actual, { left: ['a', 'b', 1], right: [2] }) }) it('reduce', () => { assert.deepStrictEqual( - pipe( + F.pipe( ['a', 'b', 'c'], _.reduce('', (acc, a) => acc + a) ), @@ -264,7 +261,7 @@ describe('ReadonlyArray', () => { it('reduceWithIndex', () => { assert.deepStrictEqual( - pipe( + F.pipe( ['a', 'b'], _.reduceWithIndex('', (i, b, a) => b + i + a) ), @@ -276,14 +273,14 @@ describe('ReadonlyArray', () => { const as: ReadonlyArray = ['a', 'b', 'c'] const b = '' const f = (a: string, acc: string) => acc + a - assert.deepStrictEqual(pipe(as, _.reduceRight(b, f)), 'cba') + assert.deepStrictEqual(F.pipe(as, _.reduceRight(b, f)), 'cba') const x2: ReadonlyArray = [] - assert.deepStrictEqual(pipe(x2, _.reduceRight(b, f)), '') + assert.deepStrictEqual(F.pipe(x2, _.reduceRight(b, f)), '') }) it('reduceRightWithIndex', () => { assert.deepStrictEqual( - pipe( + F.pipe( ['a', 'b'], _.reduceRightWithIndex('', (i, a, b) => b + i + a) ), @@ -292,7 +289,7 @@ describe('ReadonlyArray', () => { }) it('duplicate', () => { - assert.deepStrictEqual(pipe(['a', 'b'], _.duplicate), [['a', 'b'], ['b']]) + assert.deepStrictEqual(F.pipe(['a', 'b'], _.duplicate), [['a', 'b'], ['b']]) }) }) @@ -849,11 +846,17 @@ describe('ReadonlyArray', () => { it('traverseWithIndex', () => { const ta: ReadonlyArray = ['a', 'bb'] assert.deepStrictEqual( - _.readonlyArray.traverseWithIndex(O.option)(ta, (i, s) => (s.length >= 1 ? O.some(s + i) : O.none)), + F.pipe( + ta, + _.traverseWithIndex(O.option)((i, s) => (s.length >= 1 ? O.some(s + i) : O.none)) + ), O.some(['a0', 'bb1']) ) assert.deepStrictEqual( - _.readonlyArray.traverseWithIndex(O.option)(ta, (i, s) => (s.length > 1 ? O.some(s + i) : O.none)), + F.pipe( + ta, + _.traverseWithIndex(O.option)((i, s) => (s.length > 1 ? O.some(s + i) : O.none)) + ), O.none ) @@ -861,13 +864,19 @@ describe('ReadonlyArray', () => { const f = (i: number, s: string): string => s + i assert.deepStrictEqual( _.readonlyArray.foldMapWithIndex(M.monoidString)(ta, f), - _.readonlyArray.traverseWithIndex(C.getApplicative(M.monoidString))(ta, (i, a) => C.make(f(i, a))) + F.pipe( + ta, + _.traverseWithIndex(C.getApplicative(M.monoidString))((i, a) => C.make(f(i, a))) + ) ) // FunctorWithIndex compatibility assert.deepStrictEqual( _.readonlyArray.mapWithIndex(ta, f), - _.readonlyArray.traverseWithIndex(I.identity)(ta, (i, a) => I.identity.of(f(i, a))) + F.pipe( + ta, + _.traverseWithIndex(I.identity)((i, a) => I.identity.of(f(i, a))) + ) ) }) diff --git a/test/ReadonlyMap.ts b/test/ReadonlyMap.ts index 439ffedc5..af3c7a3a9 100644 --- a/test/ReadonlyMap.ts +++ b/test/ReadonlyMap.ts @@ -1,16 +1,15 @@ import * as assert from 'assert' -import * as _ from '../src/ReadonlyMap' -import { semigroupSum, getStructSemigroup, getFirstSemigroup, getLastSemigroup } from '../src/Semigroup' -import { monoidString } from '../src/Monoid' -import { Refinement, identity } from '../src/function' -import { option, some, none, Option } from '../src/Option' -import { Eq, eqNumber, fromEquals } from '../src/Eq' import { array } from '../src/Array' import { Either, left, right } from '../src/Either' +import { Eq, eqNumber, fromEquals } from '../src/Eq' +import { identity, pipe, Refinement } from '../src/function' import * as I from '../src/Identity' -import { ord, ordString, fromCompare, ordNumber } from '../src/Ord' -import { showString, getStructShow, Show } from '../src/Show' -import { pipe } from '../src/pipeable' +import { monoidString } from '../src/Monoid' +import { none, option, Option, some } from '../src/Option' +import { fromCompare, ord, ordNumber, ordString } from '../src/Ord' +import * as _ from '../src/ReadonlyMap' +import { getFirstSemigroup, getLastSemigroup, getStructSemigroup, semigroupSum } from '../src/Semigroup' +import { getStructShow, Show, showString } from '../src/Show' interface User { readonly id: string diff --git a/test/ReadonlyNonEmptyArray.ts b/test/ReadonlyNonEmptyArray.ts index 9201662f0..241981f06 100644 --- a/test/ReadonlyNonEmptyArray.ts +++ b/test/ReadonlyNonEmptyArray.ts @@ -1,7 +1,7 @@ import * as assert from 'assert' import * as C from '../src/Const' import { eqNumber } from '../src/Eq' -import { identity } from '../src/function' +import { identity, pipe } from '../src/function' import * as I from '../src/Identity' import * as M from '../src/Monoid' import * as O from '../src/Option' @@ -20,8 +20,13 @@ describe('ReadonlyNonEmptyArray', () => { }) it('map', () => { - const double = (n: number) => n * 2 - assert.deepStrictEqual(_.readonlyNonEmptyArray.map([1, 2], double), [2, 4]) + assert.deepStrictEqual( + pipe( + [1, 2], + _.map((n) => n * 2) + ), + [2, 4] + ) }) it('mapWithIndex', () => { @@ -54,17 +59,23 @@ describe('ReadonlyNonEmptyArray', () => { it('traverse', () => { assert.deepStrictEqual( - _.readonlyNonEmptyArray.traverse(O.option)([1, 2, 3], (n) => (n >= 0 ? O.some(n) : O.none)), + pipe( + [1, 2, 3], + _.traverse(O.option)((n) => (n >= 0 ? O.some(n) : O.none)) + ), O.some([1, 2, 3]) ) assert.deepStrictEqual( - _.readonlyNonEmptyArray.traverse(O.option)([1, 2, 3], (n) => (n >= 2 ? O.some(n) : O.none)), + pipe( + [1, 2, 3], + _.traverse(O.option)((n) => (n >= 2 ? O.some(n) : O.none)) + ), O.none ) }) it('sequence', () => { - const sequence = _.readonlyNonEmptyArray.sequence(O.option) + const sequence = _.sequence(O.option) assert.deepStrictEqual(sequence([O.some(1), O.some(2), O.some(3)]), O.some([1, 2, 3])) assert.deepStrictEqual(sequence([O.none, O.some(2), O.some(3)]), O.none) }) @@ -251,14 +262,16 @@ describe('ReadonlyNonEmptyArray', () => { it('traverseWithIndex', () => { assert.deepStrictEqual( - _.readonlyNonEmptyArray.traverseWithIndex(O.option)(['a', 'bb'], (i, s) => - s.length >= 1 ? O.some(s + i) : O.none + pipe( + ['a', 'bb'], + _.traverseWithIndex(O.option)((i, s) => (s.length >= 1 ? O.some(s + i) : O.none)) ), O.some(['a0', 'bb1']) ) assert.deepStrictEqual( - _.readonlyNonEmptyArray.traverseWithIndex(O.option)(['a', 'bb'], (i, s) => - s.length > 1 ? O.some(s + i) : O.none + pipe( + ['a', 'bb'], + _.traverseWithIndex(O.option)((i, s) => (s.length > 1 ? O.some(s + i) : O.none)) ), O.none ) @@ -267,15 +280,19 @@ describe('ReadonlyNonEmptyArray', () => { const f = (i: number, s: string): string => s + i assert.deepStrictEqual( _.readonlyNonEmptyArray.foldMapWithIndex(M.monoidString)(['a', 'bb'], f), - _.readonlyNonEmptyArray.traverseWithIndex(C.getApplicative(M.monoidString))(['a', 'bb'], (i, a) => - C.make(f(i, a)) + pipe( + ['a', 'bb'], + _.traverseWithIndex(C.getApplicative(M.monoidString))((i, a) => C.make(f(i, a))) ) ) // FunctorWithIndex compatibility assert.deepStrictEqual( _.readonlyNonEmptyArray.mapWithIndex(['a', 'bb'], f), - _.readonlyNonEmptyArray.traverseWithIndex(I.identity)(['a', 'bb'], (i, a) => I.identity.of(f(i, a))) + pipe( + ['a', 'bb'], + _.traverseWithIndex(I.identity)((i, a) => I.identity.of(f(i, a))) + ) ) }) diff --git a/test/ReadonlyRecord.ts b/test/ReadonlyRecord.ts index e1a55b6d2..3e3db6dfa 100644 --- a/test/ReadonlyRecord.ts +++ b/test/ReadonlyRecord.ts @@ -1,15 +1,14 @@ import * as assert from 'assert' -import * as _ from '../src/ReadonlyRecord' -import { semigroupSum, getLastSemigroup, getFirstSemigroup } from '../src/Semigroup' -import { monoidString } from '../src/Monoid' -import { identity } from '../src/function' -import { option, some, none, Option, getOrElse, isSome } from '../src/Option' -import { eqNumber } from '../src/Eq' -import { readonlyArray, zip } from '../src/ReadonlyArray' import { left, right } from '../src/Either' +import { eqNumber } from '../src/Eq' +import { identity, pipe } from '../src/function' import * as I from '../src/Identity' +import { monoidString } from '../src/Monoid' +import { getOrElse, isSome, none, option, Option, some } from '../src/Option' +import { readonlyArray, zip } from '../src/ReadonlyArray' +import * as _ from '../src/ReadonlyRecord' +import { getFirstSemigroup, getLastSemigroup, semigroupSum } from '../src/Semigroup' import { showString } from '../src/Show' -import { pipe } from '../src/pipeable' const p = (n: number) => n > 2 diff --git a/test/ReadonlyTuple.ts b/test/ReadonlyTuple.ts index f2db00a25..c1932a055 100644 --- a/test/ReadonlyTuple.ts +++ b/test/ReadonlyTuple.ts @@ -1,11 +1,10 @@ import * as assert from 'assert' import { getMonoid } from '../src/Array' import { left, right } from '../src/Either' -import { identity } from '../src/function' +import { identity, pipe } from '../src/function' import { monoidString } from '../src/Monoid' import { none, option, some } from '../src/Option' import * as _ from '../src/ReadonlyTuple' -import { pipe } from '../src/pipeable' describe('ReadonlyTuple', () => { describe('pipeables', () => { @@ -102,14 +101,9 @@ describe('ReadonlyTuple', () => { }) it('traverse', () => { - assert.deepStrictEqual( - _.readonlyTuple.traverse(option)([2, 'a'], (n) => (n >= 2 ? some(n) : none)), - some([2, 'a']) - ) - assert.deepStrictEqual( - _.readonlyTuple.traverse(option)([1, 'a'], (n) => (n >= 2 ? some(n) : none)), - none - ) + const traverse = _.traverse(option)((n: number) => (n > 1 ? some(n) : none)) + assert.deepStrictEqual(traverse([2, 'a']), some([2, 'a'])) + assert.deepStrictEqual(traverse([1, 'a']), none) }) it('sequence', () => { diff --git a/test/State.ts b/test/State.ts index 35ceef7d0..1c5f9825a 100644 --- a/test/State.ts +++ b/test/State.ts @@ -1,7 +1,6 @@ import * as assert from 'assert' +import { pipe, tuple } from '../src/function' import * as _ from '../src/State' -import { tuple } from '../src/function' -import { pipe } from '../src/pipeable' describe('State', () => { describe('pipeables', () => { diff --git a/test/StateReaderTaskEither.ts b/test/StateReaderTaskEither.ts index 38c6f8db9..d43d80d16 100644 --- a/test/StateReaderTaskEither.ts +++ b/test/StateReaderTaskEither.ts @@ -3,7 +3,7 @@ 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 { pipe } from '../src/function' import { reader } from '../src/Reader' import * as RE from '../src/ReaderEither' import * as RTE from '../src/ReaderTaskEither' @@ -289,4 +289,22 @@ describe('StateReaderTaskEither', () => { const x = await _.run(pipe(_.right('a'), _.chainReaderTaskEitherK(f)), undefined, undefined) assert.deepStrictEqual(x, E.right([1, undefined])) }) + + it('put', async () => { + assert.deepStrictEqual(await _.put(2)(1)({})(), E.right([undefined, 2])) + }) + + it('get', async () => { + assert.deepStrictEqual(await _.get()(1)({})(), E.right([1, 1])) + }) + + it('modify', async () => { + const double = (n: number) => n * 2 + assert.deepStrictEqual(await _.modify(double)(1)({})(), E.right([undefined, 2])) + }) + + it('gets', async () => { + const double = (n: number) => n * 2 + assert.deepStrictEqual(await _.gets(double)(1)({})(), E.right([2, 1])) + }) }) diff --git a/test/Store.ts b/test/Store.ts index 9e6e7a07e..63999ab17 100644 --- a/test/Store.ts +++ b/test/Store.ts @@ -1,7 +1,7 @@ import * as assert from 'assert' import * as _ from '../src/Store' import { array } from '../src/Array' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' const len = (s: string): number => s.length diff --git a/test/Task.ts b/test/Task.ts index ea88ba3f0..949006042 100644 --- a/test/Task.ts +++ b/test/Task.ts @@ -1,8 +1,8 @@ import * as assert from 'assert' -import { array } from '../src/Array' +import * as A from '../src/Array' import * as I from '../src/IO' import { monoidString } from '../src/Monoid' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' import * as _ from '../src/Task' const delayReject = (n: number, a: A): _.Task => () => @@ -106,7 +106,7 @@ describe('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 sequenceSeries = array.sequence(_.taskSeq) + const sequenceSeries = A.sequence(_.taskSeq) const x = await sequenceSeries([t1, t2])() assert.deepStrictEqual(x, [2, 4]) assert.deepStrictEqual(log, ['start 1', 'end 1', 'start 2', 'end 2']) diff --git a/test/TaskEither.ts b/test/TaskEither.ts index f7cc681bf..d757887e9 100644 --- a/test/TaskEither.ts +++ b/test/TaskEither.ts @@ -1,13 +1,14 @@ import * as assert from 'assert' -import { array, getMonoid } from '../src/Array' +import * as A from '../src/Array' import * as E from '../src/Either' import { io } from '../src/IO' import { monoidString } from '../src/Monoid' import { none, some } from '../src/Option' -import { pipe, pipeable } from '../src/pipeable' +import { pipeable } from '../src/pipeable' import { semigroupString, semigroupSum } from '../src/Semigroup' import * as _ from '../src/TaskEither' import { ioEither } from '../src/IOEither' +import { pipe } from '../src/function' describe('TaskEither', () => { describe('pipeables', () => { @@ -141,7 +142,7 @@ describe('TaskEither', () => { const useSuccess = () => _.right('use success') const useFailure = () => _.left('use failure') const releaseSuccess = () => - _.taskEither.fromIO(() => { + _.rightIO(() => { log.push('release success') }) const releaseFailure = () => _.left('release failure') @@ -300,9 +301,15 @@ describe('TaskEither', () => { const log: Array = [] const append = (message: string): _.TaskEither => _.rightTask(() => Promise.resolve(log.push(message))) - const t1 = _.taskEither.chain(append('start 1'), () => append('end 1')) - const t2 = _.taskEither.chain(append('start 2'), () => append('end 2')) - const sequenceParallel = array.sequence(_.taskEither) + const t1 = pipe( + append('start 1'), + _.chain(() => append('end 1')) + ) + const t2 = pipe( + append('start 2'), + _.chain(() => append('end 2')) + ) + const sequenceParallel = A.sequence(_.taskEither) const x = await sequenceParallel([t1, t2])() assert.deepStrictEqual(x, E.right([3, 4])) assert.deepStrictEqual(log, ['start 1', 'start 2', 'end 1', 'end 2']) @@ -313,17 +320,23 @@ describe('TaskEither', () => { const log: Array = [] const append = (message: string): _.TaskEither => _.rightTask(() => Promise.resolve(log.push(message))) - const t1 = _.taskEither.chain(append('start 1'), () => append('end 1')) - const t2 = _.taskEither.chain(append('start 2'), () => append('end 2')) - const sequenceSeries = array.sequence(_.taskEitherSeq) + const t1 = pipe( + append('start 1'), + _.chain(() => append('end 1')) + ) + const t2 = pipe( + append('start 2'), + _.chain(() => append('end 2')) + ) + const sequenceSeries = A.sequence(_.taskEitherSeq) const x = await sequenceSeries([t1, t2])() assert.deepStrictEqual(x, E.right([2, 4])) assert.deepStrictEqual(log, ['start 1', 'end 1', 'start 2', 'end 2']) }) - it('fromIO', async () => { + it('rightIO', async () => { const io = () => 1 - const fa = _.taskEither.fromIO(io) + const fa = _.rightIO(io) const e = await fa() assert.deepStrictEqual(e, E.right(1)) }) @@ -337,18 +350,6 @@ describe('TaskEither', () => { describe('getTaskValidation', () => { const TV = _.getTaskValidation(semigroupString) - it('of', async () => { - const e = await TV.of(1)() - assert.deepStrictEqual(e, E.right(1)) - }) - - it('map', async () => { - const double = (n: number): number => n * 2 - const e1 = await TV.map(TV.of(1), double)() - assert.deepStrictEqual(e1, E.right(2)) - const e2 = await TV.map(_.left('a'), double)() - assert.deepStrictEqual(e2, E.left('a')) - }) it('ap', async () => { const fab = _.left('a') @@ -357,15 +358,6 @@ describe('TaskEither', () => { assert.deepStrictEqual(e1, E.left('ab')) }) - it('chain', async () => { - const e1 = await TV.chain(_.right(3), (a) => (a > 2 ? _.right(a) : _.left('b')))() - assert.deepStrictEqual(e1, E.right(3)) - const e2 = await TV.chain(_.right(1), (a) => (a > 2 ? _.right(a) : _.left('b')))() - assert.deepStrictEqual(e2, E.left('b')) - const e3 = await TV.chain(_.left('a'), (a) => (a > 2 ? _.right(a) : _.left('b')))() - assert.deepStrictEqual(e3, E.left('a')) - }) - it('alt', async () => { const e1 = await TV.alt(_.right(1), () => _.right(2))() assert.deepStrictEqual(e1, E.right(1)) @@ -381,7 +373,7 @@ describe('TaskEither', () => { describe('getFilterable', () => { const F_ = { ..._.taskEither, - ..._.getFilterable(getMonoid()) + ..._.getFilterable(A.getMonoid()) } const { filter } = pipeable(F_) diff --git a/test/TaskThese.ts b/test/TaskThese.ts index 56aa2768b..e39b94c9f 100644 --- a/test/TaskThese.ts +++ b/test/TaskThese.ts @@ -1,7 +1,7 @@ import * as assert from 'assert' import * as IO from '../src/IO' import { monoidString, monoidSum } from '../src/Monoid' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' import * as T from '../src/Task' import * as _ from '../src/TaskThese' import * as TH from '../src/These' diff --git a/test/These.ts b/test/These.ts index 1603ad320..606e9ce01 100644 --- a/test/These.ts +++ b/test/These.ts @@ -1,12 +1,11 @@ import * as assert from 'assert' -import { identity } from '../src/function' +import { eqNumber } from '../src/Eq' +import { identity, pipe } from '../src/function' import { monoidString, monoidSum } from '../src/Monoid' import { none, option, some } from '../src/Option' import { semigroupString } from '../src/Semigroup' -import { eqNumber } from '../src/Eq' import { showString } from '../src/Show' import * as _ from '../src/These' -import { pipe } from '../src/pipeable' describe('These', () => { describe('pipeables', () => { @@ -135,24 +134,16 @@ describe('These', () => { }) it('traverse', () => { + const traverse = _.traverse(option)((n: number) => (n > 1 ? some(n) : none)) + assert.deepStrictEqual(pipe(_.left('a'), traverse), some(_.left('a'))) + assert.deepStrictEqual(pipe(_.right(2), traverse), some(_.right(2))) + assert.deepStrictEqual(pipe(_.right(1), traverse), none) + assert.deepStrictEqual(pipe(_.both('a', 2), traverse), some(_.both('a', 2))) assert.deepStrictEqual( - _.these.traverse(option)(_.left('a'), (n) => (n >= 2 ? some(n) : none)), - some(_.left('a')) - ) - assert.deepStrictEqual( - _.these.traverse(option)(_.right(2), (n) => (n >= 2 ? some(n) : none)), - some(_.right(2)) - ) - assert.deepStrictEqual( - _.these.traverse(option)(_.right(1), (n) => (n >= 2 ? some(n) : none)), - none - ) - assert.deepStrictEqual( - _.these.traverse(option)(_.both('a', 2), (n) => (n >= 2 ? some(n) : none)), - some(_.both('a', 2)) - ) - assert.deepStrictEqual( - _.these.traverse(option)(_.both('a', 1), (n) => (n >= 2 ? some(n) : none)), + pipe( + _.both('a', 1), + _.traverse(option)((n) => (n >= 2 ? some(n) : none)) + ), none ) }) diff --git a/test/Traced.ts b/test/Traced.ts index 74dd8b1da..37f86c266 100644 --- a/test/Traced.ts +++ b/test/Traced.ts @@ -1,7 +1,7 @@ import * as assert from 'assert' import { getStructMonoid, monoidAny, Monoid } from '../src/Monoid' import * as _ from '../src/Traced' -import { pipe } from '../src/pipeable' +import { pipe } from '../src/function' // Adapted from https://chshersh.github.io/posts/2019-03-25-comonadic-builders diff --git a/test/Tree.ts b/test/Tree.ts index f0688a6de..e66fc0d96 100644 --- a/test/Tree.ts +++ b/test/Tree.ts @@ -1,11 +1,10 @@ import * as assert from 'assert' -import { identity } from '../src/function' +import { eq, Eq, eqNumber } from '../src/Eq' +import { identity, pipe } from '../src/function' import * as I from '../src/Identity' import { monoidString } from '../src/Monoid' -import { eq, Eq, eqNumber } from '../src/Eq' import { showString } from '../src/Show' import * as _ from '../src/Tree' -import { pipe } from '../src/pipeable' describe('Tree', () => { it('map', () => { @@ -89,7 +88,10 @@ describe('Tree', () => { it('traverse', () => { const fa = _.make('a', [_.make('b'), _.make('c')]) assert.deepStrictEqual( - _.tree.traverse(I.identity)(fa, (a) => I.identity.of(a)), + pipe( + fa, + _.traverse(I.identity)((a) => I.identity.of(a)) + ), I.identity.of(fa) ) }) diff --git a/test/Writer.ts b/test/Writer.ts index 9e55028e7..fb5f6f37f 100644 --- a/test/Writer.ts +++ b/test/Writer.ts @@ -1,8 +1,7 @@ import * as assert from 'assert' -import * as _ from '../src/Writer' -import { tuple } from '../src/function' +import { pipe, tuple } from '../src/function' import { monoidString } from '../src/Monoid' -import { pipe } from '../src/pipeable' +import * as _ from '../src/Writer' describe('Writer', () => { describe('pipeables', () => { @@ -61,12 +60,23 @@ describe('Writer', () => { ) }) - it('getMonad', () => { + describe('getMonad', () => { const M = _.getMonad(monoidString) - assert.deepStrictEqual(M.of(1)(), [1, '']) - const double = (n: number): number => n * 2 - assert.deepStrictEqual(M.ap(M.of(double), M.of(1))(), [2, '']) - const f = (n: number) => M.of(n * 2) - assert.deepStrictEqual(M.chain(M.of(1), f)(), [2, '']) + + it('of', () => { + assert.deepStrictEqual(M.of(1)(), [1, '']) + }) + + it('ap', () => { + const fab: _.Writer number> = () => [(n: number) => n * 2, 'a'] + const fa: _.Writer = () => [1, 'b'] + assert.deepStrictEqual(M.ap(fab, fa)(), [2, 'ab']) + }) + + it('chain', () => { + const fa: _.Writer = () => [1, 'a'] + const f = (n: number): _.Writer => () => [n * 2, 'b'] + assert.deepStrictEqual(M.chain(fa, f)(), [2, 'ab']) + }) }) }) diff --git a/test/function.ts b/test/function.ts index 6523e9edf..21b984568 100644 --- a/test/function.ts +++ b/test/function.ts @@ -14,7 +14,8 @@ import { absurd, flow, tupled, - untupled + untupled, + pipe } from '../src/function' const f = (n: number) => n + 1 @@ -100,4 +101,22 @@ describe('function', () => { assert.deepStrictEqual(u1(1), 2) assert.deepStrictEqual(u2(1, 2), 3) }) + + it('pipe', () => { + const f = (n: number) => n + 1 + const g = (n: number) => n * 2 + assert.deepStrictEqual(pipe(2), 2) + assert.deepStrictEqual(pipe(2, f), 3) + assert.deepStrictEqual(pipe(2, f, g), 6) + assert.deepStrictEqual(pipe(2, f, g, f), 7) + assert.deepStrictEqual(pipe(2, f, g, f, g), 14) + assert.deepStrictEqual(pipe(2, f, g, f, g, f), 15) + assert.deepStrictEqual(pipe(2, f, g, f, g, f, g), 30) + assert.deepStrictEqual(pipe(2, f, g, f, g, f, g, f), 31) + assert.deepStrictEqual(pipe(2, f, g, f, g, f, g, f, g), 62) + assert.deepStrictEqual(pipe(2, f, g, f, g, f, g, f, g, f), 63) + assert.deepStrictEqual(pipe(2, f, g, f, g, f, g, f, g, f), 63) + // this is just to satisfy noImplicitReturns and 100% coverage + assert.deepStrictEqual((pipe as any)(...[2, f, g, f, g, f, g, f, g, f, g]), undefined) + }) }) diff --git a/test/pipeable.ts b/test/pipeable.ts index a78f78d9e..e87fa0993 100644 --- a/test/pipeable.ts +++ b/test/pipeable.ts @@ -1,11 +1,11 @@ import * as assert from 'assert' import { array } from '../src/Array' -import { pipeable, pipe } from '../src/pipeable' -import { either, right, left } from '../src/Either' -import { monoidSum, fold } from '../src/Monoid' -import { some, none, isSome, Option, option } from '../src/Option' -import { reader } from '../src/Reader' import * as C from '../src/Const' +import { either, left, right } from '../src/Either' +import { fold, monoidSum } from '../src/Monoid' +import { isSome, none, Option, option, some } from '../src/Option' +import { pipeable } from '../src/pipeable' +import { reader } from '../src/Reader' describe('pipeable', () => { it('{}', () => { @@ -134,22 +134,4 @@ describe('pipeable', () => { const { compose } = pipeable(reader) assert.deepStrictEqual(compose((s: string) => s.length)((n) => n * 2)('aa'), 4) }) - - it('pipe', () => { - const f = (n: number) => n + 1 - const g = (n: number) => n * 2 - assert.deepStrictEqual(pipe(2), 2) - assert.deepStrictEqual(pipe(2, f), 3) - assert.deepStrictEqual(pipe(2, f, g), 6) - assert.deepStrictEqual(pipe(2, f, g, f), 7) - assert.deepStrictEqual(pipe(2, f, g, f, g), 14) - assert.deepStrictEqual(pipe(2, f, g, f, g, f), 15) - assert.deepStrictEqual(pipe(2, f, g, f, g, f, g), 30) - assert.deepStrictEqual(pipe(2, f, g, f, g, f, g, f), 31) - assert.deepStrictEqual(pipe(2, f, g, f, g, f, g, f, g), 62) - assert.deepStrictEqual(pipe(2, f, g, f, g, f, g, f, g, f), 63) - assert.deepStrictEqual(pipe(2, f, g, f, g, f, g, f, g, f), 63) - // this is just to satisfy noImplicitReturns and 100% coverage - assert.deepStrictEqual((pipe as any)(...[2, f, g, f, g, f, g, f, g, f, g]), undefined) - }) })