Repository: gcanti/fp-ts
Pull request #1070 (2019-12-31 16:26:38)

add some kleisli liftings and rename kleisli chains for consistency


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index daba6d20..7113417a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,29 +20,29 @@ high state of flux, you're at risk of it changing without notice.
   - add `WriterT` module, closes #1050 (@gcanti)
   - add `TheseT` module (@gcanti)
   - add `TaskThese` module (@gcanti)
+  - `function`
+    - add `tupled`, `untupled` functions, closes #1062 (@gcanti)
+  - `IOEither`
+    - add `fromEitherK`, `chainEitherK` (@gcanti)
+  - `ReaderEither`
+    - add `fromEitherK`, `chainEitherK` (@gcanti)
+  - `ReaderTask`
+    - add `run` (@gcanti)
+    - add `fromIOK`, `chainIOK`, `fromTaskK`, `chainTaskK` (@gcanti)
+  - `ReaderTaskEither`
+    - add `fromEitherK`, `chainEitherK`, `fromIOEitherK`, `chainIOEitherK`, `fromTaskEitherK`, `chainTaskEitherK` (@gcanti)
   - `These`
     - add `swap` (@gcanti)
   - `Ord`
     - add `getMonoid` (@vicrac)
   - `Ordering`
     - add `monoidOrdering` (@gcanti)
+  - `StateReaderTaskEither`
+    - add `fromEitherK`, `chainEitherK`, `fromIOEitherK`, `chainIOEitherK`, `fromTaskEitherK`, `chainTaskEitherK`, `fromReaderTaskEitherK`, `chainReaderTaskEitherK` (@gcanti)
   - `Task`
-    - add `chainIO` (@gcanti)
+    - add `fromIOK`, `chainIOK` (@gcanti)
   - `TaskEither`
-    - add `chainEither`, `chainIOEither` (@gcanti)
-  - `IOEither`
-    - add `chainEither` (@gcanti)
-  - `ReaderEither`
-    - add `chainEither` (@gcanti)
-  - `ReaderTask`
-    - add `run` (@gcanti)
-    - add `chainIO`, `chainTask` (@gcanti)
-  - `ReaderTaskEither`
-    - add `chainEither`, `chainIOEither`, `chainTaskEither` (@gcanti)
-  - `StateReaderTaskEither`
-    - add `chainEither`, `chainIOEither`, `chainTaskEither`, `chainReaderTaskEither` (@gcanti)
-  - `function`
-    - add `tupled`, `untupled` functions, closes #1062 (@gcanti)
+    - add `fromEitherK`, `chainEitherK`, `fromIOEitherK`, `chainIOEitherK` (@gcanti)
 - **Deprecation**
   - `Ord`
     - deprecate `getSemigroup` in favor of `getMonoid` (@gcanti)
