Repository: gcanti/fp-ts
Pull request #1499 (2021-04-27 15:40:54)

Add RTE.chainReaderEitherK(W) and RTE.chainFirstReaderEitherK(W)
port of #1498


Patch:
diff --git a/docs/modules/ReaderT.ts.md b/docs/modules/ReaderT.ts.md
index 04c3bc8e..5761a844 100644
--- a/docs/modules/ReaderT.ts.md
+++ b/docs/modules/ReaderT.ts.md
@@ -14,6 +14,12 @@ Added in v3.0.0
 
 - [utils](#utils)
   - [ap](#ap)
+  - [asksEitherK](#askseitherk)
+  - [asksIOK](#asksiok)
+  - [asksReaderK](#asksreaderk)
+  - [asksStateK](#asksstatek)
+  - [asksTaskK](#askstaskk)
+  - [asksTheseK](#asksthesek)
   - [chain](#chain)
   - [fromReader](#fromreader)
   - [map](#map)
@@ -63,6 +69,163 @@ export declare function ap<F>(
 
 Added in v3.0.0
 
+## asksEitherK
+
+**Signature**
+
+```ts
+export declare function asksEitherK<F extends URIS4>(
+  F: FromEither4<F>
+): <R, FE, A, S, FR>(f: (r: R) => Either<FE, A>) => Reader<R, Kind4<F, S, FR, FE, A>>
+export declare function asksEitherK<F extends URIS3>(
+  F: FromEither3<F>
+): <R, FE, A, FR>(f: (r: R) => Either<FE, A>) => Reader<R, Kind3<F, FR, FE, A>>
+export declare function asksEitherK<F extends URIS3, FE>(
+  F: FromEither3C<F, FE>
+): <R, A, FR>(f: (r: R) => Either<FE, A>) => Reader<R, Kind3<F, FR, FE, A>>
+export declare function asksEitherK<F extends URIS2>(
+  F: FromEither2<F>
+): <R, FE, A>(f: (r: R) => Either<FE, A>) => Reader<R, Kind2<F, FE, A>>
+export declare function asksEitherK<F extends URIS2, FE>(
+  F: FromEither2C<F, FE>
+): <R, A>(f: (r: R) => Either<FE, A>) => Reader<R, Kind2<F, FE, A>>
+export declare function asksEitherK<F extends URIS>(
+  F: FromEither1<F>
+): <R, FE, A>(f: (r: R) => Either<FE, A>) => Reader<R, Kind<F, A>>
+export declare function asksEitherK<F>(
+  F: FromEither<F>
+): <R, E, A>(f: (r: R) => Either<E, A>) => Reader<R, HKT2<F, E, A>>
+```
+
+Added in v3.0.0
+
+## asksIOK
+
+**Signature**
+
+```ts
+export declare function asksIOK<F extends URIS4>(
+  F: FromIO4<F>
+): <R, A, S, FR, FE>(f: Reader<R, IO<A>>) => Reader<R, Kind4<F, S, FR, FE, A>>
+export declare function asksIOK<F extends URIS3>(
+  F: FromIO3<F>
+): <R, A, FR, FE>(f: Reader<R, IO<A>>) => Reader<R, Kind3<F, FR, FE, A>>
+export declare function asksIOK<F extends URIS3, FE>(
+  F: FromIO3C<F, FE>
+): <R, A, FR>(f: Reader<R, IO<A>>) => Reader<R, Kind3<F, FR, FE, A>>
+export declare function asksIOK<F extends URIS2>(
+  F: FromIO2<F>
+): <R, A, FE>(f: Reader<R, IO<A>>) => Reader<R, Kind2<F, FE, A>>
+export declare function asksIOK<F extends URIS2, FE>(
+  F: FromIO2C<F, FE>
+): <R, A>(f: Reader<R, IO<A>>) => Reader<R, Kind2<F, FE, A>>
+export declare function asksIOK<F extends URIS>(F: FromIO1<F>): <R, A>(f: Reader<R, IO<A>>) => Reader<R, Kind<F, A>>
+export declare function asksIOK<F>(F: FromIO<F>): <R, A>(f: Reader<R, IO<A>>) => Reader<R, HKT<F, A>>
+```
+
+Added in v3.0.0
+
+## asksReaderK
+
+**Signature**
+
+```ts
+export declare function asksReaderK<F extends URIS4>(
+  F: FromReader4<F>
+): <R, FR, A, S, FE>(f: Reader<R, Reader<FR, A>>) => Reader<R, Kind4<F, S, FR, FE, A>>
+export declare function asksReaderK<F extends URIS3>(
+  F: FromReader3<F>
+): <R, FR, A, FE>(f: Reader<R, Reader<FR, A>>) => Reader<R, Kind3<F, FR, FE, A>>
+export declare function asksReaderK<F extends URIS3, FE>(
+  F: FromReader3C<F, FE>
+): <R, FR, A>(f: Reader<R, Reader<FR, A>>) => Reader<R, Kind3<F, FR, FE, A>>
+export declare function asksReaderK<F extends URIS2>(
+  F: FromReader2<F>
+): <R, FR, A>(f: Reader<R, Reader<FR, A>>) => Reader<R, Kind2<F, FR, A>>
+export declare function asksReaderK<F>(
+  F: FromReader<F>
+): <R, FR, A>(f: Reader<R, Reader<FR, A>>) => Reader<R, HKT2<F, FR, A>>
+```
+
+Added in v3.0.0
+
+## asksStateK
+
+**Signature**
+
+```ts
+export declare function asksStateK<F extends URIS4>(
+  F: FromState4<F>
+): <R, S, A, FR, FE>(f: Reader<R, State<S, A>>) => Reader<R, Kind4<F, S, FR, FE, A>>
+export declare function asksStateK<F extends URIS3>(
+  F: FromState3<F>
+): <R, S, A, FE>(f: Reader<R, State<S, A>>) => Reader<R, Kind3<F, S, FE, A>>
+export declare function asksStateK<F extends URIS3, FE>(
+  F: FromState3C<F, FE>
+): <R, S, A>(f: Reader<R, State<S, A>>) => Reader<R, Kind3<F, S, FE, A>>
+export declare function asksStateK<F extends URIS2>(
+  F: FromState2<F>
+): <R, S, A>(f: Reader<R, State<S, A>>) => Reader<R, Kind2<F, S, A>>
+export declare function asksStateK<F>(F: FromState<F>): <R, S, A>(f: Reader<R, State<S, A>>) => Reader<R, HKT2<F, S, A>>
+```
+
+Added in v3.0.0
+
+## asksTaskK
+
+**Signature**
+
+```ts
+export declare function asksTaskK<F extends URIS4>(
+  F: FromTask4<F>
+): <R, A, S, FR, FE>(f: Reader<R, Task<A>>) => Reader<R, Kind4<F, S, FR, FE, A>>
+export declare function asksTaskK<F extends URIS3>(
+  F: FromTask3<F>
+): <R, A, FR, FE>(f: Reader<R, Task<A>>) => Reader<R, Kind3<F, FR, FE, A>>
+export declare function asksTaskK<F extends URIS3, FE>(
+  F: FromTask3C<F, FE>
+): <R, A, FR>(f: Reader<R, Task<A>>) => Reader<R, Kind3<F, FR, FE, A>>
+export declare function asksTaskK<F extends URIS2>(
+  F: FromTask2<F>
+): <R, A, FE>(f: Reader<R, Task<A>>) => Reader<R, Kind2<F, FE, A>>
+export declare function asksTaskK<F extends URIS2, FE>(
+  F: FromTask2C<F, FE>
+): <R, A>(f: Reader<R, Task<A>>) => Reader<R, Kind2<F, FE, A>>
+export declare function asksTaskK<F extends URIS>(
+  F: FromTask1<F>
+): <R, A>(f: Reader<R, Task<A>>) => Reader<R, Kind<F, A>>
+export declare function asksTaskK<F>(F: FromTask<F>): <R, A>(f: Reader<R, Task<A>>) => Reader<R, HKT<F, A>>
+```
+
+Added in v3.0.0
+
+## asksTheseK
+
+**Signature**
+
+```ts
+export declare function asksTheseK<F extends URIS4>(
+  F: FromThese4<F>
+): <R, FE, A, S, FR>(f: Reader<R, These<FE, A>>) => Reader<R, Kind4<F, S, FR, FE, A>>
+export declare function asksTheseK<F extends URIS3>(
+  F: FromThese3<F>
+): <R, FE, A, FR>(f: Reader<R, These<FE, A>>) => Reader<R, Kind3<F, FR, FE, A>>
+export declare function asksTheseK<F extends URIS3, FE>(
+  F: FromThese3C<F, FE>
+): <R, A, FR>(f: Reader<R, These<FE, A>>) => Reader<R, Kind3<F, FR, FE, A>>
+export declare function asksTheseK<F extends URIS2>(
+  F: FromThese2<F>
+): <R, FE, A>(f: Reader<R, These<FE, A>>) => Reader<R, Kind2<F, FE, A>>
+export declare function asksTheseK<F extends URIS2, FE>(
+  F: FromThese2C<F, FE>
+): <R, A>(f: Reader<R, These<FE, A>>) => Reader<R, Kind2<F, FE, A>>
+export declare function asksTheseK<F>(
+  F: FromThese<F>
+): <R, FE, A>(f: Reader<R, These<FE, A>>) => Reader<R, HKT2<F, FE, A>>
+```
+
+Added in v3.0.0
+
 ## chain
 
 **Signature**
diff --git a/docs/modules/ReaderTaskEither.ts.md b/docs/modules/ReaderTaskEither.ts.md
index 6f75b008..818d9f62 100644
--- a/docs/modules/ReaderTaskEither.ts.md
+++ b/docs/modules/ReaderTaskEither.ts.md
@@ -34,6 +34,8 @@ Added in v3.0.0
   - [chainEitherK](#chaineitherk)
   - [chainEitherKW](#chaineitherkw)
   - [chainFirstIOK](#chainfirstiok)
+  - [chainFirstReaderEitherK](#chainfirstreadereitherk)
+  - [chainFirstReaderEitherKW](#chainfirstreadereitherkw)
   - [chainFirstReaderK](#chainfirstreaderk)
   - [chainFirstReaderKW](#chainfirstreaderkw)
   - [chainFirstReaderTaskK](#chainfirstreadertaskk)
@@ -44,6 +46,8 @@ Added in v3.0.0
   - [chainIOEitherKW](#chainioeitherkw)
   - [chainIOK](#chainiok)
   - [chainOptionK](#chainoptionk)
+  - [chainReaderEitherK](#chainreadereitherk)
+  - [chainReaderEitherKW](#chainreadereitherkw)
   - [chainReaderK](#chainreaderk)
   - [chainReaderKW](#chainreaderkw)
   - [chainReaderTaskK](#chainreadertaskk)
@@ -58,6 +62,7 @@ Added in v3.0.0
   - [fromIOEitherK](#fromioeitherk)
   - [fromIOK](#fromiok)
   - [fromOptionK](#fromoptionk)
+  - [fromReaderEitherK](#fromreadereitherk)
   - [fromReaderK](#fromreaderk)
   - [fromReaderTaskK](#fromreadertaskk)
   - [fromTaskEitherK](#fromtaskeitherk)
@@ -363,6 +368,32 @@ export declare const chainFirstIOK: <A, B>(
 
 Added in v3.0.0
 
+## chainFirstReaderEitherK
+
+**Signature**
+
+```ts
+export declare const chainFirstReaderEitherK: <R, E, A, B>(
+  f: (a: A) => ReaderEither<R, E, B>
+) => (ma: ReaderTaskEither<R, E, A>) => ReaderTaskEither<R, E, A>
+```
+
+Added in v2.11.0
+
+## chainFirstReaderEitherKW
+
+Less strict version of [`chainFirstReaderEitherK`](#chainFirstReaderEitherK).
+
+**Signature**
+
+```ts
+export declare const chainFirstReaderEitherKW: <R2, E2, A, B>(
+  f: (a: A) => ReaderEither<R2, E2, B>
+) => <R1, E1>(ma: ReaderTaskEither<R1, E1, A>) => ReaderTaskEither<R1 & R2, E2 | E1, A>
+```
+
+Added in v2.11.0
+
 ## chainFirstReaderK
 
 **Signature**
@@ -491,6 +522,32 @@ export declare const chainOptionK: <E>(
 
 Added in v3.0.0
 
+## chainReaderEitherK
+
+**Signature**
+
+```ts
+export declare const chainReaderEitherK: <R, E, A, B>(
+  f: (a: A) => ReaderEither<R, E, B>
+) => (ma: ReaderTaskEither<R, E, A>) => ReaderTaskEither<R, E, B>
+```
+
+Added in v2.11.0
+
+## chainReaderEitherKW
+
+Less strict version of [`chainReaderEitherK`](#chainReaderEitherK).
+
+**Signature**
+
+```ts
+export declare const chainReaderEitherKW: <R2, E2, A, B>(
+  f: (a: A) => ReaderEither<R2, E2, B>
+) => <R1, E1>(ma: ReaderTaskEither<R1, E1, A>) => ReaderTaskEither<R1 & R2, E2 | E1, B>
+```
+
+Added in v2.11.0
+
 ## chainReaderK
 
 **Signature**
@@ -673,6 +730,18 @@ export declare const fromOptionK: <E>(
 
 Added in v3.0.0
 
+## fromReaderEitherK
+
+**Signature**
+
+```ts
+export declare const fromReaderEitherK: <R, E, A extends readonly unknown[], B>(
+  f: (...a: A) => ReaderEither<R, E, B>
+) => (...a: A) => ReaderTaskEither<R, E, B>
+```
+
+Added in v2.11.0
+
 ## fromReaderK
 
 **Signature**
diff --git a/src/ReaderTaskEither.ts b/src/ReaderTaskEither.ts
index a9eee670..4e887f78 100644
--- a/src/ReaderTaskEither.ts
+++ b/src/ReaderTaskEither.ts
@@ -444,6 +444,52 @@ export const chainTaskEitherK: <E, A, B>(
   f: (a: A) => TaskEither<E, B>
 ) => <R>(ma: ReaderTaskEither<R, E, A>) => ReaderTaskEither<R, E, B> = chainTaskEitherKW
 
+/**
+ * @category combinators
+ * @since 2.11.0
+ */
+export const fromReaderEitherK = <R, E, A extends ReadonlyArray<unknown>, B>(
+  f: (...a: A) => ReaderEither<R, E, B>
+): ((...a: A) => ReaderTaskEither<R, E, B>) => flow(f, fromReaderEither)
+
+/**
+ * Less strict version of [`chainReaderEitherK`](#chainReaderEitherK).
+ *
+ * @category combinators
+ * @since 2.11.0
+ */
+export const chainReaderEitherKW: <R2, E2, A, B>(
+  f: (a: A) => ReaderEither<R2, E2, B>
+) => <R1, E1>(ma: ReaderTaskEither<R1, E1, A>) => ReaderTaskEither<R1 & R2, E1 | E2, B> = (f) =>
+  chainW(fromReaderEitherK(f))
+
+/**
+ * @category combinators
+ * @since 2.11.0
+ */
+export const chainReaderEitherK: <R, E, A, B>(
+  f: (a: A) => ReaderEither<R, E, B>
+) => (ma: ReaderTaskEither<R, E, A>) => ReaderTaskEither<R, E, B> = chainReaderEitherKW
+
+/**
+ * Less strict version of [`chainFirstReaderEitherK`](#chainFirstReaderEitherK).
+ *
+ * @category combinators
+ * @since 2.11.0
+ */
+export const chainFirstReaderEitherKW: <R2, E2, A, B>(
+  f: (a: A) => ReaderEither<R2, E2, B>
+) => <R1, E1>(ma: ReaderTaskEither<R1, E1, A>) => ReaderTaskEither<R1 & R2, E1 | E2, A> = (f) =>
+  chainFirstW(fromReaderEitherK(f))
+
+/**
+ * @category combinators
+ * @since 2.11.0
+ */
+export const chainFirstReaderEitherK: <R, E, A, B>(
+  f: (a: A) => ReaderEither<R, E, B>
+) => (ma: ReaderTaskEither<R, E, A>) => ReaderTaskEither<R, E, A> = chainFirstReaderEitherKW
+
 /**
  * `map` can be used to turn functions `(a: A) => B` into functions `(fa: F<A>) => F<B>` whose argument and return types
  * use the type constructor `F` to represent some computational context.


Test patch:
diff --git a/test/ReaderTaskEither.ts b/test/ReaderTaskEither.ts
index a27cf879..02f3b3f7 100644
--- a/test/ReaderTaskEither.ts
+++ b/test/ReaderTaskEither.ts
@@ -359,6 +359,16 @@ describe('ReaderTaskEither', () => {
     U.deepStrictEqual(await pipe(_.right<string, {}, never>('a'), _.chainFirstReaderTaskKW(f))({})(), E.right('a'))
   })
 
+  it('chainReaderEitherKW', async () => {
+    const f = (s: string) => RE.right(s.length)
+    U.deepStrictEqual(await pipe(_.right<string, {}, never>('a'), _.chainReaderEitherKW(f))({})(), E.right(1))
+  })
+
+  it('chainFirstReaderEitherKW', async () => {
+    const f = (s: string) => RE.right(s.length)
+    U.deepStrictEqual(await pipe(_.right<string, {}, never>('a'), _.chainFirstReaderEitherKW(f))({})(), E.right('a'))
+  })
+
   // -------------------------------------------------------------------------------------
   // utils
   // -------------------------------------------------------------------------------------