Repository: gcanti/fp-ts
Pull request #1027 (2019-11-24 10:11:12)

add Alt instance to NonEmptyArray


Patch:
diff --git a/docs/modules/NonEmptyArray.ts.md b/docs/modules/NonEmptyArray.ts.md
index dfa78965..65c5192c 100644
--- a/docs/modules/NonEmptyArray.ts.md
+++ b/docs/modules/NonEmptyArray.ts.md
@@ -23,6 +23,7 @@ Data structure which represents non-empty arrays
 - [of (constant)](#of-constant)
 - [reverse (constant)](#reverse-constant)
 - [snoc (constant)](#snoc-constant)
+- [concat (function)](#concat-function)
 - [filter (function)](#filter-function)
 - [filterWithIndex (function)](#filterwithindex-function)
 - [fromArray (function)](#fromarray-function)
@@ -31,6 +32,7 @@ Data structure which represents non-empty arrays
 - [groupBy (function)](#groupby-function)
 - [groupSort (function)](#groupsort-function)
 - [head (function)](#head-function)
+- [init (function)](#init-function)
 - [insertAt (function)](#insertat-function)
 - [last (function)](#last-function)
 - [max (function)](#max-function)
@@ -160,7 +162,8 @@ export const nonEmptyArray: Monad1<URI> &
   Comonad1<URI> &
   TraversableWithIndex1<URI, number> &
   FunctorWithIndex1<URI, number> &
-  FoldableWithIndex1<URI, number> = ...
+  FoldableWithIndex1<URI, number> &
+  Alt1<URI> = ...
 ```
 
 Added in v2.0.0
@@ -205,6 +208,17 @@ assert.deepStrictEqual(snoc([1, 2, 3], 4), [1, 2, 3, 4])
 
 Added in v2.0.0
 
+# concat (function)
+
+**Signature**
+
+```ts
+export function concat<A>(fx: Array<A>, fy: NonEmptyArray<A>): NonEmptyArray<A>
+export function concat<A>(fx: NonEmptyArray<A>, fy: Array<A>): NonEmptyArray<A> { ... }
+```
+
+Added in v2.2.0
+
 # filter (function)
 
 **Signature**
@@ -330,6 +344,27 @@ export function head<A>(nea: NonEmptyArray<A>): A { ... }
 
 Added in v2.0.0
 
+# init (function)
+
+Get all but the last element of a non empty array, creating a new array.
+
+**Signature**
+
+```ts
+export function init<A>(nea: NonEmptyArray<A>): Array<A> { ... }
+```
+
+**Example**
+
+```ts
+import { init } from 'fp-ts/lib/NonEmptyArray'
+
+assert.deepStrictEqual(init([1, 2, 3]), [1, 2])
+assert.deepStrictEqual(init([1]), [])
+```
+
+Added in v2.2.0
+
 # insertAt (function)
 
 **Signature**
diff --git a/package-lock.json b/package-lock.json
index 5d7425bf..df415fcb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2819,7 +2819,8 @@
         "ansi-regex": {
           "version": "2.1.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "aproba": {
           "version": "1.2.0",
@@ -2840,12 +2841,14 @@
         "balanced-match": {
           "version": "1.0.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -2860,17 +2863,20 @@
         "code-point-at": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "concat-map": {
           "version": "0.0.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "console-control-strings": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -2987,7 +2993,8 @@
         "inherits": {
           "version": "2.0.3",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "ini": {
           "version": "1.3.5",
@@ -2999,6 +3006,7 @@
           "version": "1.0.0",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -3013,6 +3021,7 @@
           "version": "3.0.4",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
@@ -3020,12 +3029,14 @@
         "minimist": {
           "version": "0.0.8",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "minipass": {
           "version": "2.3.5",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.2",
             "yallist": "^3.0.0"
@@ -3044,6 +3055,7 @@
           "version": "0.5.1",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -3124,7 +3136,8 @@
         "number-is-nan": {
           "version": "1.0.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "object-assign": {
           "version": "4.1.1",
@@ -3136,6 +3149,7 @@
           "version": "1.4.0",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -3221,7 +3235,8 @@
         "safe-buffer": {
           "version": "5.1.2",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "safer-buffer": {
           "version": "2.1.2",
@@ -3257,6 +3272,7 @@
           "version": "1.0.2",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -3276,6 +3292,7 @@
           "version": "3.0.1",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -3319,12 +3336,14 @@
         "wrappy": {
           "version": "1.0.2",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "yallist": {
           "version": "3.0.3",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         }
       }
     },
diff --git a/src/Alt.ts b/src/Alt.ts
index 2da966ab..11f91851 100644
--- a/src/Alt.ts
+++ b/src/Alt.ts
@@ -8,7 +8,7 @@
  * 1. Associativity: `A.alt(A.alt(fa, ga), ha) = A.alt(fa, A.alt(ga, ha))`
  * 2. Distributivity: `A.map(A.alt(fa, ga), ab) = A.alt(A.map(fa, ab), A.map(ga, ab))`
  */
-import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor4 } from './Functor'
+import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor4, Functor3C } from './Functor'
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3, URIS4, Kind4 } from './HKT'
 
 /**
@@ -32,6 +32,13 @@ export interface Alt2<F extends URIS2> extends Functor2<F> {
   readonly alt: <E, A>(fx: Kind2<F, E, A>, fy: () => Kind2<F, E, A>) => Kind2<F, E, A>
 }
 
+/**
+ * @since 2.0.0
+ */
+export interface Alt2C<F extends URIS2, E> extends Functor2C<F, E> {
+  readonly alt: <A>(fx: Kind2<F, E, A>, fy: () => Kind2<F, E, A>) => Kind2<F, E, A>
+}
+
 /**
  * @since 2.0.0
  */
@@ -40,10 +47,10 @@ export interface Alt3<F extends URIS3> extends Functor3<F> {
 }
 
 /**
- * @since 2.0.0
+ * @since 2.2.0
  */
-export interface Alt2C<F extends URIS2, E> extends Functor2C<F, E> {
-  readonly alt: <A>(fx: Kind2<F, E, A>, fy: () => Kind2<F, E, A>) => Kind2<F, E, A>
+export interface Alt3C<F extends URIS3, E> extends Functor3C<F, E> {
+  readonly alt: <R, A>(fx: Kind3<F, R, E, A>, fy: () => Kind3<F, R, E, A>) => Kind3<F, R, E, A>
 }
 
 /**
diff --git a/src/Applicative.ts b/src/Applicative.ts
index f9d6c984..fb4ceb8a 100644
--- a/src/Applicative.ts
+++ b/src/Applicative.ts
@@ -15,7 +15,7 @@
  *
  * Note. `Functor`'s `map` can be derived: `A.map(x, f) = A.ap(A.of(f), x)`
  */
-import { Apply, Apply1, Apply2, Apply2C, Apply3, Apply4 } from './Apply'
+import { Apply, Apply1, Apply2, Apply2C, Apply3, Apply4, Apply3C } from './Apply'
 import {
   FunctorComposition,
   FunctorCompositionHKT1,
@@ -67,6 +67,13 @@ export interface Applicative3<F extends URIS3> extends Apply3<F> {
   readonly of: <R, E, A>(a: A) => Kind3<F, R, E, A>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface Applicative3C<F extends URIS3, E> extends Apply3C<F, E> {
+  readonly of: <R, A>(a: A) => Kind3<F, R, E, A>
+}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/Apply.ts b/src/Apply.ts
index e1af130a..e7e4290c 100644
--- a/src/Apply.ts
+++ b/src/Apply.ts
@@ -10,7 +10,7 @@
  *
  * Formally, `Apply` represents a strong lax semi-monoidal endofunctor.
  */
-import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor4 } from './Functor'
+import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor4, Functor3C } from './Functor'
 import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT'
 import { tuple } from './function'
 
@@ -35,6 +35,13 @@ export interface Apply2<F extends URIS2> extends Functor2<F> {
   readonly ap: <E, A, B>(fab: Kind2<F, E, (a: A) => B>, fa: Kind2<F, E, A>) => Kind2<F, E, B>
 }
 
+/**
+ * @since 2.0.0
+ */
+export interface Apply2C<F extends URIS2, E> extends Functor2C<F, E> {
+  readonly ap: <A, B>(fab: Kind2<F, E, (a: A) => B>, fa: Kind2<F, E, A>) => Kind2<F, E, B>
+}
+
 /**
  * @since 2.0.0
  */
@@ -43,10 +50,10 @@ export interface Apply3<F extends URIS3> extends Functor3<F> {
 }
 
 /**
- * @since 2.0.0
+ * @since 2.2.0
  */
-export interface Apply2C<F extends URIS2, E> extends Functor2C<F, E> {
-  readonly ap: <A, B>(fab: Kind2<F, E, (a: A) => B>, fa: Kind2<F, E, A>) => Kind2<F, E, B>
+export interface Apply3C<F extends URIS3, E> extends Functor3C<F, E> {
+  readonly ap: <R, A, B>(fab: Kind3<F, R, E, (a: A) => B>, fa: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
 }
 
 /**
@@ -96,6 +103,11 @@ export function sequenceT<F extends URIS3>(
 ): <R, E, T extends Array<Kind3<F, R, E, any>>>(
   ...t: T & { 0: Kind3<F, R, E, any> }
 ) => Kind3<F, R, E, { [K in keyof T]: [T[K]] extends [Kind3<F, R, E, infer A>] ? A : never }>
+export function sequenceT<F extends URIS3, E>(
+  F: Apply3C<F, E>
+): <R, T extends Array<Kind3<F, R, E, any>>>(
+  ...t: T & { 0: Kind3<F, R, E, any> }
+) => Kind3<F, R, E, { [K in keyof T]: [T[K]] extends [Kind3<F, R, E, infer A>] ? A : never }>
 export function sequenceT<F extends URIS2>(
   F: Apply2<F>
 ): <E, T extends Array<Kind2<F, E, any>>>(
@@ -182,6 +194,11 @@ export function sequenceS<F extends URIS3>(
 ): <R, E, NER extends Record<string, Kind3<F, R, E, any>>>(
   r: EnforceNonEmptyRecord<NER> & Record<string, Kind3<F, R, E, any>>
 ) => Kind3<F, R, E, { [K in keyof NER]: [NER[K]] extends [Kind3<F, any, any, infer A>] ? A : never }>
+export function sequenceS<F extends URIS3, E>(
+  F: Apply3C<F, E>
+): <R, NER extends Record<string, Kind3<F, R, E, any>>>(
+  r: EnforceNonEmptyRecord<NER> & Record<string, Kind3<F, R, E, any>>
+) => Kind3<F, R, E, { [K in keyof NER]: [NER[K]] extends [Kind3<F, any, any, infer A>] ? A : never }>
 export function sequenceS<F extends URIS2>(
   F: Apply2<F>
 ): <E, NER extends Record<string, Kind2<F, E, any>>>(
diff --git a/src/Bifunctor.ts b/src/Bifunctor.ts
index e0d0e91d..9f53d7df 100644
--- a/src/Bifunctor.ts
+++ b/src/Bifunctor.ts
@@ -37,6 +37,15 @@ export interface Bifunctor3<F extends URIS3> {
   readonly mapLeft: <R, E, A, G>(fea: Kind3<F, R, E, A>, f: (e: E) => G) => Kind3<F, R, G, A>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface Bifunctor3C<F extends URIS3, E> {
+  readonly URI: F
+  readonly bimap: <R, A, G, B>(fea: Kind3<F, R, E, A>, f: (e: E) => G, g: (a: A) => B) => Kind3<F, R, G, B>
+  readonly mapLeft: <R, A, G>(fea: Kind3<F, R, E, A>, f: (e: E) => G) => Kind3<F, R, G, A>
+}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/Chain.ts b/src/Chain.ts
index 0a1f849c..3572db1c 100644
--- a/src/Chain.ts
+++ b/src/Chain.ts
@@ -8,7 +8,7 @@
  *
  * Note. `Apply`'s `ap` can be derived: `(fab, fa) => F.chain(fab, f => F.map(f, fa))`
  */
-import { Apply, Apply1, Apply2, Apply2C, Apply3, Apply4 } from './Apply'
+import { Apply, Apply1, Apply2, Apply2C, Apply3, Apply4, Apply3C } from './Apply'
 import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT'
 
 /**
@@ -46,6 +46,13 @@ export interface Chain3<F extends URIS3> extends Apply3<F> {
   readonly chain: <R, E, A, B>(fa: Kind3<F, R, E, A>, f: (a: A) => Kind3<F, R, E, B>) => Kind3<F, R, E, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface Chain3C<F extends URIS3, E> extends Apply3C<F, E> {
+  readonly chain: <R, A, B>(fa: Kind3<F, R, E, A>, f: (a: A) => Kind3<F, R, E, B>) => Kind3<F, R, E, B>
+}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/Compactable.ts b/src/Compactable.ts
index e41bc4e8..97c9b1b8 100644
--- a/src/Compactable.ts
+++ b/src/Compactable.ts
@@ -21,7 +21,10 @@ import {
   FunctorComposition22,
   FunctorComposition22C,
   FunctorComposition2C1,
-  getFunctorComposition
+  getFunctorComposition,
+  Functor3C,
+  FunctorComposition23C,
+  FunctorComposition23
 } from './Functor'
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3, URIS4, Kind4 } from './HKT'
 import { getLeft, getRight, Option } from './Option'
@@ -88,6 +91,15 @@ export interface Compactable3<F extends URIS3> {
   readonly separate: <R, E, A, B>(fa: Kind3<F, R, E, Either<A, B>>) => Separated<Kind3<F, R, E, A>, Kind3<F, R, E, B>>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface Compactable3C<F extends URIS3, E> {
+  readonly URI: F
+  readonly compact: <R, A>(fa: Kind3<F, R, E, Option<A>>) => Kind3<F, R, E, A>
+  readonly separate: <R, A, B>(fa: Kind3<F, R, E, Either<A, B>>) => Separated<Kind3<F, R, E, A>, Kind3<F, R, E, B>>
+}
+
 /**
  * @since 2.0.0
  */
@@ -175,9 +187,33 @@ export interface CompactableComposition22C<F extends URIS2, G extends URIS2, E>
   ) => Separated<Kind2<F, FE, Kind2<G, E, A>>, Kind2<F, FE, Kind2<G, E, B>>>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface CompactableComposition23<F extends URIS2, G extends URIS3> extends FunctorComposition23<F, G> {
+  readonly compact: <R, FE, GE, A>(fga: Kind2<F, FE, Kind3<G, R, GE, Option<A>>>) => Kind2<F, FE, Kind3<G, R, GE, A>>
+  readonly separate: <R, FE, GE, A, B>(
+    fge: Kind2<F, FE, Kind3<G, R, GE, Either<A, B>>>
+  ) => Separated<Kind2<F, FE, Kind3<G, R, GE, A>>, Kind2<F, FE, Kind3<G, R, GE, B>>>
+}
+
+/**
+ * @since 2.2.0
+ */
+export interface CompactableComposition23C<F extends URIS2, G extends URIS3, E> extends FunctorComposition23C<F, G, E> {
+  readonly compact: <FE, R, A>(fga: Kind2<F, FE, Kind3<G, R, E, Option<A>>>) => Kind2<F, FE, Kind3<G, R, E, A>>
+  readonly separate: <FE, R, A, B>(
+    fge: Kind2<F, FE, Kind3<G, R, E, Either<A, B>>>
+  ) => Separated<Kind2<F, FE, Kind3<G, R, E, A>>, Kind2<F, FE, Kind3<G, R, E, B>>>
+}
+
 /**
  * @since 2.0.0
  */
+export function getCompactableComposition<F extends URIS2, G extends URIS3, E>(
+  F: Functor2<F>,
+  G: Compactable3C<G, E> & Functor3C<G, E>
+): CompactableComposition23C<F, G, E>
 export function getCompactableComposition<F extends URIS2, G extends URIS2, E>(
   F: Functor2<F>,
   G: Compactable2C<G, E> & Functor2C<G, E>
diff --git a/src/Contravariant.ts b/src/Contravariant.ts
index bd8ac167..df8b909f 100644
--- a/src/Contravariant.ts
+++ b/src/Contravariant.ts
@@ -41,6 +41,14 @@ export interface Contravariant3<F extends URIS3> {
   readonly contramap: <R, E, A, B>(fa: Kind3<F, R, E, A>, f: (b: B) => A) => Kind3<F, R, E, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface Contravariant3C<F extends URIS3, E> {
+  readonly URI: F
+  readonly contramap: <R, A, B>(fa: Kind3<F, R, E, A>, f: (b: B) => A) => Kind3<F, R, E, B>
+}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/Extend.ts b/src/Extend.ts
index a8fe53d8..d450c63f 100644
--- a/src/Extend.ts
+++ b/src/Extend.ts
@@ -1,4 +1,4 @@
-import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor4 } from './Functor'
+import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor4, Functor3C } from './Functor'
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3, URIS4, Kind4 } from './HKT'
 
 /**
@@ -36,6 +36,13 @@ export interface Extend3<W extends URIS3> extends Functor3<W> {
   readonly extend: <R, E, A, B>(wa: Kind3<W, R, E, A>, f: (wa: Kind3<W, R, E, A>) => B) => Kind3<W, R, E, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface Extend3C<W extends URIS3, E> extends Functor3C<W, E> {
+  readonly extend: <R, A, B>(wa: Kind3<W, R, E, A>, f: (wa: Kind3<W, R, E, A>) => B) => Kind3<W, R, E, B>
+}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/Filterable.ts b/src/Filterable.ts
index f8fd6555..fe8d8b2d 100644
--- a/src/Filterable.ts
+++ b/src/Filterable.ts
@@ -17,7 +17,9 @@ import {
   CompactableComposition22,
   getCompactableComposition,
   Separated,
-  Compactable4
+  Compactable4,
+  Compactable3C,
+  CompactableComposition23
 } from './Compactable'
 import { Either } from './Either'
 import { Predicate, Refinement } from './function'
@@ -33,7 +35,9 @@ import {
   FunctorComposition12C,
   FunctorComposition21,
   FunctorComposition22,
-  Functor4
+  Functor4,
+  Functor3C,
+  FunctorComposition23
 } from './Functor'
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3, URIS4, Kind4 } from './HKT'
 import { getLeft, getRight, Option } from './Option'
@@ -192,6 +196,38 @@ export interface Filterable3<F extends URIS3> extends Functor3<F>, Compactable3<
   readonly filter: Filter3<F>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface Filter3C<F extends URIS3, E> {
+  <R, A, B extends A>(fa: Kind3<F, R, E, A>, refinement: Refinement<A, B>): Kind3<F, R, E, B>
+  <R, A>(fa: Kind3<F, R, E, A>, predicate: Predicate<A>): Kind3<F, R, E, A>
+}
+
+/**
+ * @since 2.2.0
+ */
+export interface Partition3C<F extends URIS3, E> {
+  <R, A, B extends A>(fa: Kind3<F, R, E, A>, refinement: Refinement<A, B>): Separated<
+    Kind3<F, R, E, A>,
+    Kind3<F, R, E, B>
+  >
+  <R, A>(fa: Kind3<F, R, E, A>, predicate: Predicate<A>): Separated<Kind3<F, R, E, A>, Kind3<F, R, E, A>>
+}
+
+/**
+ * @since 2.2.0
+ */
+export interface Filterable3C<F extends URIS3, E> extends Functor3C<F, E>, Compactable3C<F, E> {
+  readonly partitionMap: <R, A, B, C>(
+    fa: Kind3<F, R, E, A>,
+    f: (a: A) => Either<B, C>
+  ) => Separated<Kind3<F, R, E, B>, Kind3<F, R, E, C>>
+  readonly partition: Partition3C<F, E>
+  readonly filterMap: <R, A, B>(fa: Kind3<F, R, E, A>, f: (a: A) => Option<B>) => Kind3<F, R, E, B>
+  readonly filter: Filter3C<F, E>
+}
+
 /**
  * @since 2.0.0
  */
@@ -375,9 +411,37 @@ export interface FilterableComposition22C<F extends URIS2, G extends URIS2, E>
   readonly filter: <FE, A>(fa: Kind2<F, FE, Kind2<G, E, A>>, predicate: Predicate<A>) => Kind2<F, FE, Kind2<G, E, A>>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface FilterableComposition23C<F extends URIS2, G extends URIS3, E>
+  extends FunctorComposition23<F, G>,
+    CompactableComposition23<F, G> {
+  readonly partitionMap: <R, FE, A, B, C>(
+    fa: Kind2<F, FE, Kind3<G, R, E, A>>,
+    f: (a: A) => Either<B, C>
+  ) => Separated<Kind2<F, FE, Kind3<G, R, E, B>>, Kind2<F, FE, Kind3<G, R, E, C>>>
+  readonly partition: <R, FE, A>(
+    fa: Kind2<F, FE, Kind3<G, R, E, A>>,
+    predicate: Predicate<A>
+  ) => Separated<Kind2<F, FE, Kind3<G, R, E, A>>, Kind2<F, FE, Kind3<G, R, E, A>>>
+  readonly filterMap: <R, FE, A, B>(
+    fa: Kind2<F, FE, Kind3<G, R, E, A>>,
+    f: (a: A) => Option<B>
+  ) => Kind2<F, FE, Kind3<G, R, E, B>>
+  readonly filter: <R, FE, A>(
+    fa: Kind2<F, FE, Kind3<G, R, E, A>>,
+    predicate: Predicate<A>
+  ) => Kind2<F, FE, Kind3<G, R, E, A>>
+}
+
 /**
  * @since 2.0.0
  */
+export function getFilterableComposition<F extends URIS2, G extends URIS3, E>(
+  F: Functor2<F>,
+  G: Filterable3C<G, E>
+): FilterableComposition23C<F, G, E>
 export function getFilterableComposition<F extends URIS2, G extends URIS2, E>(
   F: Functor2<F>,
   G: Filterable2C<G, E>
diff --git a/src/FilterableWithIndex.ts b/src/FilterableWithIndex.ts
index e1223c06..49cddeb2 100644
--- a/src/FilterableWithIndex.ts
+++ b/src/FilterableWithIndex.ts
@@ -1,13 +1,22 @@
 import { Separated } from './Compactable'
 import { Either } from './Either'
-import { Filterable, Filterable1, Filterable2, Filterable2C, Filterable3, Filterable4 } from './Filterable'
+import {
+  Filterable,
+  Filterable1,
+  Filterable2,
+  Filterable2C,
+  Filterable3,
+  Filterable4,
+  Filterable3C
+} from './Filterable'
 import {
   FunctorWithIndex,
   FunctorWithIndex1,
   FunctorWithIndex2,
   FunctorWithIndex2C,
   FunctorWithIndex3,
-  FunctorWithIndex4
+  FunctorWithIndex4,
+  FunctorWithIndex3C
 } from './FunctorWithIndex'
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3, URIS4, Kind4 } from './HKT'
 import { Option } from './Option'
@@ -152,6 +161,27 @@ export interface FilterWithIndex3<F extends URIS3, I> {
   <R, E, A>(fa: Kind3<F, R, E, A>, predicateWithIndex: PredicateWithIndex<I, A>): Kind3<F, R, E, A>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface FilterWithIndex3C<F extends URIS3, I, E> {
+  <R, A, B extends A>(fa: Kind3<F, R, E, A>, refinementWithIndex: RefinementWithIndex<I, A, B>): Kind3<F, R, E, B>
+  <R, A>(fa: Kind3<F, R, E, A>, predicateWithIndex: PredicateWithIndex<I, A>): Kind3<F, R, E, A>
+}
+
+/**
+ * @since 2.2.0
+ */
+export interface FilterableWithIndex3C<F extends URIS3, I, E> extends FunctorWithIndex3C<F, I, E>, Filterable3C<F, E> {
+  readonly partitionMapWithIndex: <R, A, B, C>(
+    fa: Kind3<F, R, E, A>,
+    f: (i: I, a: A) => Either<B, C>
+  ) => Separated<Kind3<F, R, E, B>, Kind3<F, R, E, C>>
+  readonly partitionWithIndex: PartitionWithIndex3C<F, I, E>
+  readonly filterMapWithIndex: <R, A, B>(fa: Kind3<F, R, E, A>, f: (i: I, a: A) => Option<B>) => Kind3<F, R, E, B>
+  readonly filterWithIndex: FilterWithIndex3C<F, I, E>
+}
+
 /**
  * @since 2.0.0
  */
@@ -166,6 +196,20 @@ export interface PartitionWithIndex3<F extends URIS3, I> {
   >
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PartitionWithIndex3C<F extends URIS3, I, E> {
+  <R, A, B extends A>(fa: Kind3<F, R, E, A>, refinementWithIndex: RefinementWithIndex<I, A, B>): Separated<
+    Kind3<F, R, E, A>,
+    Kind3<F, R, E, B>
+  >
+  <R, A>(fa: Kind3<F, R, E, A>, predicateWithIndex: PredicateWithIndex<I, A>): Separated<
+    Kind3<F, R, E, A>,
+    Kind3<F, R, E, A>
+  >
+}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/Foldable.ts b/src/Foldable.ts
index 79086981..a27f085c 100644
--- a/src/Foldable.ts
+++ b/src/Foldable.ts
@@ -1,7 +1,7 @@
 import { Applicative, Applicative1, Applicative2, Applicative2C, Applicative3 } from './Applicative'
 import { constant } from './function'
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3, URIS4, Kind4 } from './HKT'
-import { Monad, Monad1, Monad2, Monad2C, Monad3 } from './Monad'
+import { Monad, Monad1, Monad2, Monad2C, Monad3, Monad3C } from './Monad'
 import { Monoid } from './Monoid'
 
 /**
@@ -55,6 +55,17 @@ export interface Foldable3<F extends URIS3> {
   readonly reduceRight: <R, E, A, B>(fa: Kind3<F, R, E, A>, b: B, f: (a: A, b: B) => B) => B
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface Foldable3C<F extends URIS3, E> {
+  readonly URI: F
+  readonly _E: E
+  readonly reduce: <R, A, B>(fa: Kind3<F, R, E, A>, b: B, f: (b: B, a: A) => B) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <R, A>(fa: Kind3<F, R, E, A>, f: (a: A) => M) => M
+  readonly reduceRight: <R, A, B>(fa: Kind3<F, R, E, A>, b: B, f: (a: A, b: B) => B) => B
+}
+
 /**
  * @since 2.0.0
  */
@@ -212,6 +223,10 @@ export function foldM<M extends URIS3, F extends URIS>(
   M: Monad3<M>,
   F: Foldable1<F>
 ): <R, E, A, B>(fa: Kind<F, A>, b: B, f: (b: B, a: A) => Kind3<M, R, E, B>) => Kind3<M, R, E, B>
+export function foldM<M extends URIS3, F extends URIS, E>(
+  M: Monad3C<M, E>,
+  F: Foldable1<F>
+): <R, A, B>(fa: Kind<F, A>, b: B, f: (b: B, a: A) => Kind3<M, R, E, B>) => Kind3<M, R, E, B>
 export function foldM<M extends URIS2, F extends URIS>(
   M: Monad2<M>,
   F: Foldable1<F>
diff --git a/src/FoldableWithIndex.ts b/src/FoldableWithIndex.ts
index f18e35d3..58969d56 100644
--- a/src/FoldableWithIndex.ts
+++ b/src/FoldableWithIndex.ts
@@ -23,7 +23,8 @@ import {
   FoldableComposition2C1,
   FoldableComposition22,
   FoldableComposition22C,
-  Foldable4
+  Foldable4,
+  Foldable3C
 } from './Foldable'
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3, URIS4, Kind4 } from './HKT'
 import { Monoid } from './Monoid'
@@ -73,6 +74,15 @@ export interface FoldableWithIndex3<F extends URIS3, I> extends Foldable3<F> {
   readonly reduceRightWithIndex: <R, E, A, B>(fa: Kind3<F, R, E, A>, b: B, f: (i: I, a: A, b: B) => B) => B
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface FoldableWithIndex3C<F extends URIS3, I, E> extends Foldable3C<F, E> {
+  readonly reduceWithIndex: <R, A, B>(fa: Kind3<F, R, E, A>, b: B, f: (i: I, b: B, a: A) => B) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <R, A>(fa: Kind3<F, R, E, A>, f: (i: I, a: A) => M) => M
+  readonly reduceRightWithIndex: <R, A, B>(fa: Kind3<F, R, E, A>, b: B, f: (i: I, a: A, b: B) => B) => B
+}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/Functor.ts b/src/Functor.ts
index 001d1c35..2997322e 100644
--- a/src/Functor.ts
+++ b/src/Functor.ts
@@ -52,6 +52,15 @@ export interface Functor3<F extends URIS3> {
   readonly map: <R, E, A, B>(fa: Kind3<F, R, E, A>, f: (a: A) => B) => Kind3<F, R, E, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface Functor3C<F extends URIS3, E> {
+  readonly URI: F
+  readonly _E: E
+  readonly map: <R, A, B>(fa: Kind3<F, R, E, A>, f: (a: A) => B) => Kind3<F, R, E, B>
+}
+
 /**
  * @since 2.0.0
  */
@@ -137,9 +146,27 @@ export interface FunctorComposition22C<F extends URIS2, G extends URIS2, E> {
   readonly map: <FE, A, B>(fa: Kind2<F, FE, Kind2<G, E, A>>, f: (a: A) => B) => Kind2<F, FE, Kind2<G, E, B>>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface FunctorComposition23<F extends URIS2, G extends URIS3> {
+  readonly map: <FE, R, E, A, B>(fa: Kind2<F, FE, Kind3<G, R, E, A>>, f: (a: A) => B) => Kind2<F, FE, Kind3<G, R, E, B>>
+}
+
+/**
+ * @since 2.2.0
+ */
+export interface FunctorComposition23C<F extends URIS2, G extends URIS3, E> {
+  readonly map: <FE, R, A, B>(fa: Kind2<F, FE, Kind3<G, R, E, A>>, f: (a: A) => B) => Kind2<F, FE, Kind3<G, R, E, B>>
+}
+
 /**
  * @since 2.0.0
  */
+export function getFunctorComposition<F extends URIS2, G extends URIS3, E>(
+  F: Functor2<F>,
+  G: Functor3C<G, E>
+): FunctorComposition23C<F, G, E>
 export function getFunctorComposition<F extends URIS2, G extends URIS2, E>(
   F: Functor2<F>,
   G: Functor2C<G, E>
diff --git a/src/FunctorWithIndex.ts b/src/FunctorWithIndex.ts
index 29397e5f..44dad714 100644
--- a/src/FunctorWithIndex.ts
+++ b/src/FunctorWithIndex.ts
@@ -25,7 +25,8 @@ import {
   FunctorComposition2C1,
   FunctorComposition22,
   FunctorComposition22C,
-  getFunctorComposition
+  getFunctorComposition,
+  Functor3C
 } from './Functor'
 
 /**
@@ -63,6 +64,13 @@ export interface FunctorWithIndex3<F extends URIS3, I> extends Functor3<F> {
   readonly mapWithIndex: <R, E, A, B>(fa: Kind3<F, R, E, A>, f: (i: I, a: A) => B) => Kind3<F, R, E, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface FunctorWithIndex3C<F extends URIS3, I, E> extends Functor3C<F, E> {
+  readonly mapWithIndex: <R, A, B>(fa: Kind3<F, R, E, A>, f: (i: I, a: A) => B) => Kind3<F, R, E, B>
+}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/Monad.ts b/src/Monad.ts
index dfcf8bbe..1f6ac061 100644
--- a/src/Monad.ts
+++ b/src/Monad.ts
@@ -11,8 +11,16 @@
  *
  * Note. `Functor`'s `map` can be derived: `A.map = (fa, f) => A.chain(fa, a => A.of(f(a)))`
  */
-import { Applicative, Applicative1, Applicative2, Applicative2C, Applicative3, Applicative4 } from './Applicative'
-import { Chain, Chain1, Chain2, Chain2C, Chain3, Chain4 } from './Chain'
+import {
+  Applicative,
+  Applicative1,
+  Applicative2,
+  Applicative2C,
+  Applicative3,
+  Applicative4,
+  Applicative3C
+} from './Applicative'
+import { Chain, Chain1, Chain2, Chain2C, Chain3, Chain4, Chain3C } from './Chain'
 import { URIS, URIS2, URIS3, URIS4 } from './HKT'
 
 /**
@@ -40,6 +48,11 @@ export interface Monad2C<M extends URIS2, L> extends Applicative2C<M, L>, Chain2
  */
 export interface Monad3<M extends URIS3> extends Applicative3<M>, Chain3<M> {}
 
+/**
+ * @since 2.2.0
+ */
+export interface Monad3C<M extends URIS3, E> extends Applicative3C<M, E>, Chain3C<M, E> {}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/MonadIO.ts b/src/MonadIO.ts
index 952e28e9..3038e3fb 100644
--- a/src/MonadIO.ts
+++ b/src/MonadIO.ts
@@ -3,7 +3,7 @@
  */
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT'
 import { IO } from './IO'
-import { Monad, Monad1, Monad2, Monad3, Monad2C } from './Monad'
+import { Monad, Monad1, Monad2, Monad3, Monad2C, Monad3C } from './Monad'
 
 /**
  * @since 2.0.0
@@ -39,3 +39,10 @@ export interface MonadIO2C<M extends URIS2, E> extends Monad2C<M, E> {
 export interface MonadIO3<M extends URIS3> extends Monad3<M> {
   readonly fromIO: <R, E, A>(fa: IO<A>) => Kind3<M, R, E, A>
 }
+
+/**
+ * @since 2.2.0
+ */
+export interface MonadIO3C<M extends URIS3, E> extends Monad3C<M, E> {
+  readonly fromIO: <R, A>(fa: IO<A>) => Kind3<M, R, E, A>
+}
diff --git a/src/MonadTask.ts b/src/MonadTask.ts
index a502a1ea..1e32c897 100644
--- a/src/MonadTask.ts
+++ b/src/MonadTask.ts
@@ -2,7 +2,7 @@
  * @file Lift a computation from the `Task` monad
  */
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT'
-import { MonadIO, MonadIO1, MonadIO2, MonadIO2C, MonadIO3 } from './MonadIO'
+import { MonadIO, MonadIO1, MonadIO2, MonadIO2C, MonadIO3, MonadIO3C } from './MonadIO'
 import { Task } from './Task'
 
 /**
@@ -39,3 +39,10 @@ export interface MonadTask2C<M extends URIS2, E> extends MonadIO2C<M, E> {
 export interface MonadTask3<M extends URIS3> extends MonadIO3<M> {
   readonly fromTask: <R, E, A>(fa: Task<A>) => Kind3<M, R, E, A>
 }
+
+/**
+ * @since 2.2.0
+ */
+export interface MonadTask3C<M extends URIS3, E> extends MonadIO3C<M, E> {
+  readonly fromTask: <R, A>(fa: Task<A>) => Kind3<M, R, E, A>
+}
diff --git a/src/MonadThrow.ts b/src/MonadThrow.ts
index 6071a70d..a282ce9c 100644
--- a/src/MonadThrow.ts
+++ b/src/MonadThrow.ts
@@ -7,7 +7,7 @@
  * - Left zero: `M.chain(M.throwError(e), f) = M.throwError(e)`
  */
 import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT'
-import { Monad, Monad1, Monad2, Monad2C, Monad3, Monad4 } from './Monad'
+import { Monad, Monad1, Monad2, Monad2C, Monad3, Monad4, Monad3C } from './Monad'
 
 /**
  * @since 2.0.0
@@ -44,6 +44,13 @@ export interface MonadThrow3<M extends URIS3> extends Monad3<M> {
   readonly throwError: <R, E, A>(e: E) => Kind3<M, R, E, A>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface MonadThrow3C<M extends URIS3, E> extends Monad3C<M, E> {
+  readonly throwError: <R, A>(e: E) => Kind3<M, R, E, A>
+}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/NonEmptyArray.ts b/src/NonEmptyArray.ts
index f6b88f35..5efe6f1d 100644
--- a/src/NonEmptyArray.ts
+++ b/src/NonEmptyArray.ts
@@ -14,6 +14,7 @@ import { Eq } from './Eq'
 import { Predicate, Refinement } from './function'
 import { Show } from './Show'
 import { pipeable } from './pipeable'
+import { Alt1 } from './Alt'
 
 declare module './HKT' {
   interface URItoKind<A> {
@@ -118,7 +119,7 @@ export function max<A>(ord: Ord<A>): (nea: NonEmptyArray<A>) => A {
  */
 export function getSemigroup<A = never>(): Semigroup<NonEmptyArray<A>> {
   return {
-    concat: (x, y) => x.concat(y) as any
+    concat: concat
   }
 }
 
@@ -228,7 +229,7 @@ export function last<A>(nea: NonEmptyArray<A>): A {
 }
 
 /**
- * Get all but the last element of an array, creating a new array.
+ * Get all but the last element of a non empty array, creating a new array.
  *
  * @example
  * import { init } from 'fp-ts/lib/NonEmptyArray'
@@ -236,7 +237,7 @@ export function last<A>(nea: NonEmptyArray<A>): A {
  * assert.deepStrictEqual(init([1, 2, 3]), [1, 2])
  * assert.deepStrictEqual(init([1]), [])
  *
- * @since 2.0.0
+ * @since 2.2.0
  */
 export function init<A>(nea: NonEmptyArray<A>): Array<A> {
   return nea.slice(0, -1)
@@ -300,6 +301,15 @@ export function filterWithIndex<A>(
  */
 export const of: <A>(a: A) => NonEmptyArray<A> = A.of as any
 
+/**
+ * @since 2.2.0
+ */
+export function concat<A>(fx: Array<A>, fy: NonEmptyArray<A>): NonEmptyArray<A>
+export function concat<A>(fx: NonEmptyArray<A>, fy: Array<A>): NonEmptyArray<A>
+export function concat<A>(fx: Array<A>, fy: Array<A>): Array<A> {
+  return fx.concat(fy)
+}
+
 /**
  * @since 2.0.0
  */
@@ -307,7 +317,8 @@ export const nonEmptyArray: Monad1<URI> &
   Comonad1<URI> &
   TraversableWithIndex1<URI, number> &
   FunctorWithIndex1<URI, number> &
-  FoldableWithIndex1<URI, number> = {
+  FoldableWithIndex1<URI, number> &
+  Alt1<URI> = {
   URI,
   map: A.array.map as any,
   mapWithIndex: A.array.mapWithIndex as any,
@@ -324,7 +335,8 @@ export const nonEmptyArray: Monad1<URI> &
   reduceWithIndex: A.array.reduceWithIndex,
   foldMapWithIndex: A.array.foldMapWithIndex,
   reduceRightWithIndex: A.array.reduceRightWithIndex,
-  traverseWithIndex: A.array.traverseWithIndex as any
+  traverseWithIndex: A.array.traverseWithIndex as any,
+  alt: (fx, fy) => concat(fx, fy())
 }
 
 const {
diff --git a/src/Profunctor.ts b/src/Profunctor.ts
index b2bdfe31..4b54b67b 100644
--- a/src/Profunctor.ts
+++ b/src/Profunctor.ts
@@ -1,4 +1,4 @@
-import { Functor2, Functor2C, Functor3, Functor4 } from './Functor'
+import { Functor2, Functor2C, Functor3, Functor4, Functor3C } from './Functor'
 import { HKT, HKT2, Kind2, Kind3, Kind4, URIS2, URIS3, URIS4 } from './HKT'
 
 /**
@@ -31,6 +31,13 @@ export interface Profunctor3<F extends URIS3> extends Functor3<F> {
   readonly promap: <R, E, A, D, B>(fbc: Kind3<F, R, E, A>, f: (d: D) => E, g: (a: A) => B) => Kind3<F, R, D, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface Profunctor3C<F extends URIS3, E> extends Functor3C<F, E> {
+  readonly promap: <R, A, D, B>(fbc: Kind3<F, R, E, A>, f: (d: D) => E, g: (a: A) => B) => Kind3<F, R, D, B>
+}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/Record.ts b/src/Record.ts
index d5d3a6a0..0f95ff60 100644
--- a/src/Record.ts
+++ b/src/Record.ts
@@ -1,4 +1,4 @@
-import { Applicative, Applicative1, Applicative2, Applicative2C, Applicative3 } from './Applicative'
+import { Applicative, Applicative1, Applicative2, Applicative2C, Applicative3, Applicative3C } from './Applicative'
 import { Compactable1, Separated } from './Compactable'
 import { Either } from './Either'
 import { Eq, fromEquals } from './Eq'
@@ -352,6 +352,11 @@ export function traverseWithIndex<F extends URIS3>(
 ): <K extends string, R, E, A, B>(
   f: (k: K, a: A) => Kind3<F, R, E, B>
 ) => (ta: Record<K, A>) => Kind3<F, R, E, Record<K, B>>
+export function traverseWithIndex<F extends URIS3, E>(
+  F: Applicative3C<F, E>
+): <K extends string, R, A, B>(
+  f: (k: K, a: A) => Kind3<F, R, E, B>
+) => (ta: Record<K, A>) => Kind3<F, R, E, Record<K, B>>
 export function traverseWithIndex<F extends URIS2>(
   F: Applicative2<F>
 ): <K extends string, E, A, B>(f: (k: K, a: A) => Kind2<F, E, B>) => (ta: Record<K, A>) => Kind2<F, E, Record<K, B>>
@@ -377,6 +382,9 @@ export function traverseWithIndex<F>(
 export function traverse<F extends URIS3>(
   F: Applicative3<F>
 ): <R, E, A, B>(f: (a: A) => Kind3<F, R, E, B>) => <K extends string>(ta: Record<K, A>) => Kind3<F, R, E, Record<K, B>>
+export function traverse<F extends URIS3, E>(
+  F: Applicative3C<F, E>
+): <R, A, B>(f: (a: A) => Kind3<F, R, E, B>) => <K extends string>(ta: Record<K, A>) => Kind3<F, R, E, Record<K, B>>
 export function traverse<F extends URIS2>(
   F: Applicative2<F>
 ): <E, A, B>(f: (a: A) => Kind2<F, E, B>) => <K extends string>(ta: Record<K, A>) => Kind2<F, E, Record<K, B>>
@@ -402,6 +410,9 @@ export function traverse<F>(
 export function sequence<F extends URIS3>(
   F: Applicative3<F>
 ): <K extends string, R, E, A>(ta: Record<K, Kind3<F, R, E, A>>) => Kind3<F, R, E, Record<K, A>>
+export function sequence<F extends URIS3, E>(
+  F: Applicative3C<F, E>
+): <K extends string, R, A>(ta: Record<K, Kind3<F, R, E, A>>) => Kind3<F, R, E, Record<K, A>>
 export function sequence<F extends URIS2>(
   F: Applicative2<F>
 ): <K extends string, E, A>(ta: Record<K, Kind2<F, E, A>>) => Kind2<F, E, Record<K, A>>
diff --git a/src/Semigroupoid.ts b/src/Semigroupoid.ts
index b95beb98..52d37409 100644
--- a/src/Semigroupoid.ts
+++ b/src/Semigroupoid.ts
@@ -21,6 +21,7 @@ export interface Semigroupoid2<F extends URIS2> {
  */
 export interface Semigroupoid2C<F extends URIS2, E> {
   readonly URI: F
+  readonly _E: E
   readonly compose: <A, B>(ab: Kind2<F, A, B>, la: Kind2<F, E, A>) => Kind2<F, E, B>
 }
 
@@ -32,6 +33,15 @@ export interface Semigroupoid3<F extends URIS3> {
   readonly compose: <R, E, A, B>(ab: Kind3<F, R, A, B>, la: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface Semigroupoid3C<F extends URIS3, E> {
+  readonly URI: F
+  readonly _E: E
+  readonly compose: <R, A, B>(ab: Kind3<F, R, A, B>, la: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
+}
+
 /**
  * @since 2.0.0
  */
diff --git a/src/Store.ts b/src/Store.ts
index 9f6eb05b..437277b4 100644
--- a/src/Store.ts
+++ b/src/Store.ts
@@ -1,6 +1,6 @@
 import { Comonad2 } from './Comonad'
 import { Endomorphism } from './function'
-import { Functor, Functor1, Functor2, Functor2C, Functor3 } from './Functor'
+import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor3C } from './Functor'
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT'
 import { pipeable } from './pipeable'
 
@@ -63,6 +63,9 @@ export function peeks<S>(f: Endomorphism<S>): <A>(wa: Store<S, A>) => A {
 export function experiment<F extends URIS3>(
   F: Functor3<F>
 ): <R, E, S>(f: (s: S) => Kind3<F, R, E, S>) => <A>(wa: Store<S, A>) => Kind3<F, R, E, A>
+export function experiment<F extends URIS3, E>(
+  F: Functor3C<F, E>
+): <R, S>(f: (s: S) => Kind3<F, R, E, S>) => <A>(wa: Store<S, A>) => Kind3<F, R, E, A>
 export function experiment<F extends URIS2>(
   F: Functor2<F>
 ): <E, S>(f: (s: S) => Kind2<F, E, S>) => <A>(wa: Store<S, A>) => Kind2<F, E, A>
diff --git a/src/Traversable.ts b/src/Traversable.ts
index 1c923f3f..b5722390 100644
--- a/src/Traversable.ts
+++ b/src/Traversable.ts
@@ -14,7 +14,7 @@
  * <F>(F: Applicative<F>) => <A>(ta: HKT<T, HKT<F, A>>) => HKT<F, HKT<T, A>>
  * ```
  */
-import { Applicative, Applicative1, Applicative2, Applicative2C, Applicative3 } from './Applicative'
+import { Applicative, Applicative1, Applicative2, Applicative2C, Applicative3, Applicative3C } from './Applicative'
 import {
   Foldable,
   Foldable1,
@@ -88,6 +88,10 @@ export interface Traverse<T> {
     ta: HKT<T, A>,
     f: (a: A) => Kind3<F, R, E, B>
   ) => Kind3<F, R, E, HKT<T, B>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <A, R, B>(
+    ta: HKT<T, A>,
+    f: (a: A) => Kind3<F, R, E, B>
+  ) => Kind3<F, R, E, HKT<T, B>>
   <F extends URIS2>(F: Applicative2<F>): <A, E, B>(ta: HKT<T, A>, f: (a: A) => Kind2<F, E, B>) => Kind2<F, E, HKT<T, B>>
   <F extends URIS2, E>(F: Applicative2C<F, E>): <A, B>(
     ta: HKT<T, A>,
@@ -105,6 +109,10 @@ export interface Traverse1<T extends URIS> {
     ta: Kind<T, A>,
     f: (a: A) => Kind3<F, R, E, B>
   ) => Kind3<F, R, E, Kind<T, B>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <A, R, B>(
+    ta: Kind<T, A>,
+    f: (a: A) => Kind3<F, R, E, B>
+  ) => Kind3<F, R, E, Kind<T, B>>
   <F extends URIS2>(F: Applicative2<F>): <A, E, B>(
     ta: Kind<T, A>,
     f: (a: A) => Kind2<F, E, B>
@@ -188,6 +196,7 @@ export interface Traverse3<T extends URIS3> {
  */
 export interface Sequence<T> {
   <F extends URIS3>(F: Applicative3<F>): <R, E, A>(ta: HKT<T, Kind3<F, R, E, A>>) => Kind3<F, R, E, HKT<T, A>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <R, A>(ta: HKT<T, Kind3<F, R, E, A>>) => Kind3<F, R, E, HKT<T, A>>
   <F extends URIS2>(F: Applicative2<F>): <E, A>(ta: HKT<T, Kind2<F, E, A>>) => Kind2<F, E, HKT<T, A>>
   <F extends URIS2, E>(F: Applicative2C<F, E>): <A>(ta: HKT<T, Kind2<F, E, A>>) => Kind2<F, E, HKT<T, A>>
   <F extends URIS>(F: Applicative1<F>): <A>(ta: HKT<T, Kind<F, A>>) => Kind<F, HKT<T, A>>
@@ -199,6 +208,7 @@ export interface Sequence<T> {
  */
 export interface Sequence1<T extends URIS> {
   <F extends URIS3>(F: Applicative3<F>): <R, E, A>(ta: Kind<T, Kind3<F, R, E, A>>) => Kind3<F, R, E, Kind<T, A>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <R, A>(ta: Kind<T, Kind3<F, R, E, A>>) => Kind3<F, R, E, Kind<T, A>>
   <F extends URIS2>(F: Applicative2<F>): <E, A>(ta: Kind<T, Kind2<F, E, A>>) => Kind2<F, E, Kind<T, A>>
   <F extends URIS2, E>(F: Applicative2C<F, E>): <A>(ta: Kind<T, Kind2<F, E, A>>) => Kind2<F, E, Kind<T, A>>
   <F extends URIS>(F: Applicative1<F>): <A>(ta: Kind<T, Kind<F, A>>) => Kind<F, Kind<T, A>>
diff --git a/src/TraversableWithIndex.ts b/src/TraversableWithIndex.ts
index 847a4fad..e71a0089 100644
--- a/src/TraversableWithIndex.ts
+++ b/src/TraversableWithIndex.ts
@@ -18,7 +18,7 @@
  * mapWithIndex(ta, f) = traverseWithIndex(identity)(ta, (i, a) => new Identity(f(i, a))).value
  * ```
  */
-import { Applicative, Applicative1, Applicative2, Applicative2C, Applicative3 } from './Applicative'
+import { Applicative, Applicative1, Applicative2, Applicative2C, Applicative3, Applicative3C } from './Applicative'
 import { FoldableWithIndex, FoldableWithIndex1, FoldableWithIndex2, FoldableWithIndex2C } from './FoldableWithIndex'
 import { FunctorWithIndex, FunctorWithIndex1, FunctorWithIndex2, FunctorWithIndex2C } from './FunctorWithIndex'
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT'
@@ -69,6 +69,10 @@ export interface TraverseWithIndex<T, I> {
     ta: HKT<T, A>,
     f: (i: I, a: A) => Kind3<F, R, E, B>
   ) => Kind3<F, R, E, HKT<T, B>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <A, R, B>(
+    ta: HKT<T, A>,
+    f: (i: I, a: A) => Kind3<F, R, E, B>
+  ) => Kind3<F, R, E, HKT<T, B>>
   <F extends URIS2>(F: Applicative2<F>): <A, E, B>(
     ta: HKT<T, A>,
     f: (i: I, a: A) => Kind2<F, E, B>
@@ -89,6 +93,10 @@ export interface TraverseWithIndex1<T extends URIS, I> {
     ta: Kind<T, A>,
     f: (i: I, a: A) => Kind3<F, R, E, B>
   ) => Kind3<F, R, E, Kind<T, B>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <A, R, B>(
+    ta: Kind<T, A>,
+    f: (i: I, a: A) => Kind3<F, R, E, B>
+  ) => Kind3<F, R, E, Kind<T, B>>
   <F extends URIS2>(F: Applicative2<F>): <A, E, B>(
     ta: Kind<T, A>,
     f: (i: I, a: A) => Kind2<F, E, B>
@@ -132,6 +140,10 @@ export interface TraverseWithIndex2C<T extends URIS2, I, E> {
     ta: Kind2<T, E, A>,
     f: (i: I, a: A) => Kind3<F, R, FE, B>
   ) => Kind3<F, R, FE, Kind2<T, E, B>>
+  <F extends URIS3>(F: Applicative3C<F, E>): <A, R, B>(
+    ta: Kind2<T, E, A>,
+    f: (i: I, a: A) => Kind3<F, R, E, B>
+  ) => Kind3<F, R, E, Kind2<T, E, B>>
   <F extends URIS2>(F: Applicative2<F>): <A, FE, B>(
     ta: Kind2<T, E, A>,
     f: (i: I, a: A) => Kind2<F, FE, B>
diff --git a/src/Tree.ts b/src/Tree.ts
index 74eca541..dc67e5ff 100644
--- a/src/Tree.ts
+++ b/src/Tree.ts
@@ -12,7 +12,7 @@ import { Eq, fromEquals } from './Eq'
 import { Foldable1 } from './Foldable'
 import { identity } from './function'
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT'
-import { Monad, Monad1, Monad2, Monad2C, Monad3 } from './Monad'
+import { Monad, Monad1, Monad2, Monad2C, Monad3, Monad3C } from './Monad'
 import { Show } from './Show'
 import { Traversable1 } from './Traversable'
 import { pipeable } from './pipeable'
@@ -155,6 +155,9 @@ export function unfoldForest<A, B>(bs: Array<B>, f: (b: B) => [A, Array<B>]): Fo
 export function unfoldTreeM<M extends URIS3>(
   M: Monad3<M>
 ): <R, E, A, B>(b: B, f: (b: B) => Kind3<M, R, E, [A, Array<B>]>) => Kind3<M, R, E, Tree<A>>
+export function unfoldTreeM<M extends URIS3, E>(
+  M: Monad3C<M, E>
+): <R, A, B>(b: B, f: (b: B) => Kind3<M, R, E, [A, Array<B>]>) => Kind3<M, R, E, Tree<A>>
 export function unfoldTreeM<M extends URIS2>(
   M: Monad2<M>
 ): <E, A, B>(b: B, f: (b: B) => Kind2<M, E, [A, Array<B>]>) => Kind2<M, E, Tree<A>>
@@ -178,6 +181,9 @@ export function unfoldTreeM<M>(M: Monad<M>): <A, B>(b: B, f: (b: B) => HKT<M, [A
 export function unfoldForestM<M extends URIS3>(
   M: Monad3<M>
 ): <R, E, A, B>(bs: Array<B>, f: (b: B) => Kind3<M, R, E, [A, Array<B>]>) => Kind3<M, R, E, Forest<A>>
+export function unfoldForestM<M extends URIS3, E>(
+  M: Monad3C<M, E>
+): <R, A, B>(bs: Array<B>, f: (b: B) => Kind3<M, R, E, [A, Array<B>]>) => Kind3<M, R, E, Forest<A>>
 export function unfoldForestM<M extends URIS2>(
   M: Monad2<M>
 ): <R, E, B>(bs: Array<B>, f: (b: B) => Kind2<M, R, [E, Array<B>]>) => Kind2<M, R, Forest<E>>
diff --git a/src/Witherable.ts b/src/Witherable.ts
index acdbd245..e5dff7f8 100644
--- a/src/Witherable.ts
+++ b/src/Witherable.ts
@@ -18,7 +18,7 @@
 import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT'
 import { Option } from './Option'
 import { Traversable, Traversable1, Traversable2, Traversable2C, Traversable3 } from './Traversable'
-import { Applicative, Applicative1, Applicative2, Applicative2C, Applicative3 } from './Applicative'
+import { Applicative, Applicative1, Applicative2, Applicative2C, Applicative3, Applicative3C } from './Applicative'
 import { Filterable, Filterable1, Filterable2, Filterable2C, Filterable3 } from './Filterable'
 import { Either } from './Either'
 import { Separated } from './Compactable'
@@ -78,6 +78,10 @@ export interface Wither<W> {
     ta: HKT<W, A>,
     f: (a: A) => Kind3<F, R, E, Option<B>>
   ) => Kind3<F, R, E, HKT<W, B>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <A, R, B>(
+    ta: HKT<W, A>,
+    f: (a: A) => Kind3<F, R, E, Option<B>>
+  ) => Kind3<F, R, E, HKT<W, B>>
   <F extends URIS2>(F: Applicative2<F>): <A, E, B>(
     ta: HKT<W, A>,
     f: (a: A) => Kind2<F, E, Option<B>>
@@ -98,6 +102,10 @@ export interface Wither1<W extends URIS> {
     ta: Kind<W, A>,
     f: (a: A) => Kind3<F, R, E, Option<B>>
   ) => Kind3<F, R, E, Kind<W, B>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <A, R, B>(
+    ta: Kind<W, A>,
+    f: (a: A) => Kind3<F, R, E, Option<B>>
+  ) => Kind3<F, R, E, Kind<W, B>>
   <F extends URIS2>(F: Applicative2<F>): <A, E, B>(
     ta: Kind<W, A>,
     f: (a: A) => Kind2<F, E, Option<B>>
@@ -190,6 +198,10 @@ export interface Wilt<W> {
     wa: HKT<W, A>,
     f: (a: A) => Kind3<F, R, E, Either<B, C>>
   ) => Kind3<F, R, E, Separated<HKT<W, B>, HKT<W, C>>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <A, R, B, C>(
+    wa: HKT<W, A>,
+    f: (a: A) => Kind3<F, R, E, Either<B, C>>
+  ) => Kind3<F, R, E, Separated<HKT<W, B>, HKT<W, C>>>
   <F extends URIS2>(F: Applicative2<F>): <A, E, B, C>(
     wa: HKT<W, A>,
     f: (a: A) => Kind2<F, E, Either<B, C>>
@@ -216,6 +228,10 @@ export interface Wilt1<W extends URIS> {
     wa: Kind<W, A>,
     f: (a: A) => Kind3<F, R, E, Either<B, C>>
   ) => Kind3<F, R, E, Separated<Kind<W, B>, Kind<W, C>>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <A, R, B, C>(
+    wa: Kind<W, A>,
+    f: (a: A) => Kind3<F, R, E, Either<B, C>>
+  ) => Kind3<F, R, E, Separated<Kind<W, B>, Kind<W, C>>>
   <F extends URIS2>(F: Applicative2<F>): <A, E, B, C>(
     wa: Kind<W, A>,
     f: (a: A) => Kind2<F, E, Either<B, C>>
diff --git a/src/pipeable.ts b/src/pipeable.ts
index 432a2c9f..1c783816 100644
--- a/src/pipeable.ts
+++ b/src/pipeable.ts
@@ -1,7 +1,7 @@
-import { Alt, Alt1, Alt2, Alt2C, Alt3, Alt4 } from './Alt'
-import { Apply, Apply1, Apply2, Apply2C, Apply3, Apply4 } from './Apply'
-import { Bifunctor, Bifunctor2, Bifunctor3, Bifunctor4 } from './Bifunctor'
-import { Chain, Chain1, Chain2, Chain2C, Chain3, Chain4 } from './Chain'
+import { Alt, Alt1, Alt2, Alt2C, Alt3, Alt4, Alt3C } from './Alt'
+import { Apply, Apply1, Apply2, Apply2C, Apply3, Apply4, Apply3C } from './Apply'
+import { Bifunctor, Bifunctor2, Bifunctor3, Bifunctor4, Bifunctor3C } from './Bifunctor'
+import { Chain, Chain1, Chain2, Chain2C, Chain3, Chain4, Chain3C } from './Chain'
 import {
   Compactable,
   Compactable1,
@@ -9,7 +9,8 @@ import {
   Compactable2C,
   Compactable3,
   Compactable4,
-  Separated
+  Separated,
+  Compactable3C
 } from './Compactable'
 import {
   Contravariant,
@@ -17,11 +18,20 @@ import {
   Contravariant2,
   Contravariant2C,
   Contravariant3,
-  Contravariant4
+  Contravariant4,
+  Contravariant3C
 } from './Contravariant'
 import { Either } from './Either'
-import { Extend, Extend1, Extend2, Extend2C, Extend3, Extend4 } from './Extend'
-import { Filterable, Filterable1, Filterable2, Filterable2C, Filterable3, Filterable4 } from './Filterable'
+import { Extend, Extend1, Extend2, Extend2C, Extend3, Extend4, Extend3C } from './Extend'
+import {
+  Filterable,
+  Filterable1,
+  Filterable2,
+  Filterable2C,
+  Filterable3,
+  Filterable4,
+  Filterable3C
+} from './Filterable'
 import {
   FilterableWithIndex,
   FilterableWithIndex1,
@@ -30,33 +40,51 @@ import {
   FilterableWithIndex3,
   FilterableWithIndex4,
   PredicateWithIndex,
-  RefinementWithIndex
+  RefinementWithIndex,
+  FilterableWithIndex3C
 } from './FilterableWithIndex'
-import { Foldable, Foldable1, Foldable2, Foldable2C, Foldable3, Foldable4 } from './Foldable'
+import { Foldable, Foldable1, Foldable2, Foldable2C, Foldable3, Foldable4, Foldable3C } from './Foldable'
 import {
   FoldableWithIndex,
   FoldableWithIndex1,
   FoldableWithIndex2,
   FoldableWithIndex2C,
   FoldableWithIndex3,
-  FoldableWithIndex4
+  FoldableWithIndex4,
+  FoldableWithIndex3C
 } from './FoldableWithIndex'
 import { identity, Predicate, Refinement } from './function'
-import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor4 } from './Functor'
+import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor4, Functor3C } from './Functor'
 import {
   FunctorWithIndex,
   FunctorWithIndex1,
   FunctorWithIndex2,
   FunctorWithIndex2C,
   FunctorWithIndex3,
-  FunctorWithIndex4
+  FunctorWithIndex4,
+  FunctorWithIndex3C
 } from './FunctorWithIndex'
 import { HKT, HKT2, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT'
-import { MonadThrow, MonadThrow1, MonadThrow2, MonadThrow2C, MonadThrow3, MonadThrow4 } from './MonadThrow'
+import {
+  MonadThrow,
+  MonadThrow1,
+  MonadThrow2,
+  MonadThrow2C,
+  MonadThrow3,
+  MonadThrow4,
+  MonadThrow3C
+} from './MonadThrow'
 import { Monoid } from './Monoid'
 import { Option } from './Option'
-import { Profunctor, Profunctor2, Profunctor2C, Profunctor3, Profunctor4 } from './Profunctor'
-import { Semigroupoid, Semigroupoid2, Semigroupoid2C, Semigroupoid3, Semigroupoid4 } from './Semigroupoid'
+import { Profunctor, Profunctor2, Profunctor2C, Profunctor3, Profunctor4, Profunctor3C } from './Profunctor'
+import {
+  Semigroupoid,
+  Semigroupoid2,
+  Semigroupoid2C,
+  Semigroupoid3,
+  Semigroupoid4,
+  Semigroupoid3C
+} from './Semigroupoid'
 
 /**
  * @since 2.0.0
@@ -187,6 +215,13 @@ export interface PipeableFunctor3<F extends URIS3> {
   readonly map: <A, B>(f: (a: A) => B) => <R, E>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableFunctor3C<F extends URIS3, E> {
+  readonly map: <A, B>(f: (a: A) => B) => <R>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
+}
+
 /**
  * @since 2.0.0
  */
@@ -229,6 +264,13 @@ export interface PipeableContravariant3<F extends URIS3> {
   readonly contramap: <A, B>(f: (b: B) => A) => <R, E>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableContravariant3C<F extends URIS3, E> {
+  readonly contramap: <A, B>(f: (b: B) => A) => <R>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
+}
+
 /**
  * @since 2.0.0
  */
@@ -271,6 +313,13 @@ export interface PipeableFunctorWithIndex3<F extends URIS3, I> extends PipeableF
   readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => <R, E>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableFunctorWithIndex3C<F extends URIS3, I, E> extends PipeableFunctor3C<F, E> {
+  readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => <R>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
+}
+
 /**
  * @since 2.0.0
  */
@@ -323,6 +372,15 @@ export interface PipeableApply3<F extends URIS3> extends PipeableFunctor3<F> {
   readonly apSecond: <R, E, B>(fb: Kind3<F, R, E, B>) => <A>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableApply3C<F extends URIS3, E> extends PipeableFunctor3C<F, E> {
+  readonly ap: <R, A>(fa: Kind3<F, R, E, A>) => <B>(fab: Kind3<F, R, E, (a: A) => B>) => Kind3<F, R, E, B>
+  readonly apFirst: <R, B>(fb: Kind3<F, R, E, B>) => <A>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, A>
+  readonly apSecond: <R, B>(fb: Kind3<F, R, E, B>) => <A>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
+}
+
 /**
  * @since 2.0.0
  */
@@ -379,6 +437,15 @@ export interface PipeableChain3<F extends URIS3> extends PipeableApply3<F> {
   readonly flatten: <R, E, A>(mma: Kind3<F, R, E, Kind3<F, R, E, A>>) => Kind3<F, R, E, A>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableChain3C<F extends URIS3, E> extends PipeableApply3C<F, E> {
+  readonly chain: <R, A, B>(f: (a: A) => Kind3<F, R, E, B>) => (ma: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
+  readonly chainFirst: <R, A, B>(f: (a: A) => Kind3<F, R, E, B>) => (ma: Kind3<F, R, E, A>) => Kind3<F, R, E, A>
+  readonly flatten: <R, A>(mma: Kind3<F, R, E, Kind3<F, R, E, A>>) => Kind3<F, R, E, A>
+}
+
 /**
  * @since 2.0.0
  */
@@ -432,6 +499,14 @@ export interface PipeableExtend3<F extends URIS3> extends PipeableFunctor3<F> {
   readonly duplicate: <R, E, A>(ma: Kind3<F, R, E, A>) => Kind3<F, R, E, Kind3<F, R, E, A>>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableExtend3C<F extends URIS3, E> extends PipeableFunctor3C<F, E> {
+  readonly extend: <R, A, B>(f: (fa: Kind3<F, R, E, A>) => B) => (ma: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
+  readonly duplicate: <R, A>(ma: Kind3<F, R, E, A>) => Kind3<F, R, E, Kind3<F, R, E, A>>
+}
+
 /**
  * @since 2.0.0
  */
@@ -466,6 +541,14 @@ export interface PipeableBifunctor3<F extends URIS3> {
   readonly mapLeft: <E, G>(f: (e: E) => G) => <R, A>(fa: Kind3<F, R, E, A>) => Kind3<F, R, G, A>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableBifunctor3C<F extends URIS3, E> {
+  readonly bimap: <G, A, B>(f: (e: E) => G, g: (a: A) => B) => <R>(fa: Kind3<F, R, E, A>) => Kind3<F, R, G, B>
+  readonly mapLeft: <G>(f: (e: E) => G) => <R, A>(fa: Kind3<F, R, E, A>) => Kind3<F, R, G, A>
+}
+
 /**
  * @since 2.0.0
  */
@@ -522,6 +605,15 @@ export interface PipeableFoldable3<F extends URIS3> {
   readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => <R, E>(fa: Kind3<F, R, E, A>) => B
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableFoldable3C<F extends URIS3, E> {
+  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => <R>(fa: Kind3<F, R, E, A>) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => <R>(fa: Kind3<F, R, E, A>) => M
+  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => <R>(fa: Kind3<F, R, E, A>) => B
+}
+
 /**
  * @since 2.0.0
  */
@@ -576,6 +668,15 @@ export interface PipeableFoldableWithIndex3<F extends URIS3, I> extends Pipeable
   readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => <R, E>(fa: Kind3<F, R, E, A>) => B
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableFoldableWithIndex3C<F extends URIS3, I, E> extends PipeableFoldable3C<F, E> {
+  readonly reduceWithIndex: <A, B>(b: B, f: (i: I, b: B, a: A) => B) => <R>(fa: Kind3<F, R, E, A>) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <A>(f: (i: I, a: A) => M) => <R>(fa: Kind3<F, R, E, A>) => M
+  readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => <R>(fa: Kind3<F, R, E, A>) => B
+}
+
 /**
  * @since 2.0.0
  */
@@ -620,6 +721,13 @@ export interface PipeableAlt3<F extends URIS3> {
   readonly alt: <R, E, A>(that: () => Kind3<F, R, E, A>) => (fa: Kind3<F, R, E, A>) => Kind3<F, R, E, A>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableAlt3C<F extends URIS3, E> {
+  readonly alt: <R, A>(that: () => Kind3<F, R, E, A>) => (fa: Kind3<F, R, E, A>) => Kind3<F, R, E, A>
+}
+
 /**
  * @since 2.0.0
  */
@@ -667,6 +775,14 @@ export interface PipeableCompactable3<F extends URIS3> {
   readonly separate: <R, E, A, B>(fa: Kind3<F, R, E, Either<A, B>>) => Separated<Kind3<F, R, E, A>, Kind3<F, R, E, B>>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableCompactable3C<F extends URIS3, E> {
+  readonly compact: <R, A>(fa: Kind3<F, R, E, Option<A>>) => Kind3<F, R, E, A>
+  readonly separate: <R, A, B>(fa: Kind3<F, R, E, Either<A, B>>) => Separated<Kind3<F, R, E, A>, Kind3<F, R, E, B>>
+}
+
 /**
  * @since 2.0.0
  */
@@ -765,6 +881,26 @@ export interface PipeableFilterable3<F extends URIS3> extends PipeableCompactabl
   ) => <R, E>(fa: Kind3<F, R, E, A>) => Separated<Kind3<F, R, E, B>, Kind3<F, R, E, C>>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableFilterable3C<F extends URIS3, E> extends PipeableCompactable3C<F, E> {
+  readonly filter: {
+    <A, B extends A>(refinement: Refinement<A, B>): <R>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
+    <A>(predicate: Predicate<A>): <R>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, A>
+  }
+  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => <R>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, A>
+  readonly partition: {
+    <A, B extends A>(refinement: Refinement<A, B>): <R>(
+      fa: Kind3<F, R, E, A>
+    ) => Separated<Kind3<F, R, E, A>, Kind3<F, R, E, B>>
+    <A>(predicate: Predicate<A>): <R>(fa: Kind3<F, R, E, A>) => Separated<Kind3<F, R, E, A>, Kind3<F, R, E, A>>
+  }
+  readonly partitionMap: <A, B, C>(
+    f: (a: A) => Either<B, C>
+  ) => <R>(fa: Kind3<F, R, E, A>) => Separated<Kind3<F, R, E, B>, Kind3<F, R, E, C>>
+}
+
 /**
  * @since 2.0.0
  */
@@ -895,6 +1031,28 @@ export interface PipeableFilterableWithIndex3<F extends URIS3, I> extends Pipeab
   ) => <R, E>(fa: Kind3<F, R, E, A>) => Separated<Kind3<F, R, E, B>, Kind3<F, R, E, C>>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableFilterableWithIndex3C<F extends URIS3, I, E> extends PipeableFilterable3C<F, E> {
+  readonly filterWithIndex: {
+    <A, B extends A>(refinementWithIndex: RefinementWithIndex<I, A, B>): <R>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, B>
+    <A>(predicateWithIndex: PredicateWithIndex<I, A>): <R, E>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, A>
+  }
+  readonly filterMapWithIndex: <A, B>(f: (i: I, a: A) => Option<B>) => <R>(fa: Kind3<F, R, E, A>) => Kind3<F, R, E, A>
+  readonly partitionWithIndex: {
+    <A, B extends A>(refinementWithIndex: RefinementWithIndex<I, A, B>): <R>(
+      fa: Kind3<F, R, E, A>
+    ) => Separated<Kind3<F, R, E, A>, Kind3<F, R, E, B>>
+    <A>(predicateWithIndex: PredicateWithIndex<I, A>): <R>(
+      fa: Kind3<F, R, E, A>
+    ) => Separated<Kind3<F, R, E, A>, Kind3<F, R, E, A>>
+  }
+  readonly partitionMapWithIndex: <A, B, C>(
+    f: (i: I, a: A) => Either<B, C>
+  ) => <R>(fa: Kind3<F, R, E, A>) => Separated<Kind3<F, R, E, B>, Kind3<F, R, E, C>>
+}
+
 /**
  * @since 2.0.0
  */
@@ -949,6 +1107,13 @@ export interface PipeableProfunctor3<F extends URIS3> extends PipeableFunctor3<F
   readonly promap: <R, E, A, D, B>(f: (d: D) => E, g: (a: A) => B) => (fbc: Kind3<F, R, E, A>) => Kind3<F, R, D, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableProfunctor3C<F extends URIS3, E> extends PipeableFunctor3C<F, E> {
+  readonly promap: <R, A, D, B>(f: (d: D) => E, g: (a: A) => B) => (fbc: Kind3<F, R, E, A>) => Kind3<F, R, D, B>
+}
+
 /**
  * @since 2.0.0
  */
@@ -987,6 +1152,13 @@ export interface PipeableSemigroupoid3<F extends URIS3> {
   readonly compose: <R, E, A>(la: Kind3<F, R, E, A>) => <B>(ab: Kind3<F, R, A, B>) => Kind3<F, R, E, B>
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableSemigroupoid3C<F extends URIS3, E> {
+  readonly compose: <R, A>(la: Kind3<F, R, E, A>) => <B>(ab: Kind3<F, R, A, B>) => Kind3<F, R, E, B>
+}
+
 /**
  * @since 2.0.0
  */
@@ -1076,6 +1248,24 @@ export interface PipeableMonadThrow3<F extends URIS3> {
   }
 }
 
+/**
+ * @since 2.2.0
+ */
+export interface PipeableMonadThrow3C<F extends URIS3, E> {
+  readonly fromOption: (onNone: () => E) => <R, A>(ma: Option<A>) => Kind3<F, R, E, A>
+  readonly fromEither: <R, A>(ma: Either<E, A>) => Kind3<F, R, E, A>
+  readonly fromPredicate: {
+    <A, B extends A>(refinement: Refinement<A, B>, onFalse: (a: A) => E): <U>(a: A) => Kind3<F, U, E, B>
+    <A>(predicate: Predicate<A>, onFalse: (a: A) => E): <R>(a: A) => Kind3<F, R, E, A>
+  }
+  readonly filterOrElse: {
+    <A, B extends A>(refinement: Refinement<A, B>, onFalse: (a: A) => E): <R>(
+      ma: Kind3<F, R, E, A>
+    ) => Kind3<F, R, E, B>
+    <A>(predicate: Predicate<A>, onFalse: (a: A) => E): <R>(ma: Kind3<F, R, E, A>) => Kind3<F, R, E, A>
+  }
+}
+
 /**
  * @since 2.0.0
  */
@@ -1173,6 +1363,35 @@ export function pipeable<F extends URIS3, I>(
   (I extends Profunctor3<F> ? PipeableProfunctor3<F> : {}) &
   (I extends Semigroupoid3<F> ? PipeableSemigroupoid3<F> : {}) &
   (I extends MonadThrow3<F> ? PipeableMonadThrow3<F> : {})
+export function pipeable<F extends URIS3, I, E>(
+  I: { URI: F } & I
+): (I extends Chain3C<F, E>
+  ? PipeableChain3C<F, E>
+  : I extends Apply3C<F, E>
+  ? PipeableApply3C<F, E>
+  : I extends Functor3C<F, E>
+  ? PipeableFunctor3C<F, E>
+  : {}) &
+  (I extends Contravariant3C<F, E> ? PipeableContravariant3C<F, E> : {}) &
+  (I extends FunctorWithIndex3C<F, infer Ix, E> ? PipeableFunctorWithIndex3C<F, Ix, E> : {}) &
+  (I extends Bifunctor3C<F, E> ? PipeableBifunctor3C<F, E> : {}) &
+  (I extends Extend3C<F, E> ? PipeableExtend3C<F, E> : {}) &
+  (I extends FoldableWithIndex3C<F, infer Ix, E>
+    ? PipeableFoldableWithIndex3C<F, Ix, E>
+    : I extends Foldable3C<F, E>
+    ? PipeableFoldable3C<F, E>
+    : {}) &
+  (I extends Alt3C<F, E> ? PipeableAlt3C<F, E> : {}) &
+  (I extends FilterableWithIndex3C<F, infer Ix, E>
+    ? PipeableFilterableWithIndex3C<F, Ix, E>
+    : I extends Filterable3C<F, E>
+    ? PipeableFilterable3C<F, E>
+    : I extends Compactable3C<F, E>
+    ? PipeableCompactable3C<F, E>
+    : {}) &
+  (I extends Profunctor3C<F, E> ? PipeableProfunctor3C<F, E> : {}) &
+  (I extends Semigroupoid3C<F, E> ? PipeableSemigroupoid3C<F, E> : {}) &
+  (I extends MonadThrow3C<F, E> ? PipeableMonadThrow3C<F, E> : {})
 export function pipeable<F extends URIS2, I, E>(
   I: { URI: F; _E: E } & I
 ): (I extends Chain2C<F, E>


Test patch:
diff --git a/test/NonEmptyArray.ts b/test/NonEmptyArray.ts
index 154e0a22..5d4c3534 100644
--- a/test/NonEmptyArray.ts
+++ b/test/NonEmptyArray.ts
@@ -29,7 +29,8 @@ import {
   tail,
   updateAt,
   NonEmptyArray,
-  init
+  init,
+  concat
 } from '../src/NonEmptyArray'
 import { isSome, none, option, some } from '../src/Option'
 import { ordNumber } from '../src/Ord'
@@ -321,4 +322,12 @@ describe('NonEmptyArray', () => {
     assert.strictEqual(S.show(['a']), `["a"]`)
     assert.strictEqual(S.show(['a', 'b', 'c']), `["a", "b", "c"]`)
   })
+
+  it('alt / concat', () => {
+    assert.deepStrictEqual(concat(['a'], []), ['a'])
+    assert.deepStrictEqual(
+      nonEmptyArray.alt(['a'], () => ['b']),
+      ['a', 'b']
+    )
+  })
 })