diff --git a/docs/introduction/ecosystem.md b/docs/introduction/ecosystem.md
index 164e66b4..c99ce844 100644
--- a/docs/introduction/ecosystem.md
+++ b/docs/introduction/ecosystem.md
@@ -25,6 +25,7 @@ has_toc: false
 - [waveguide](https://github.com/rzeigler/waveguide) - Bifunctor effect type and concurrent data structures.
 - [kleisli-ts](https://github.com/YBogomolov/kleisli-ts) - Kleisli arrows for bifunctor MonadThrow (IOEither, TaskEither)
 - [@nll/datum](https://github.com/nullpub/datum) - Datum and DatumEither types, another take on RemoteData and [flow](https://medium.com/@gcanti/slaying-a-ui-antipattern-with-flow-5eed0cfb627b)
+- [fetcher-ts](https://github.com/YBogomolov/fetcher-ts) - Type-safe REST HTTP client with io-ts response validation
 
 ## Bindings
 
diff --git a/docs/modules/IOEither.ts.md b/docs/modules/IOEither.ts.md
index 1aefc812..9aad98bf 100644
--- a/docs/modules/IOEither.ts.md
+++ b/docs/modules/IOEither.ts.md
@@ -25,8 +25,9 @@ Added in v2.0.0
 - [rightIO (constant)](#rightio-constant)
 - [swap (constant)](#swap-constant)
 - [bracket (function)](#bracket-function)
-- [chainEither (function)](#chaineither-function)
+- [chainEitherK (function)](#chaineitherk-function)
 - [fold (function)](#fold-function)
+- [fromEitherK (function)](#fromeitherk-function)
 - [getApplyMonoid (function)](#getapplymonoid-function)
 - [getApplySemigroup (function)](#getapplysemigroup-function)
 - [getFilterable (function)](#getfilterable-function)
@@ -161,12 +162,12 @@ export function bracket<E, A, B>(
 
 Added in v2.0.0
 
-# chainEither (function)
+# chainEitherK (function)
 
 **Signature**
 
 ```ts
-export function chainEither<E, A, B>(f: (a: A) => Either<E, B>): (ma: IOEither<E, A>) => IOEither<E, B> { ... }
+export function chainEitherK<E, A, B>(f: (a: A) => Either<E, B>): (ma: IOEither<E, A>) => IOEither<E, B> { ... }
 ```
 
 Added in v2.4.0
@@ -181,6 +182,16 @@ export function fold<E, A, B>(onLeft: (e: E) => IO<B>, onRight: (a: A) => IO<B>)
 
 Added in v2.0.0
 
+# fromEitherK (function)
+
+**Signature**
+
+```ts
+export function fromEitherK<E, A extends Array<unknown>, B>(f: (...a: A) => Either<E, B>): (...a: A) => IOEither<E, B> { ... }
+```
+
+Added in v2.4.0
+
 # getApplyMonoid (function)
 
 **Signature**
diff --git a/docs/modules/ReaderEither.ts.md b/docs/modules/ReaderEither.ts.md
index e9fa2b69..3e7c1415 100644
--- a/docs/modules/ReaderEither.ts.md
+++ b/docs/modules/ReaderEither.ts.md
@@ -23,8 +23,9 @@ Added in v2.0.0
 - [swap (constant)](#swap-constant)
 - [ask (function)](#ask-function)
 - [asks (function)](#asks-function)
-- [chainEither (function)](#chaineither-function)
+- [chainEitherK (function)](#chaineitherk-function)
 - [fold (function)](#fold-function)
+- [fromEitherK (function)](#fromeitherk-function)
 - [getApplyMonoid (function)](#getapplymonoid-function)
 - [getApplySemigroup (function)](#getapplysemigroup-function)
 - [getOrElse (function)](#getorelse-function)
@@ -159,12 +160,12 @@ export function asks<R, E = never, A = never>(f: (r: R) => A): ReaderEither<R, E
 
 Added in v2.0.0
 
-# chainEither (function)
+# chainEitherK (function)
 
 **Signature**
 
 ```ts
-export function chainEither<E, A, B>(
+export function chainEitherK<E, A, B>(
   f: (a: A) => Either<E, B>
 ): <R>(ma: ReaderEither<R, E, A>) => ReaderEither<R, E, B> { ... }
 ```
@@ -184,6 +185,18 @@ export function fold<R, E, A, B>(
 
 Added in v2.0.0
 
+# fromEitherK (function)
+
+**Signature**
+
+```ts
+export function fromEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => Either<E, B>
+): <R>(...a: A) => ReaderEither<R, E, B> { ... }
+```
+
+Added in v2.4.0
+
 # getApplyMonoid (function)
 
 **Signature**
diff --git a/docs/modules/ReaderTask.ts.md b/docs/modules/ReaderTask.ts.md
index 62fb1d5b..3217b172 100644
--- a/docs/modules/ReaderTask.ts.md
+++ b/docs/modules/ReaderTask.ts.md
@@ -22,9 +22,11 @@ Added in v2.3.0
 - [of (constant)](#of-constant)
 - [readerTask (constant)](#readertask-constant)
 - [readerTaskSeq (constant)](#readertaskseq-constant)
-- [chainIO (function)](#chainio-function)
-- [chainTask (function)](#chaintask-function)
+- [chainIOK (function)](#chainiok-function)
+- [chainTaskK (function)](#chaintaskk-function)
 - [fromIO (function)](#fromio-function)
+- [fromIOK (function)](#fromiok-function)
+- [fromTaskK (function)](#fromtaskk-function)
 - [getMonoid (function)](#getmonoid-function)
 - [getSemigroup (function)](#getsemigroup-function)
 - [local (function)](#local-function)
@@ -143,22 +145,22 @@ export const readerTaskSeq: typeof readerTask = ...
 
 Added in v2.3.0
 
-# chainIO (function)
+# chainIOK (function)
 
 **Signature**
 
 ```ts
-export function chainIO<A, B>(f: (a: A) => IO<B>): <R>(ma: ReaderTask<R, A>) => ReaderTask<R, B> { ... }
+export function chainIOK<A, B>(f: (a: A) => IO<B>): <R>(ma: ReaderTask<R, A>) => ReaderTask<R, B> { ... }
 ```
 
 Added in v2.4.0
 
-# chainTask (function)
+# chainTaskK (function)
 
 **Signature**
 
 ```ts
-export function chainTask<A, B>(f: (a: A) => Task<B>): <R>(ma: ReaderTask<R, A>) => ReaderTask<R, B> { ... }
+export function chainTaskK<A, B>(f: (a: A) => Task<B>): <R>(ma: ReaderTask<R, A>) => ReaderTask<R, B> { ... }
 ```
 
 Added in v2.4.0
@@ -173,6 +175,26 @@ export function fromIO<R, A>(ma: IO<A>): ReaderTask<R, A> { ... }
 
 Added in v2.3.0
 
+# fromIOK (function)
+
+**Signature**
+
+```ts
+export function fromIOK<A extends Array<unknown>, B>(f: (...a: A) => IO<B>): <R>(...a: A) => ReaderTask<R, B> { ... }
+```
+
+Added in v2.4.0
+
+# fromTaskK (function)
+
+**Signature**
+
+```ts
+export function fromTaskK<A extends Array<unknown>, B>(f: (...a: A) => Task<B>): <R>(...a: A) => ReaderTask<R, B> { ... }
+```
+
+Added in v2.4.0
+
 # getMonoid (function)
 
 **Signature**
diff --git a/docs/modules/ReaderTaskEither.ts.md b/docs/modules/ReaderTaskEither.ts.md
index 55ab8b08..f9e4b26c 100644
--- a/docs/modules/ReaderTaskEither.ts.md
+++ b/docs/modules/ReaderTaskEither.ts.md
@@ -23,12 +23,15 @@ Added in v2.0.0
 - [right (constant)](#right-constant)
 - [rightReader (constant)](#rightreader-constant)
 - [bracket (function)](#bracket-function)
-- [chainEither (function)](#chaineither-function)
-- [chainIOEither (function)](#chainioeither-function)
-- [chainTaskEither (function)](#chaintaskeither-function)
+- [chainEitherK (function)](#chaineitherk-function)
+- [chainIOEitherK (function)](#chainioeitherk-function)
+- [chainTaskEitherK (function)](#chaintaskeitherk-function)
 - [fold (function)](#fold-function)
+- [fromEitherK (function)](#fromeitherk-function)
 - [fromIOEither (function)](#fromioeither-function)
+- [fromIOEitherK (function)](#fromioeitherk-function)
 - [fromReaderEither (function)](#fromreadereither-function)
+- [fromTaskEitherK (function)](#fromtaskeitherk-function)
 - [getApplyMonoid (function)](#getapplymonoid-function)
 - [getApplySemigroup (function)](#getapplysemigroup-function)
 - [getOrElse (function)](#getorelse-function)
@@ -184,36 +187,36 @@ export function bracket<R, E, A, B>(
 
 Added in v2.0.4
 
-# chainEither (function)
+# chainEitherK (function)
 
 **Signature**
 
 ```ts
-export function chainEither<E, A, B>(
+export function chainEitherK<E, A, B>(
   f: (a: A) => Either<E, B>
 ): <R>(ma: ReaderTaskEither<R, E, A>) => ReaderTaskEither<R, E, B> { ... }
 ```
 
 Added in v2.4.0
 
-# chainIOEither (function)
+# chainIOEitherK (function)
 
 **Signature**
 
 ```ts
-export function chainIOEither<E, A, B>(
+export function chainIOEitherK<E, A, B>(
   f: (a: A) => IOEither<E, B>
 ): <R>(ma: ReaderTaskEither<R, E, A>) => ReaderTaskEither<R, E, B> { ... }
 ```
 
 Added in v2.4.0
 
-# chainTaskEither (function)
+# chainTaskEitherK (function)
 
 **Signature**
 
 ```ts
-export function chainTaskEither<E, A, B>(
+export function chainTaskEitherK<E, A, B>(
   f: (a: A) => TaskEither<E, B>
 ): <R>(ma: ReaderTaskEither<R, E, A>) => ReaderTaskEither<R, E, B> { ... }
 ```
@@ -233,6 +236,18 @@ export function fold<R, E, A, B>(
 
 Added in v2.0.0
 
+# fromEitherK (function)
+
+**Signature**
+
+```ts
+export function fromEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => Either<E, B>
+): <R>(...a: A) => ReaderTaskEither<R, E, B> { ... }
+```
+
+Added in v2.4.0
+
 # fromIOEither (function)
 
 **Signature**
@@ -243,6 +258,18 @@ export function fromIOEither<R, E, A>(ma: IOEither<E, A>): ReaderTaskEither<R, E
 
 Added in v2.0.0
 
+# fromIOEitherK (function)
+
+**Signature**
+
+```ts
+export function fromIOEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => IOEither<E, B>
+): <R>(...a: A) => ReaderTaskEither<R, E, B> { ... }
+```
+
+Added in v2.4.0
+
 # fromReaderEither (function)
 
 **Signature**
@@ -253,6 +280,18 @@ export function fromReaderEither<R, E, A>(ma: ReaderEither<R, E, A>): ReaderTask
 
 Added in v2.0.0
 
+# fromTaskEitherK (function)
+
+**Signature**
+
+```ts
+export function fromTaskEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => TaskEither<E, B>
+): <R>(...a: A) => ReaderTaskEither<R, E, B> { ... }
+```
+
+Added in v2.4.0
+
 # getApplyMonoid (function)
 
 **Signature**
diff --git a/docs/modules/StateReaderTaskEither.ts.md b/docs/modules/StateReaderTaskEither.ts.md
index 8086fa69..03228d02 100644
--- a/docs/modules/StateReaderTaskEither.ts.md
+++ b/docs/modules/StateReaderTaskEither.ts.md
@@ -26,13 +26,17 @@ Added in v2.0.0
 - [rightState (constant)](#rightstate-constant)
 - [stateReaderTaskEither (constant)](#statereadertaskeither-constant)
 - [stateReaderTaskEitherSeq (constant)](#statereadertaskeitherseq-constant)
-- [chainEither (function)](#chaineither-function)
-- [chainIOEither (function)](#chainioeither-function)
-- [chainReaderTaskEither (function)](#chainreadertaskeither-function)
-- [chainTaskEither (function)](#chaintaskeither-function)
+- [chainEitherK (function)](#chaineitherk-function)
+- [chainIOEitherK (function)](#chainioeitherk-function)
+- [chainReaderTaskEitherK (function)](#chainreadertaskeitherk-function)
+- [chainTaskEitherK (function)](#chaintaskeitherk-function)
+- [fromEitherK (function)](#fromeitherk-function)
 - [fromIOEither (function)](#fromioeither-function)
+- [fromIOEitherK (function)](#fromioeitherk-function)
 - [fromReaderEither (function)](#fromreadereither-function)
+- [fromReaderTaskEitherK (function)](#fromreadertaskeitherk-function)
 - [fromTaskEither (function)](#fromtaskeither-function)
+- [fromTaskEitherK (function)](#fromtaskeitherk-function)
 - [left (function)](#left-function)
 - [leftIO (function)](#leftio-function)
 - [leftReader (function)](#leftreader-function)
@@ -210,54 +214,66 @@ export const stateReaderTaskEitherSeq: typeof stateReaderTaskEither = ...
 
 Added in v2.0.0
 
-# chainEither (function)
+# chainEitherK (function)
 
 **Signature**
 
 ```ts
-export function chainEither<E, A, B>(
+export function chainEitherK<E, A, B>(
   f: (a: A) => Either<E, B>
 ): <S, R>(ma: StateReaderTaskEither<S, R, E, A>) => StateReaderTaskEither<S, R, E, B> { ... }
 ```
 
 Added in v2.4.0
 
-# chainIOEither (function)
+# chainIOEitherK (function)
 
 **Signature**
 
 ```ts
-export function chainIOEither<E, A, B>(
+export function chainIOEitherK<E, A, B>(
   f: (a: A) => IOEither<E, B>
 ): <S, R>(ma: StateReaderTaskEither<S, R, E, A>) => StateReaderTaskEither<S, R, E, B> { ... }
 ```
 
 Added in v2.4.0
 
-# chainReaderTaskEither (function)
+# chainReaderTaskEitherK (function)
 
 **Signature**
 
 ```ts
-export function chainReaderTaskEither<R, E, A, B>(
+export function chainReaderTaskEitherK<R, E, A, B>(
   f: (a: A) => ReaderTaskEither<R, E, B>
 ): <S>(ma: StateReaderTaskEither<S, R, E, A>) => StateReaderTaskEither<S, R, E, B> { ... }
 ```
 
 Added in v2.4.0
 
-# chainTaskEither (function)
+# chainTaskEitherK (function)
 
 **Signature**
 
 ```ts
-export function chainTaskEither<E, A, B>(
+export function chainTaskEitherK<E, A, B>(
   f: (a: A) => TaskEither<E, B>
 ): <S, R>(ma: StateReaderTaskEither<S, R, E, A>) => StateReaderTaskEither<S, R, E, B> { ... }
 ```
 
 Added in v2.4.0
 
+# fromEitherK (function)
+
+**Signature**
+
+```ts
+export function fromEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => Either<E, B>
+): <S, R>(...a: A) => StateReaderTaskEither<S, R, E, B> { ... }
+```
+
+Added in v2.4.0
+
 # fromIOEither (function)
 
 **Signature**
@@ -268,6 +284,18 @@ export function fromIOEither<S, R, E, A>(ma: IOEither<E, A>): StateReaderTaskEit
 
 Added in v2.0.0
 
+# fromIOEitherK (function)
+
+**Signature**
+
+```ts
+export function fromIOEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => IOEither<E, B>
+): <S, R>(...a: A) => StateReaderTaskEither<S, R, E, B> { ... }
+```
+
+Added in v2.4.0
+
 # fromReaderEither (function)
 
 **Signature**
@@ -278,6 +306,18 @@ export function fromReaderEither<S, R, E, A>(ma: ReaderEither<R, E, A>): StateRe
 
 Added in v2.0.0
 
+# fromReaderTaskEitherK (function)
+
+**Signature**
+
+```ts
+export function fromReaderTaskEitherK<R, E, A extends Array<unknown>, B>(
+  f: (...a: A) => ReaderTaskEither<R, E, B>
+): <S>(...a: A) => StateReaderTaskEither<S, R, E, B> { ... }
+```
+
+Added in v2.4.0
+
 # fromTaskEither (function)
 
 **Signature**
@@ -288,6 +328,18 @@ export function fromTaskEither<S, R, E, A>(ma: TaskEither<E, A>): StateReaderTas
 
 Added in v2.0.0
 
+# fromTaskEitherK (function)
+
+**Signature**
+
+```ts
+export function fromTaskEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => TaskEither<E, B>
+): <S, R>(...a: A) => StateReaderTaskEither<S, R, E, B> { ... }
+```
+
+Added in v2.4.0
+
 # left (function)
 
 **Signature**
diff --git a/docs/modules/Task.ts.md b/docs/modules/Task.ts.md
index a0b06835..31c10bda 100644
--- a/docs/modules/Task.ts.md
+++ b/docs/modules/Task.ts.md
@@ -20,9 +20,10 @@ Added in v2.0.0
 - [URI (constant)](#uri-constant)
 - [task (constant)](#task-constant)
 - [taskSeq (constant)](#taskseq-constant)
-- [chainIO (function)](#chainio-function)
+- [chainIOK (function)](#chainiok-function)
 - [delay (function)](#delay-function)
 - [fromIO (function)](#fromio-function)
+- [fromIOK (function)](#fromiok-function)
 - [getMonoid (function)](#getmonoid-function)
 - [getRaceMonoid (function)](#getracemonoid-function)
 - [getSemigroup (function)](#getsemigroup-function)
@@ -92,12 +93,12 @@ export const taskSeq: typeof task = ...
 
 Added in v2.0.0
 
-# chainIO (function)
+# chainIOK (function)
 
 **Signature**
 
 ```ts
-export function chainIO<A, B>(f: (a: A) => IO<B>): (ma: Task<A>) => Task<B> { ... }
+export function chainIOK<A, B>(f: (a: A) => IO<B>): (ma: Task<A>) => Task<B> { ... }
 ```
 
 Added in v2.4.0
@@ -122,6 +123,16 @@ export function fromIO<A>(ma: IO<A>): Task<A> { ... }
 
 Added in v2.0.0
 
+# fromIOK (function)
+
+**Signature**
+
+```ts
+export function fromIOK<A extends Array<unknown>, B>(f: (...a: A) => IO<B>): (...a: A) => Task<B> { ... }
+```
+
+Added in v2.4.0
+
 # getMonoid (function)
 
 **Signature**
diff --git a/docs/modules/TaskEither.ts.md b/docs/modules/TaskEither.ts.md
index bfdd9b56..6684ce1b 100644
--- a/docs/modules/TaskEither.ts.md
+++ b/docs/modules/TaskEither.ts.md
@@ -27,9 +27,11 @@ Added in v2.0.0
 - [taskEither (constant)](#taskeither-constant)
 - [taskEitherSeq (constant)](#taskeitherseq-constant)
 - [bracket (function)](#bracket-function)
-- [chainEither (function)](#chaineither-function)
-- [chainIOEither (function)](#chainioeither-function)
+- [chainEitherK (function)](#chaineitherk-function)
+- [chainIOEitherK (function)](#chainioeitherk-function)
 - [fold (function)](#fold-function)
+- [fromEitherK (function)](#fromeitherk-function)
+- [fromIOEitherK (function)](#fromioeitherk-function)
 - [getApplyMonoid (function)](#getapplymonoid-function)
 - [getApplySemigroup (function)](#getapplysemigroup-function)
 - [getFilterable (function)](#getfilterable-function)
@@ -189,22 +191,22 @@ export function bracket<E, A, B>(
 
 Added in v2.0.0
 
-# chainEither (function)
+# chainEitherK (function)
 
 **Signature**
 
 ```ts
-export function chainEither<E, A, B>(f: (a: A) => Either<E, B>): (ma: TaskEither<E, A>) => TaskEither<E, B> { ... }
+export function chainEitherK<E, A, B>(f: (a: A) => Either<E, B>): (ma: TaskEither<E, A>) => TaskEither<E, B> { ... }
 ```
 
 Added in v2.4.0
 
-# chainIOEither (function)
+# chainIOEitherK (function)
 
 **Signature**
 
 ```ts
-export function chainIOEither<E, A, B>(f: (a: A) => IOEither<E, B>): (ma: TaskEither<E, A>) => TaskEither<E, B> { ... }
+export function chainIOEitherK<E, A, B>(f: (a: A) => IOEither<E, B>): (ma: TaskEither<E, A>) => TaskEither<E, B> { ... }
 ```
 
 Added in v2.4.0
@@ -222,6 +224,30 @@ export function fold<E, A, B>(
 
 Added in v2.0.0
 
+# fromEitherK (function)
+
+**Signature**
+
+```ts
+export function fromEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => Either<E, B>
+): (...a: A) => TaskEither<E, B> { ... }
+```
+
+Added in v2.4.0
+
+# fromIOEitherK (function)
+
+**Signature**
+
+```ts
+export function fromIOEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => IOEither<E, B>
+): (...a: A) => TaskEither<E, B> { ... }
+```
+
+Added in v2.4.0
+
 # getApplyMonoid (function)
 
 **Signature**
diff --git a/src/IOEither.ts b/src/IOEither.ts
index b9f3e358..09af49ce 100644
--- a/src/IOEither.ts
+++ b/src/IOEither.ts
@@ -175,8 +175,15 @@ export function getFilterable<E>(M: Monoid<E>): Filterable2C<URI, E> {
 /**
  * @since 2.4.0
  */
-export function chainEither<E, A, B>(f: (a: A) => Either<E, B>): (ma: IOEither<E, A>) => IOEither<E, B> {
-  return chain(a => fromEither(f(a)))
+export function fromEitherK<E, A extends Array<unknown>, B>(f: (...a: A) => Either<E, B>): (...a: A) => IOEither<E, B> {
+  return (...a) => fromEither(f(...a))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function chainEitherK<E, A, B>(f: (a: A) => Either<E, B>): (ma: IOEither<E, A>) => IOEither<E, B> {
+  return chain(fromEitherK(f))
 }
 
 /**
diff --git a/src/ReaderEither.ts b/src/ReaderEither.ts
index e8a55e40..1cfcf647 100644
--- a/src/ReaderEither.ts
+++ b/src/ReaderEither.ts
@@ -154,10 +154,19 @@ export function getReaderValidation<E>(
 /**
  * @since 2.4.0
  */
-export function chainEither<E, A, B>(
+export function fromEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => Either<E, B>
+): <R>(...a: A) => ReaderEither<R, E, B> {
+  return (...a) => fromEither(f(...a))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function chainEitherK<E, A, B>(
   f: (a: A) => Either<E, B>
 ): <R>(ma: ReaderEither<R, E, A>) => ReaderEither<R, E, B> {
-  return chain(a => fromEither(f(a)))
+  return chain<any, E, A, B>(fromEitherK(f))
 }
 
 /**
diff --git a/src/ReaderTask.ts b/src/ReaderTask.ts
index 0e8f9057..4d3cad7c 100644
--- a/src/ReaderTask.ts
+++ b/src/ReaderTask.ts
@@ -104,15 +104,29 @@ export function local<Q, R>(f: (f: Q) => R): <E, A>(ma: ReaderTask<R, A>) => Rea
 /**
  * @since 2.4.0
  */
-export function chainIO<A, B>(f: (a: A) => IO<B>): <R>(ma: ReaderTask<R, A>) => ReaderTask<R, B> {
-  return chain(a => fromIO(f(a)))
+export function fromIOK<A extends Array<unknown>, B>(f: (...a: A) => IO<B>): <R>(...a: A) => ReaderTask<R, B> {
+  return (...a) => fromIO(f(...a))
 }
 
 /**
  * @since 2.4.0
  */
-export function chainTask<A, B>(f: (a: A) => Task<B>): <R>(ma: ReaderTask<R, A>) => ReaderTask<R, B> {
-  return chain(a => fromTask(f(a)))
+export function chainIOK<A, B>(f: (a: A) => IO<B>): <R>(ma: ReaderTask<R, A>) => ReaderTask<R, B> {
+  return chain<any, A, B>(fromIOK(f))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function fromTaskK<A extends Array<unknown>, B>(f: (...a: A) => Task<B>): <R>(...a: A) => ReaderTask<R, B> {
+  return (...a) => fromTask(f(...a))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function chainTaskK<A, B>(f: (a: A) => Task<B>): <R>(ma: ReaderTask<R, A>) => ReaderTask<R, B> {
+  return chain<any, A, B>(fromTaskK(f))
 }
 
 /**
diff --git a/src/ReaderTaskEither.ts b/src/ReaderTaskEither.ts
index 35e8aad4..b038627e 100644
--- a/src/ReaderTaskEither.ts
+++ b/src/ReaderTaskEither.ts
@@ -251,28 +251,55 @@ export function getReaderTaskValidation<E>(
 /**
  * @since 2.4.0
  */
-export function chainEither<E, A, B>(
+export function fromEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => Either<E, B>
+): <R>(...a: A) => ReaderTaskEither<R, E, B> {
+  return (...a) => fromEither(f(...a))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function chainEitherK<E, A, B>(
   f: (a: A) => Either<E, B>
 ): <R>(ma: ReaderTaskEither<R, E, A>) => ReaderTaskEither<R, E, B> {
-  return chain(a => fromEither(f(a)))
+  return chain<any, E, A, B>(fromEitherK(f))
 }
 
 /**
  * @since 2.4.0
  */
-export function chainIOEither<E, A, B>(
+export function fromIOEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => IOEither<E, B>
+): <R>(...a: A) => ReaderTaskEither<R, E, B> {
+  return (...a) => fromIOEither(f(...a))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function chainIOEitherK<E, A, B>(
   f: (a: A) => IOEither<E, B>
 ): <R>(ma: ReaderTaskEither<R, E, A>) => ReaderTaskEither<R, E, B> {
-  return chain(a => fromIOEither(f(a)))
+  return chain<any, E, A, B>(fromIOEitherK(f))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function fromTaskEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => TaskEither<E, B>
+): <R>(...a: A) => ReaderTaskEither<R, E, B> {
+  return (...a) => fromTaskEither(f(...a))
 }
 
 /**
  * @since 2.4.0
  */
-export function chainTaskEither<E, A, B>(
+export function chainTaskEitherK<E, A, B>(
   f: (a: A) => TaskEither<E, B>
 ): <R>(ma: ReaderTaskEither<R, E, A>) => ReaderTaskEither<R, E, B> {
-  return chain(a => fromTaskEither(f(a)))
+  return chain<any, E, A, B>(fromTaskEitherK(f))
 }
 
 /**
diff --git a/src/StateReaderTaskEither.ts b/src/StateReaderTaskEither.ts
index eae4dae9..b5e05de5 100644
--- a/src/StateReaderTaskEither.ts
+++ b/src/StateReaderTaskEither.ts
@@ -190,37 +190,73 @@ export const gets: <S, R, E = never, A = never>(f: (s: S) => A) => StateReaderTa
 /**
  * @since 2.4.0
  */
-export function chainEither<E, A, B>(
+export function fromEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => Either<E, B>
+): <S, R>(...a: A) => StateReaderTaskEither<S, R, E, B> {
+  return (...a) => fromEither(f(...a))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function chainEitherK<E, A, B>(
   f: (a: A) => Either<E, B>
 ): <S, R>(ma: StateReaderTaskEither<S, R, E, A>) => StateReaderTaskEither<S, R, E, B> {
-  return chain(a => fromEither(f(a)))
+  return chain<any, any, E, A, B>(fromEitherK(f))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function fromIOEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => IOEither<E, B>
+): <S, R>(...a: A) => StateReaderTaskEither<S, R, E, B> {
+  return (...a) => fromIOEither(f(...a))
 }
 
 /**
  * @since 2.4.0
  */
-export function chainIOEither<E, A, B>(
+export function chainIOEitherK<E, A, B>(
   f: (a: A) => IOEither<E, B>
 ): <S, R>(ma: StateReaderTaskEither<S, R, E, A>) => StateReaderTaskEither<S, R, E, B> {
-  return chain(a => fromIOEither(f(a)))
+  return chain<any, any, E, A, B>(fromIOEitherK(f))
 }
 
 /**
  * @since 2.4.0
  */
-export function chainTaskEither<E, A, B>(
+export function fromTaskEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => TaskEither<E, B>
+): <S, R>(...a: A) => StateReaderTaskEither<S, R, E, B> {
+  return (...a) => fromTaskEither(f(...a))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function chainTaskEitherK<E, A, B>(
   f: (a: A) => TaskEither<E, B>
 ): <S, R>(ma: StateReaderTaskEither<S, R, E, A>) => StateReaderTaskEither<S, R, E, B> {
-  return chain(a => fromTaskEither(f(a)))
+  return chain<any, any, E, A, B>(fromTaskEitherK(f))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function fromReaderTaskEitherK<R, E, A extends Array<unknown>, B>(
+  f: (...a: A) => ReaderTaskEither<R, E, B>
+): <S>(...a: A) => StateReaderTaskEither<S, R, E, B> {
+  return (...a) => fromReaderTaskEither(f(...a))
 }
 
 /**
  * @since 2.4.0
  */
-export function chainReaderTaskEither<R, E, A, B>(
+export function chainReaderTaskEitherK<R, E, A, B>(
   f: (a: A) => ReaderTaskEither<R, E, B>
 ): <S>(ma: StateReaderTaskEither<S, R, E, A>) => StateReaderTaskEither<S, R, E, B> {
-  return chain(a => fromReaderTaskEither(f(a)))
+  return chain<any, any, E, A, B>(fromReaderTaskEitherK(f))
 }
 
 /**
diff --git a/src/Task.ts b/src/Task.ts
index 4a91baff..f6f292af 100644
--- a/src/Task.ts
+++ b/src/Task.ts
@@ -117,8 +117,15 @@ export function of<A>(a: A): Task<A> {
 /**
  * @since 2.4.0
  */
-export function chainIO<A, B>(f: (a: A) => IO<B>): (ma: Task<A>) => Task<B> {
-  return chain(a => fromIO(f(a)))
+export function fromIOK<A extends Array<unknown>, B>(f: (...a: A) => IO<B>): (...a: A) => Task<B> {
+  return (...a) => fromIO(f(...a))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function chainIOK<A, B>(f: (a: A) => IO<B>): (ma: Task<A>) => Task<B> {
+  return chain(fromIOK(f))
 }
 
 /**
diff --git a/src/TaskEither.ts b/src/TaskEither.ts
index a275c723..0192a419 100644
--- a/src/TaskEither.ts
+++ b/src/TaskEither.ts
@@ -269,15 +269,33 @@ export function getFilterable<E>(M: Monoid<E>): Filterable2C<URI, E> {
 /**
  * @since 2.4.0
  */
-export function chainEither<E, A, B>(f: (a: A) => Either<E, B>): (ma: TaskEither<E, A>) => TaskEither<E, B> {
-  return chain(a => fromEither(f(a)))
+export function fromEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => Either<E, B>
+): (...a: A) => TaskEither<E, B> {
+  return (...a) => fromEither(f(...a))
 }
 
 /**
  * @since 2.4.0
  */
-export function chainIOEither<E, A, B>(f: (a: A) => IOEither<E, B>): (ma: TaskEither<E, A>) => TaskEither<E, B> {
-  return chain(a => fromIOEither(f(a)))
+export function chainEitherK<E, A, B>(f: (a: A) => Either<E, B>): (ma: TaskEither<E, A>) => TaskEither<E, B> {
+  return chain(fromEitherK(f))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function fromIOEitherK<E, A extends Array<unknown>, B>(
+  f: (...a: A) => IOEither<E, B>
+): (...a: A) => TaskEither<E, B> {
+  return (...a) => fromIOEither(f(...a))
+}
+
+/**
+ * @since 2.4.0
+ */
+export function chainIOEitherK<E, A, B>(f: (a: A) => IOEither<E, B>): (ma: TaskEither<E, A>) => TaskEither<E, B> {
+  return chain(fromIOEitherK(f))
 }
 
 /**


Test patch:
diff --git a/test/IOEither.ts b/test/IOEither.ts
index dc9a117a..f7728a24 100644
--- a/test/IOEither.ts
+++ b/test/IOEither.ts
@@ -311,9 +311,9 @@ describe('IOEither', () => {
     })
   })
 
-  it('chainEither', () => {
+  it('chainEitherK', () => {
     const f = (s: string) => E.right(s.length)
-    const x = pipe(_.right('a'), _.chainEither(f))()
+    const x = pipe(_.right('a'), _.chainEitherK(f))()
     assert.deepStrictEqual(x, E.right(1))
   })
 })
diff --git a/test/ReaderEither.ts b/test/ReaderEither.ts
index 08a12dc4..034f5f4b 100644
--- a/test/ReaderEither.ts
+++ b/test/ReaderEither.ts
@@ -131,9 +131,9 @@ describe('ReaderEither', () => {
     })
   })
 
-  it('chainEither', () => {
+  it('chainEitherK', () => {
     const f = (s: string) => E.right(s.length)
-    const x = pipe(_.right('a'), _.chainEither(f))(undefined)
+    const x = pipe(_.right('a'), _.chainEitherK(f))(undefined)
     assert.deepStrictEqual(x, E.right(1))
   })
 })
diff --git a/test/ReaderTask.ts b/test/ReaderTask.ts
index 7a1fab55..a0a48b28 100644
--- a/test/ReaderTask.ts
+++ b/test/ReaderTask.ts
@@ -119,15 +119,15 @@ describe('ReaderTask', () => {
     })
   })
 
-  it('chainIO', async () => {
+  it('chainIOK', async () => {
     const f = (s: string) => I.of(s.length)
-    const x = await _.run(pipe(_.of('a'), _.chainIO(f)), undefined)
+    const x = await _.run(pipe(_.of('a'), _.chainIOK(f)), undefined)
     assert.deepStrictEqual(x, 1)
   })
 
-  it('chainTask', async () => {
+  it('chainTaskK', async () => {
     const f = (s: string) => T.of(s.length)
-    const x = await _.run(pipe(_.of('a'), _.chainTask(f)), undefined)
+    const x = await _.run(pipe(_.of('a'), _.chainTaskK(f)), undefined)
     assert.deepStrictEqual(x, 1)
   })
 })
diff --git a/test/ReaderTaskEither.ts b/test/ReaderTaskEither.ts
index e86064e2..394de4b8 100644
--- a/test/ReaderTaskEither.ts
+++ b/test/ReaderTaskEither.ts
@@ -456,21 +456,21 @@ describe('ReaderTaskEither', () => {
     })
   })
 
-  it('chainEither', async () => {
+  it('chainEitherK', async () => {
     const f = (s: string) => E.right(s.length)
-    const x = await _.run(pipe(_.right('a'), _.chainEither(f)), undefined)
+    const x = await _.run(pipe(_.right('a'), _.chainEitherK(f)), undefined)
     assert.deepStrictEqual(x, E.right(1))
   })
 
-  it('chainIOEither', async () => {
+  it('chainIOEitherK', async () => {
     const f = (s: string) => IE.right(s.length)
-    const x = await _.run(pipe(_.right('a'), _.chainIOEither(f)), undefined)
+    const x = await _.run(pipe(_.right('a'), _.chainIOEitherK(f)), undefined)
     assert.deepStrictEqual(x, E.right(1))
   })
 
-  it('chainTaskEither', async () => {
+  it('chainTaskEitherK', async () => {
     const f = (s: string) => TE.right(s.length)
-    const x = await _.run(pipe(_.right('a'), _.chainTaskEither(f)), undefined)
+    const x = await _.run(pipe(_.right('a'), _.chainTaskEitherK(f)), undefined)
     assert.deepStrictEqual(x, E.right(1))
   })
 })
diff --git a/test/StateReaderTaskEither.ts b/test/StateReaderTaskEither.ts
index 71978a34..307875f2 100644
--- a/test/StateReaderTaskEither.ts
+++ b/test/StateReaderTaskEither.ts
@@ -151,27 +151,27 @@ describe('StateReaderTaskEither', () => {
     assert.deepStrictEqual(e2, E.right([1, {}]))
   })
 
-  it('chainEither', async () => {
+  it('chainEitherK', async () => {
     const f = (s: string) => E.right(s.length)
-    const x = await _.run(pipe(_.right('a'), _.chainEither(f)), undefined, undefined)
+    const x = await _.run(pipe(_.right('a'), _.chainEitherK(f)), undefined, undefined)
     assert.deepStrictEqual(x, E.right([1, undefined]))
   })
 
-  it('chainIOEither', async () => {
+  it('chainIOEitherK', async () => {
     const f = (s: string) => IE.right(s.length)
-    const x = await _.run(pipe(_.right('a'), _.chainIOEither(f)), undefined, undefined)
+    const x = await _.run(pipe(_.right('a'), _.chainIOEitherK(f)), undefined, undefined)
     assert.deepStrictEqual(x, E.right([1, undefined]))
   })
 
-  it('chainTaskEither', async () => {
+  it('chainTaskEitherK', async () => {
     const f = (s: string) => TE.right(s.length)
-    const x = await _.run(pipe(_.right('a'), _.chainTaskEither(f)), undefined, undefined)
+    const x = await _.run(pipe(_.right('a'), _.chainTaskEitherK(f)), undefined, undefined)
     assert.deepStrictEqual(x, E.right([1, undefined]))
   })
 
-  it('chainReaderTaskEither', async () => {
+  it('chainReaderTaskEitherK', async () => {
     const f = (s: string) => RTE.right(s.length)
-    const x = await _.run(pipe(_.right('a'), _.chainReaderTaskEither(f)), undefined, undefined)
+    const x = await _.run(pipe(_.right('a'), _.chainReaderTaskEitherK(f)), undefined, undefined)
     assert.deepStrictEqual(x, E.right([1, undefined]))
   })
 })
diff --git a/test/Task.ts b/test/Task.ts
index f1d11843..8a172994 100644
--- a/test/Task.ts
+++ b/test/Task.ts
@@ -122,9 +122,9 @@ describe('Task', () => {
     })
   })
 
-  it('chainIO', async () => {
+  it('chainIOK', async () => {
     const f = (s: string) => I.of(s.length)
-    const x = await pipe(_.of('a'), _.chainIO(f))()
+    const x = await pipe(_.of('a'), _.chainIOK(f))()
     assert.deepStrictEqual(x, 1)
   })
 })
diff --git a/test/TaskEither.ts b/test/TaskEither.ts
index 382161ff..81d5627a 100644
--- a/test/TaskEither.ts
+++ b/test/TaskEither.ts
@@ -364,15 +364,15 @@ describe('TaskEither', () => {
     })
   })
 
-  it('chainEither', async () => {
+  it('chainEitherK', async () => {
     const f = (s: string) => E.right(s.length)
-    const x = await pipe(_.right('a'), _.chainEither(f))()
+    const x = await pipe(_.right('a'), _.chainEitherK(f))()
     assert.deepStrictEqual(x, E.right(1))
   })
 
-  it('chainIOEither', async () => {
+  it('chainIOEitherK', async () => {
     const f = (s: string) => ioEither.of(s.length)
-    const x = await pipe(_.right('a'), _.chainIOEither(f))()
+    const x = await pipe(_.right('a'), _.chainIOEitherK(f))()
     assert.deepStrictEqual(x, E.right(1))
   })
 })