Repository: gcanti/fp-ts
Pull request #871 (2019-05-15 10:58:06)

Experimental: add `pipeable` module
I wrote the longest function signature of my TypeScript career


Patch:
diff --git a/docs/modules/Chain.ts.md b/docs/modules/Chain.ts.md
index 11299ca2..0fc34dd4 100644
--- a/docs/modules/Chain.ts.md
+++ b/docs/modules/Chain.ts.md
@@ -25,7 +25,6 @@ Note. `Apply`'s `ap` can be derived: `(fab, fa) => F.chain(fab, f => F.map(f, fa
 - [Chain2C (interface)](#chain2c-interface)
 - [Chain3 (interface)](#chain3-interface)
 - [Chain4 (interface)](#chain4-interface)
-- [flatMap (function)](#flatmap-function)
 
 ---
 
@@ -100,23 +99,3 @@ export interface Chain4<F extends URIS4> extends Apply4<F> {
 ```
 
 Added in v2.0.0
-
-# flatMap (function)
-
-**Signature**
-
-```ts
-export function flatMap<F extends URIS3>(
-  F: Chain3<F>
-): <U, L, A, B>(f: (a: A) => Type3<F, U, L, B>) => (fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
-export function flatMap<F extends URIS2>(
-  F: Chain2<F>
-): <L, A, B>(f: (a: A) => Type2<F, L, B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
-export function flatMap<F extends URIS2, L>(
-  F: Chain2C<F, L>
-): <A, B>(f: (a: A) => Type2<F, L, B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
-export function flatMap<F extends URIS>(F: Chain1<F>): <A, B>(f: (a: A) => Type<F, B>) => (fa: Type<F, A>) => Type<F, B>
-export function flatMap<F>(F: Chain<F>): <A, B>(f: (a: A) => HKT<F, B>) => (fa: HKT<F, A>) => HKT<F, B> { ... }
-```
-
-Added in v2.0.0
diff --git a/docs/modules/Functor.ts.md b/docs/modules/Functor.ts.md
index b252d9e4..1c3d3c43 100644
--- a/docs/modules/Functor.ts.md
+++ b/docs/modules/Functor.ts.md
@@ -37,7 +37,6 @@ Instances must satisfy the following laws:
 - [FunctorComposition22C (interface)](#functorcomposition22c-interface)
 - [FunctorComposition2C1 (interface)](#functorcomposition2c1-interface)
 - [getFunctorComposition (function)](#getfunctorcomposition-function)
-- [lift (function)](#lift-function)
 
 ---
 
@@ -277,23 +276,3 @@ export function getFunctorComposition<F, G>(F: Functor<F>, G: Functor<G>): Funct
 ```
 
 Added in v2.0.0
-
-# lift (function)
-
-**Signature**
-
-```ts
-export function lift<F extends URIS3>(
-  F: Functor3<F>
-): <A, B>(f: (a: A) => B) => <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
-export function lift<F extends URIS2>(
-  F: Functor2<F>
-): <A, B>(f: (a: A) => B) => <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
-export function lift<F extends URIS2, L>(
-  F: Functor2C<F, L>
-): <A, B>(f: (a: A) => B) => (fa: Type2<F, L, A>) => Type2<F, L, B>
-export function lift<F extends URIS>(F: Functor1<F>): <A, B>(f: (a: A) => B) => (fa: Type<F, A>) => Type<F, B>
-export function lift<F>(F: Functor<F>): <A, B>(f: (a: A) => B) => (fa: HKT<F, A>) => HKT<F, B> { ... }
-```
-
-Added in v2.0.0
diff --git a/docs/modules/Plus.ts.md b/docs/modules/Plus.ts.md
index 09429079..33c09295 100644
--- a/docs/modules/Plus.ts.md
+++ b/docs/modules/Plus.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Plus.ts
-nav_order: 63
+nav_order: 64
 parent: Modules
 ---
 
diff --git a/docs/modules/Profunctor.ts.md b/docs/modules/Profunctor.ts.md
index 096ef647..58ccd310 100644
--- a/docs/modules/Profunctor.ts.md
+++ b/docs/modules/Profunctor.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Profunctor.ts
-nav_order: 64
+nav_order: 65
 parent: Modules
 ---
 
diff --git a/docs/modules/Random.ts.md b/docs/modules/Random.ts.md
index 1a5e3fbe..10050174 100644
--- a/docs/modules/Random.ts.md
+++ b/docs/modules/Random.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Random.ts
-nav_order: 65
+nav_order: 66
 parent: Modules
 ---
 
diff --git a/docs/modules/Reader.ts.md b/docs/modules/Reader.ts.md
index 8a3b25ea..0b33d8b7 100644
--- a/docs/modules/Reader.ts.md
+++ b/docs/modules/Reader.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Reader.ts
-nav_order: 66
+nav_order: 67
 parent: Modules
 ---
 
diff --git a/docs/modules/ReaderT.ts.md b/docs/modules/ReaderT.ts.md
index 245c07b7..fad0856c 100644
--- a/docs/modules/ReaderT.ts.md
+++ b/docs/modules/ReaderT.ts.md
@@ -1,6 +1,6 @@
 ---
 title: ReaderT.ts
-nav_order: 67
+nav_order: 68
 parent: Modules
 ---
 
diff --git a/docs/modules/ReaderTaskEither.ts.md b/docs/modules/ReaderTaskEither.ts.md
index c05bf554..55ae38a1 100644
--- a/docs/modules/ReaderTaskEither.ts.md
+++ b/docs/modules/ReaderTaskEither.ts.md
@@ -1,6 +1,6 @@
 ---
 title: ReaderTaskEither.ts
-nav_order: 68
+nav_order: 69
 parent: Modules
 ---
 
diff --git a/docs/modules/Record.ts.md b/docs/modules/Record.ts.md
index 286fa187..eff49408 100644
--- a/docs/modules/Record.ts.md
+++ b/docs/modules/Record.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Record.ts
-nav_order: 69
+nav_order: 70
 parent: Modules
 ---
 
diff --git a/docs/modules/Ring.ts.md b/docs/modules/Ring.ts.md
index f400080f..bde6bbe2 100644
--- a/docs/modules/Ring.ts.md
+++ b/docs/modules/Ring.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Ring.ts
-nav_order: 70
+nav_order: 71
 parent: Modules
 ---
 
diff --git a/docs/modules/Semigroup.ts.md b/docs/modules/Semigroup.ts.md
index a3d28935..f628dd62 100644
--- a/docs/modules/Semigroup.ts.md
+++ b/docs/modules/Semigroup.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Semigroup.ts
-nav_order: 71
+nav_order: 72
 parent: Modules
 ---
 
diff --git a/docs/modules/Semigroupoid.ts.md b/docs/modules/Semigroupoid.ts.md
index 6a7d70aa..17cab8ba 100644
--- a/docs/modules/Semigroupoid.ts.md
+++ b/docs/modules/Semigroupoid.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Semigroupoid.ts
-nav_order: 72
+nav_order: 73
 parent: Modules
 ---
 
diff --git a/docs/modules/Semiring.ts.md b/docs/modules/Semiring.ts.md
index 9f572649..ab297b67 100644
--- a/docs/modules/Semiring.ts.md
+++ b/docs/modules/Semiring.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Semiring.ts
-nav_order: 73
+nav_order: 74
 parent: Modules
 ---
 
diff --git a/docs/modules/Set.ts.md b/docs/modules/Set.ts.md
index 9534f1bb..05e9dfe7 100644
--- a/docs/modules/Set.ts.md
+++ b/docs/modules/Set.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Set.ts
-nav_order: 74
+nav_order: 75
 parent: Modules
 ---
 
diff --git a/docs/modules/Show.ts.md b/docs/modules/Show.ts.md
index e0e2d0e4..378f43c6 100644
--- a/docs/modules/Show.ts.md
+++ b/docs/modules/Show.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Show.ts
-nav_order: 75
+nav_order: 76
 parent: Modules
 ---
 
diff --git a/docs/modules/State.ts.md b/docs/modules/State.ts.md
index 4aebbbaa..a3043a93 100644
--- a/docs/modules/State.ts.md
+++ b/docs/modules/State.ts.md
@@ -1,6 +1,6 @@
 ---
 title: State.ts
-nav_order: 76
+nav_order: 77
 parent: Modules
 ---
 
diff --git a/docs/modules/StateReaderTaskEither.ts.md b/docs/modules/StateReaderTaskEither.ts.md
index c17fe1f8..cf58418f 100644
--- a/docs/modules/StateReaderTaskEither.ts.md
+++ b/docs/modules/StateReaderTaskEither.ts.md
@@ -1,6 +1,6 @@
 ---
 title: StateReaderTaskEither.ts
-nav_order: 77
+nav_order: 78
 parent: Modules
 ---
 
diff --git a/docs/modules/StateT.ts.md b/docs/modules/StateT.ts.md
index 644ec69f..7111499d 100644
--- a/docs/modules/StateT.ts.md
+++ b/docs/modules/StateT.ts.md
@@ -1,6 +1,6 @@
 ---
 title: StateT.ts
-nav_order: 78
+nav_order: 79
 parent: Modules
 ---
 
diff --git a/docs/modules/Store.ts.md b/docs/modules/Store.ts.md
index 0eb42d29..2f677284 100644
--- a/docs/modules/Store.ts.md
+++ b/docs/modules/Store.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Store.ts
-nav_order: 79
+nav_order: 80
 parent: Modules
 ---
 
diff --git a/docs/modules/Strong.ts.md b/docs/modules/Strong.ts.md
index 230be6f9..1c18ab1b 100644
--- a/docs/modules/Strong.ts.md
+++ b/docs/modules/Strong.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Strong.ts
-nav_order: 80
+nav_order: 81
 parent: Modules
 ---
 
diff --git a/docs/modules/Task.ts.md b/docs/modules/Task.ts.md
index 92509356..02ffc81c 100644
--- a/docs/modules/Task.ts.md
+++ b/docs/modules/Task.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Task.ts
-nav_order: 81
+nav_order: 82
 parent: Modules
 ---
 
diff --git a/docs/modules/TaskEither.ts.md b/docs/modules/TaskEither.ts.md
index e393a6e5..943eee46 100644
--- a/docs/modules/TaskEither.ts.md
+++ b/docs/modules/TaskEither.ts.md
@@ -1,6 +1,6 @@
 ---
 title: TaskEither.ts
-nav_order: 82
+nav_order: 83
 parent: Modules
 ---
 
diff --git a/docs/modules/These.ts.md b/docs/modules/These.ts.md
index ef247ebc..729593ef 100644
--- a/docs/modules/These.ts.md
+++ b/docs/modules/These.ts.md
@@ -1,6 +1,6 @@
 ---
 title: These.ts
-nav_order: 83
+nav_order: 84
 parent: Modules
 ---
 
diff --git a/docs/modules/Trace.ts.md b/docs/modules/Trace.ts.md
index ab5251b7..d26e185d 100644
--- a/docs/modules/Trace.ts.md
+++ b/docs/modules/Trace.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Trace.ts
-nav_order: 84
+nav_order: 85
 parent: Modules
 ---
 
diff --git a/docs/modules/Traced.ts.md b/docs/modules/Traced.ts.md
index e5feb3b8..7c28b66b 100644
--- a/docs/modules/Traced.ts.md
+++ b/docs/modules/Traced.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Traced.ts
-nav_order: 85
+nav_order: 86
 parent: Modules
 ---
 
diff --git a/docs/modules/Traversable.ts.md b/docs/modules/Traversable.ts.md
index 25792d95..1147bf41 100644
--- a/docs/modules/Traversable.ts.md
+++ b/docs/modules/Traversable.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Traversable.ts
-nav_order: 86
+nav_order: 87
 parent: Modules
 ---
 
diff --git a/docs/modules/TraversableWithIndex.ts.md b/docs/modules/TraversableWithIndex.ts.md
index bbc3d641..3ab9231a 100644
--- a/docs/modules/TraversableWithIndex.ts.md
+++ b/docs/modules/TraversableWithIndex.ts.md
@@ -1,6 +1,6 @@
 ---
 title: TraversableWithIndex.ts
-nav_order: 87
+nav_order: 88
 parent: Modules
 ---
 
diff --git a/docs/modules/Tree.ts.md b/docs/modules/Tree.ts.md
index bedbca9f..ca92d3aa 100644
--- a/docs/modules/Tree.ts.md
+++ b/docs/modules/Tree.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Tree.ts
-nav_order: 88
+nav_order: 89
 parent: Modules
 ---
 
diff --git a/docs/modules/Tuple.ts.md b/docs/modules/Tuple.ts.md
index 650ee373..4183d505 100644
--- a/docs/modules/Tuple.ts.md
+++ b/docs/modules/Tuple.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Tuple.ts
-nav_order: 89
+nav_order: 90
 parent: Modules
 ---
 
diff --git a/docs/modules/Unfoldable.ts.md b/docs/modules/Unfoldable.ts.md
index e87c2056..59c72cab 100644
--- a/docs/modules/Unfoldable.ts.md
+++ b/docs/modules/Unfoldable.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Unfoldable.ts
-nav_order: 90
+nav_order: 91
 parent: Modules
 ---
 
diff --git a/docs/modules/Validation.ts.md b/docs/modules/Validation.ts.md
index 0283f30f..82890412 100644
--- a/docs/modules/Validation.ts.md
+++ b/docs/modules/Validation.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Validation.ts
-nav_order: 91
+nav_order: 92
 parent: Modules
 ---
 
diff --git a/docs/modules/Witherable.ts.md b/docs/modules/Witherable.ts.md
index a958fe58..2e4f2db3 100644
--- a/docs/modules/Witherable.ts.md
+++ b/docs/modules/Witherable.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Witherable.ts
-nav_order: 92
+nav_order: 93
 parent: Modules
 ---
 
diff --git a/docs/modules/Writer.ts.md b/docs/modules/Writer.ts.md
index 52007e23..bdd705a8 100644
--- a/docs/modules/Writer.ts.md
+++ b/docs/modules/Writer.ts.md
@@ -1,6 +1,6 @@
 ---
 title: Writer.ts
-nav_order: 93
+nav_order: 94
 parent: Modules
 ---
 
diff --git a/docs/modules/index.ts.md b/docs/modules/index.ts.md
index 9d189254..927d5d5c 100644
--- a/docs/modules/index.ts.md
+++ b/docs/modules/index.ts.md
@@ -69,6 +69,7 @@ parent: Modules
 - [optionT (export)](#optiont-export)
 - [ord (export)](#ord-export)
 - [ordering (export)](#ordering-export)
+- [pipeable (export)](#pipeable-export)
 - [plus (export)](#plus-export)
 - [profunctor (export)](#profunctor-export)
 - [random (export)](#random-export)
@@ -591,6 +592,14 @@ export { ord }
 export { ordering }
 ```
 
+# pipeable (export)
+
+**Signature**
+
+```ts
+export { pipeable }
+```
+
 # plus (export)
 
 **Signature**
diff --git a/docs/modules/pipeable.ts.md b/docs/modules/pipeable.ts.md
new file mode 100644
index 00000000..85f786df
--- /dev/null
+++ b/docs/modules/pipeable.ts.md
@@ -0,0 +1,1074 @@
+---
+title: pipeable.ts
+nav_order: 63
+parent: Modules
+---
+
+---
+
+<h2 class="text-delta">Table of contents</h2>
+
+- [PipeableAlt (interface)](#pipeablealt-interface)
+- [PipeableAlt1 (interface)](#pipeablealt1-interface)
+- [PipeableAlt2 (interface)](#pipeablealt2-interface)
+- [PipeableAlt2C (interface)](#pipeablealt2c-interface)
+- [PipeableAlt3 (interface)](#pipeablealt3-interface)
+- [PipeableApply (interface)](#pipeableapply-interface)
+- [PipeableApply1 (interface)](#pipeableapply1-interface)
+- [PipeableApply2 (interface)](#pipeableapply2-interface)
+- [PipeableApply2C (interface)](#pipeableapply2c-interface)
+- [PipeableApply3 (interface)](#pipeableapply3-interface)
+- [PipeableBifunctor (interface)](#pipeablebifunctor-interface)
+- [PipeableBifunctor2 (interface)](#pipeablebifunctor2-interface)
+- [PipeableBifunctor3 (interface)](#pipeablebifunctor3-interface)
+- [PipeableChain (interface)](#pipeablechain-interface)
+- [PipeableChain1 (interface)](#pipeablechain1-interface)
+- [PipeableChain2 (interface)](#pipeablechain2-interface)
+- [PipeableChain2C (interface)](#pipeablechain2c-interface)
+- [PipeableChain3 (interface)](#pipeablechain3-interface)
+- [PipeableCompactable (interface)](#pipeablecompactable-interface)
+- [PipeableCompactable1 (interface)](#pipeablecompactable1-interface)
+- [PipeableCompactable2 (interface)](#pipeablecompactable2-interface)
+- [PipeableCompactable2C (interface)](#pipeablecompactable2c-interface)
+- [PipeableCompactable3 (interface)](#pipeablecompactable3-interface)
+- [PipeableExtend (interface)](#pipeableextend-interface)
+- [PipeableExtend1 (interface)](#pipeableextend1-interface)
+- [PipeableExtend2 (interface)](#pipeableextend2-interface)
+- [PipeableExtend2C (interface)](#pipeableextend2c-interface)
+- [PipeableExtend3 (interface)](#pipeableextend3-interface)
+- [PipeableFilterable (interface)](#pipeablefilterable-interface)
+- [PipeableFilterable1 (interface)](#pipeablefilterable1-interface)
+- [PipeableFilterable2 (interface)](#pipeablefilterable2-interface)
+- [PipeableFilterable2C (interface)](#pipeablefilterable2c-interface)
+- [PipeableFilterable3 (interface)](#pipeablefilterable3-interface)
+- [PipeableFilterableWithIndex (interface)](#pipeablefilterablewithindex-interface)
+- [PipeableFilterableWithIndex1 (interface)](#pipeablefilterablewithindex1-interface)
+- [PipeableFilterableWithIndex2 (interface)](#pipeablefilterablewithindex2-interface)
+- [PipeableFilterableWithIndex2C (interface)](#pipeablefilterablewithindex2c-interface)
+- [PipeableFilterableWithIndex3 (interface)](#pipeablefilterablewithindex3-interface)
+- [PipeableFoldable (interface)](#pipeablefoldable-interface)
+- [PipeableFoldable1 (interface)](#pipeablefoldable1-interface)
+- [PipeableFoldable2 (interface)](#pipeablefoldable2-interface)
+- [PipeableFoldable2C (interface)](#pipeablefoldable2c-interface)
+- [PipeableFoldable3 (interface)](#pipeablefoldable3-interface)
+- [PipeableFoldableWithIndex (interface)](#pipeablefoldablewithindex-interface)
+- [PipeableFoldableWithIndex1 (interface)](#pipeablefoldablewithindex1-interface)
+- [PipeableFoldableWithIndex2 (interface)](#pipeablefoldablewithindex2-interface)
+- [PipeableFoldableWithIndex2C (interface)](#pipeablefoldablewithindex2c-interface)
+- [PipeableFoldableWithIndex3 (interface)](#pipeablefoldablewithindex3-interface)
+- [PipeableFunctor (interface)](#pipeablefunctor-interface)
+- [PipeableFunctor1 (interface)](#pipeablefunctor1-interface)
+- [PipeableFunctor2 (interface)](#pipeablefunctor2-interface)
+- [PipeableFunctor2C (interface)](#pipeablefunctor2c-interface)
+- [PipeableFunctor3 (interface)](#pipeablefunctor3-interface)
+- [PipeableFunctorWithIndex (interface)](#pipeablefunctorwithindex-interface)
+- [PipeableFunctorWithIndex1 (interface)](#pipeablefunctorwithindex1-interface)
+- [PipeableFunctorWithIndex2 (interface)](#pipeablefunctorwithindex2-interface)
+- [PipeableFunctorWithIndex2C (interface)](#pipeablefunctorwithindex2c-interface)
+- [PipeableFunctorWithIndex3 (interface)](#pipeablefunctorwithindex3-interface)
+- [PipeableProfunctor (interface)](#pipeableprofunctor-interface)
+- [PipeableProfunctor2 (interface)](#pipeableprofunctor2-interface)
+- [PipeableProfunctor2C (interface)](#pipeableprofunctor2c-interface)
+- [PipeableProfunctor3 (interface)](#pipeableprofunctor3-interface)
+- [PipeableSemigroupoid (interface)](#pipeablesemigroupoid-interface)
+- [PipeableSemigroupoid2 (interface)](#pipeablesemigroupoid2-interface)
+- [PipeableSemigroupoid2C (interface)](#pipeablesemigroupoid2c-interface)
+- [PipeableSemigroupoid3 (interface)](#pipeablesemigroupoid3-interface)
+- [pipe (constant)](#pipe-constant)
+- [apply (function)](#apply-function)
+- [pipeable (function)](#pipeable-function)
+
+---
+
+# PipeableAlt (interface)
+
+**Signature**
+
+```ts
+export interface PipeableAlt<F> {
+  readonly alt: <A>(that: () => HKT<F, A>) => (fa: HKT<F, A>) => HKT<F, A>
+}
+```
+
+# PipeableAlt1 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableAlt1<F extends URIS> {
+  readonly alt: <A>(that: () => Type<F, A>) => (fa: Type<F, A>) => Type<F, A>
+}
+```
+
+# PipeableAlt2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableAlt2<F extends URIS2> {
+  readonly alt: <L, A>(that: () => Type2<F, L, A>) => (fa: Type2<F, L, A>) => Type2<F, L, A>
+}
+```
+
+# PipeableAlt2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableAlt2C<F extends URIS2, L> {
+  readonly alt: <A>(that: () => Type2<F, L, A>) => (fa: Type2<F, L, A>) => Type2<F, L, A>
+}
+```
+
+# PipeableAlt3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableAlt3<F extends URIS3> {
+  readonly alt: <U, L, A>(that: () => Type3<F, U, L, A>) => (fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+}
+```
+
+# PipeableApply (interface)
+
+**Signature**
+
+```ts
+export interface PipeableApply<F> extends PipeableFunctor<F> {
+  readonly ap: <A, B>(fab: HKT<F, (a: A) => B>) => (fa: HKT<F, A>) => HKT<F, B>
+  readonly apFirst: <B>(fb: HKT<F, B>) => <A>(fa: HKT<F, A>) => HKT<F, A>
+  readonly apSecond: <B>(fb: HKT<F, B>) => <A>(fa: HKT<F, A>) => HKT<F, B>
+}
+```
+
+# PipeableApply1 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableApply1<F extends URIS> extends PipeableFunctor1<F> {
+  readonly ap: <A, B>(fab: Type<F, (a: A) => B>) => (fa: Type<F, A>) => Type<F, B>
+  readonly apFirst: <B>(fb: Type<F, B>) => <A>(fa: Type<F, A>) => Type<F, A>
+  readonly apSecond: <B>(fb: Type<F, B>) => <A>(fa: Type<F, A>) => Type<F, B>
+}
+```
+
+# PipeableApply2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableApply2<F extends URIS2> extends PipeableFunctor2<F> {
+  readonly ap: <L, A, B>(fab: Type2<F, L, (a: A) => B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly apFirst: <L, B>(fb: Type2<F, L, B>) => <A>(fa: Type2<F, L, A>) => Type2<F, L, A>
+  readonly apSecond: <L, B>(fb: Type2<F, L, B>) => <A>(fa: Type2<F, L, A>) => Type2<F, L, B>
+}
+```
+
+# PipeableApply2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableApply2C<F extends URIS2, L> extends PipeableFunctor2C<F, L> {
+  readonly ap: <A, B>(fab: Type2<F, L, (a: A) => B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly apFirst: <A>(fb: Type2<F, L, A>) => <B>(fb: Type2<F, L, B>) => Type2<F, L, A>
+  readonly apSecond: <A>(fb: Type2<F, L, A>) => <B>(fb: Type2<F, L, B>) => Type2<F, L, B>
+}
+```
+
+# PipeableApply3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableApply3<F extends URIS3> extends PipeableFunctor3<F> {
+  readonly ap: <U, L, A, B>(fab: Type3<F, U, L, (a: A) => B>) => (fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+  readonly apFirst: <U, L, B>(fb: Type3<F, U, L, B>) => <A>(fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+  readonly apSecond: <U, L, B>(fb: Type3<F, U, L, B>) => <A>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+}
+```
+
+# PipeableBifunctor (interface)
+
+**Signature**
+
+```ts
+export interface PipeableBifunctor<F> {
+  readonly bimap: <L, A, M, B>(f: (l: L) => M, g: (a: A) => B) => (fa: HKT2<F, L, A>) => HKT2<F, M, B>
+  readonly mapLeft: <L, A, M>(f: (l: L) => M) => (fa: HKT2<F, L, A>) => HKT2<F, M, A>
+}
+```
+
+# PipeableBifunctor2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableBifunctor2<F extends URIS2> {
+  readonly bimap: <L, A, M, B>(f: (l: L) => M, g: (a: A) => B) => (fa: Type2<F, L, A>) => Type2<F, M, B>
+  readonly mapLeft: <L, A, M>(f: (l: L) => M) => (fa: Type2<F, L, A>) => Type2<F, M, A>
+}
+```
+
+# PipeableBifunctor3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableBifunctor3<F extends URIS3> {
+  readonly bimap: <L, A, M, B>(f: (l: L) => M, g: (a: A) => B) => <U>(fa: Type3<F, U, L, A>) => Type3<F, U, M, B>
+  readonly mapLeft: <L, A, M>(f: (l: L) => M) => <U>(fa: Type3<F, U, L, A>) => Type3<F, U, M, A>
+}
+```
+
+# PipeableChain (interface)
+
+**Signature**
+
+```ts
+export interface PipeableChain<F> extends PipeableApply<F> {
+  readonly chain: <A, B>(f: (a: A) => HKT<F, B>) => (ma: HKT<F, A>) => HKT<F, B>
+  readonly flatten: <A>(mma: HKT<F, HKT<F, A>>) => HKT<F, A>
+}
+```
+
+# PipeableChain1 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableChain1<F extends URIS> extends PipeableApply1<F> {
+  readonly chain: <A, B>(f: (a: A) => Type<F, B>) => (ma: Type<F, A>) => Type<F, B>
+  readonly flatten: <A>(mma: Type<F, Type<F, A>>) => Type<F, A>
+}
+```
+
+# PipeableChain2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableChain2<F extends URIS2> extends PipeableApply2<F> {
+  readonly chain: <L, A, B>(f: (a: A) => Type2<F, L, B>) => (ma: Type2<F, L, A>) => Type2<F, L, B>
+  readonly flatten: <L, A>(mma: Type2<F, L, Type2<F, L, A>>) => Type2<F, L, A>
+}
+```
+
+# PipeableChain2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableChain2C<F extends URIS2, L> extends PipeableApply2C<F, L> {
+  readonly chain: <A, B>(f: (a: A) => Type2<F, L, B>) => (ma: Type2<F, L, A>) => Type2<F, L, B>
+  readonly flatten: <A>(mma: Type2<F, L, Type2<F, L, A>>) => Type2<F, L, A>
+}
+```
+
+# PipeableChain3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableChain3<F extends URIS3> extends PipeableApply3<F> {
+  readonly chain: <U, L, A, B>(f: (a: A) => Type3<F, U, L, B>) => (ma: Type3<F, U, L, A>) => Type3<F, U, L, B>
+  readonly flatten: <U, L, A>(mma: Type3<F, U, L, Type3<F, U, L, A>>) => Type3<F, U, L, A>
+}
+```
+
+# PipeableCompactable (interface)
+
+**Signature**
+
+```ts
+export interface PipeableCompactable<F> {
+  readonly compact: <A>(fa: HKT<F, Option<A>>) => HKT<F, A>
+  readonly separate: <A, B>(fa: HKT<F, Either<A, B>>) => Separated<HKT<F, A>, HKT<F, B>>
+}
+```
+
+# PipeableCompactable1 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableCompactable1<F extends URIS> {
+  readonly compact: <A>(fa: Type<F, Option<A>>) => Type<F, A>
+  readonly separate: <A, B>(fa: Type<F, Either<A, B>>) => Separated<Type<F, A>, Type<F, B>>
+}
+```
+
+# PipeableCompactable2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableCompactable2<F extends URIS2> {
+  readonly compact: <L, A>(fa: Type2<F, L, Option<A>>) => Type2<F, L, A>
+  readonly separate: <L, A, B>(fa: Type2<F, L, Either<A, B>>) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+}
+```
+
+# PipeableCompactable2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableCompactable2C<F extends URIS2, L> {
+  readonly compact: <A>(fa: Type2<F, L, Option<A>>) => Type2<F, L, A>
+  readonly separate: <A, B>(fa: Type2<F, L, Either<A, B>>) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+}
+```
+
+# PipeableCompactable3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableCompactable3<F extends URIS3> {
+  readonly compact: <U, L, A>(fa: Type3<F, U, L, Option<A>>) => Type3<F, U, L, A>
+  readonly separate: <U, L, A, B>(fa: Type3<F, U, L, Either<A, B>>) => Separated<Type3<F, U, L, A>, Type3<F, U, L, B>>
+}
+```
+
+# PipeableExtend (interface)
+
+**Signature**
+
+```ts
+export interface PipeableExtend<F> extends PipeableFunctor<F> {
+  readonly extend: <A, B>(f: (fa: HKT<F, A>) => B) => (ma: HKT<F, A>) => HKT<F, B>
+  readonly duplicate: <A>(ma: HKT<F, A>) => HKT<F, HKT<F, A>>
+}
+```
+
+# PipeableExtend1 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableExtend1<F extends URIS> extends PipeableFunctor1<F> {
+  readonly extend: <A, B>(f: (fa: Type<F, A>) => B) => (ma: Type<F, A>) => Type<F, B>
+  readonly duplicate: <A>(ma: Type<F, A>) => Type<F, Type<F, A>>
+}
+```
+
+# PipeableExtend2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableExtend2<F extends URIS2> extends PipeableFunctor2<F> {
+  readonly extend: <L, A, B>(f: (fa: Type2<F, L, A>) => B) => (ma: Type2<F, L, A>) => Type2<F, L, B>
+  readonly duplicate: <L, A>(ma: Type2<F, L, A>) => Type2<F, L, Type2<F, L, A>>
+}
+```
+
+# PipeableExtend2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableExtend2C<F extends URIS2, L> extends PipeableFunctor2C<F, L> {
+  readonly extend: <A, B>(f: (fa: Type2<F, L, A>) => B) => (ma: Type2<F, L, A>) => Type2<F, L, B>
+  readonly duplicate: <A>(ma: Type2<F, L, A>) => Type2<F, L, Type2<F, L, A>>
+}
+```
+
+# PipeableExtend3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableExtend3<F extends URIS3> extends PipeableFunctor3<F> {
+  readonly extend: <U, L, A, B>(f: (fa: Type3<F, U, L, A>) => B) => (ma: Type3<F, U, L, A>) => Type3<F, U, L, B>
+  readonly duplicate: <U, L, A>(ma: Type3<F, U, L, A>) => Type3<F, U, L, Type3<F, U, L, A>>
+}
+```
+
+# PipeableFilterable (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFilterable<F> extends PipeableCompactable<F> {
+  readonly filter: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: HKT<F, A>) => HKT<F, B>
+    <A>(predicate: Predicate<A>): (fa: HKT<F, A>) => HKT<F, A>
+  }
+  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => (fa: HKT<F, A>) => HKT<F, B>
+  readonly partition: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: HKT<F, A>) => Separated<HKT<F, A>, HKT<F, B>>
+    <A>(predicate: Predicate<A>): (fa: HKT<F, A>) => Separated<HKT<F, A>, HKT<F, A>>
+  }
+  readonly partitionMap: <A, RL, RR>(
+    f: (a: A) => Either<RL, RR>
+  ) => (fa: HKT<F, A>) => Separated<HKT<F, RL>, HKT<F, RR>>
+}
+```
+
+# PipeableFilterable1 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFilterable1<F extends URIS> extends PipeableCompactable1<F> {
+  readonly filter: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: Type<F, A>) => Type<F, B>
+    <A>(predicate: Predicate<A>): (fa: Type<F, A>) => Type<F, A>
+  }
+  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => (fa: Type<F, A>) => Type<F, B>
+  readonly partition: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: Type<F, A>) => Separated<Type<F, A>, Type<F, B>>
+    <A>(predicate: Predicate<A>): (fa: Type<F, A>) => Separated<Type<F, A>, Type<F, A>>
+  }
+  readonly partitionMap: <A, RL, RR>(
+    f: (a: A) => Either<RL, RR>
+  ) => (fa: Type<F, A>) => Separated<Type<F, RL>, Type<F, RR>>
+}
+```
+
+# PipeableFilterable2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFilterable2<F extends URIS2> extends PipeableCompactable2<F> {
+  readonly filter: {
+    <A, B extends A>(refinement: Refinement<A, B>): <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+    <A>(predicate: Predicate<A>): <L>(fa: Type2<F, L, A>) => Type2<F, L, A>
+  }
+  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly partition: {
+    <A, B extends A>(refinement: Refinement<A, B>): <L>(fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+    <A>(predicate: Predicate<A>): <L>(fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, A>>
+  }
+  readonly partitionMap: <A, RL, RR>(
+    f: (a: A) => Either<RL, RR>
+  ) => <L>(fa: Type2<F, L, A>) => Separated<Type2<F, L, RL>, Type2<F, L, RR>>
+}
+```
+
+# PipeableFilterable2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFilterable2C<F extends URIS2, L> extends PipeableCompactable2C<F, L> {
+  readonly filter: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: Type2<F, L, A>) => Type2<F, L, B>
+    <A>(predicate: Predicate<A>): (fa: Type2<F, L, A>) => Type2<F, L, A>
+  }
+  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly partition: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+    <A>(predicate: Predicate<A>): (fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, A>>
+  }
+  readonly partitionMap: <A, RL, RR>(
+    f: (a: A) => Either<RL, RR>
+  ) => (fa: Type2<F, L, A>) => Separated<Type2<F, L, RL>, Type2<F, L, RR>>
+}
+```
+
+# PipeableFilterable3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFilterable3<F extends URIS3> extends PipeableCompactable3<F> {
+  readonly filter: {
+    <A, B extends A>(refinement: Refinement<A, B>): <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+    <A>(predicate: Predicate<A>): <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+  }
+  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+  readonly partition: {
+    <A, B extends A>(refinement: Refinement<A, B>): <U, L>(
+      fa: Type3<F, U, L, A>
+    ) => Separated<Type3<F, U, L, A>, Type3<F, U, L, B>>
+    <A>(predicate: Predicate<A>): <U, L>(fa: Type3<F, U, L, A>) => Separated<Type3<F, U, L, A>, Type3<F, U, L, A>>
+  }
+  readonly partitionMap: <A, RL, RR>(
+    f: (a: A) => Either<RL, RR>
+  ) => <U, L>(fa: Type3<F, U, L, A>) => Separated<Type3<F, U, L, RL>, Type3<F, U, L, RR>>
+}
+```
+
+# PipeableFilterableWithIndex (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFilterableWithIndex<F, I> extends PipeableFilterable<F> {
+  readonly filterWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (fa: HKT<F, A>) => HKT<F, B>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: HKT<F, A>) => HKT<F, A>
+  }
+  readonly filterMapWithIndex: <A, B>(f: (i: I, a: A) => Option<B>) => (fa: HKT<F, A>) => HKT<F, B>
+  readonly partitionWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (fa: HKT<F, A>) => Separated<HKT<F, A>, HKT<F, B>>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: HKT<F, A>) => Separated<HKT<F, A>, HKT<F, A>>
+  }
+  readonly partitionMapWithIndex: <A, RL, RR>(
+    f: (i: I, a: A) => Either<RL, RR>
+  ) => (fa: HKT<F, A>) => Separated<HKT<F, RL>, HKT<F, RR>>
+}
+```
+
+# PipeableFilterableWithIndex1 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFilterableWithIndex1<F extends URIS, I> extends PipeableFilterable1<F> {
+  readonly filterWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (fa: Type<F, A>) => Type<F, B>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: Type<F, A>) => Type<F, A>
+  }
+  readonly filterMapWithIndex: <A, B>(f: (i: I, a: A) => Option<B>) => (fa: Type<F, A>) => Type<F, B>
+  readonly partitionWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (fa: Type<F, A>) => Separated<Type<F, A>, Type<F, B>>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: Type<F, A>) => Separated<Type<F, A>, Type<F, A>>
+  }
+  readonly partitionMapWithIndex: <A, RL, RR>(
+    f: (i: I, a: A) => Either<RL, RR>
+  ) => (fa: Type<F, A>) => Separated<Type<F, RL>, Type<F, RR>>
+}
+```
+
+# PipeableFilterableWithIndex2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFilterableWithIndex2<F extends URIS2, I> extends PipeableFilterable2<F> {
+  readonly filterWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+    <A>(predicate: PredicateWithIndex<I, A>): <L>(fa: Type2<F, L, A>) => Type2<F, L, A>
+  }
+  readonly filterMapWithIndex: <A, B>(f: (i: I, a: A) => Option<B>) => <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly partitionWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): <L>(
+      fa: Type2<F, L, A>
+    ) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+    <A>(predicate: PredicateWithIndex<I, A>): <L>(fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, A>>
+  }
+  readonly partitionMapWithIndex: <A, RL, RR>(
+    f: (i: I, a: A) => Either<RL, RR>
+  ) => <L>(fa: Type2<F, L, A>) => Separated<Type2<F, L, RL>, Type2<F, L, RR>>
+}
+```
+
+# PipeableFilterableWithIndex2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFilterableWithIndex2C<F extends URIS2, I, L> extends PipeableFilterable2C<F, L> {
+  readonly filterWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (fa: Type2<F, L, A>) => Type2<F, L, B>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: Type2<F, L, A>) => Type2<F, L, A>
+  }
+  readonly filterMapWithIndex: <A, B>(f: (i: I, a: A) => Option<B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly partitionWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (
+      fa: Type2<F, L, A>
+    ) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, A>>
+  }
+  readonly partitionMapWithIndex: <A, RL, RR>(
+    f: (i: I, a: A) => Either<RL, RR>
+  ) => (fa: Type2<F, L, A>) => Separated<Type2<F, L, RL>, Type2<F, L, RR>>
+}
+```
+
+# PipeableFilterableWithIndex3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFilterableWithIndex3<F extends URIS3, I> extends PipeableFilterable3<F> {
+  readonly filterWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+    <A>(predicate: PredicateWithIndex<I, A>): <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+  }
+  readonly filterMapWithIndex: <A, B>(
+    f: (i: I, a: A) => Option<B>
+  ) => <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+  readonly partitionWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): <U, L>(
+      fa: Type3<F, U, L, A>
+    ) => Separated<Type3<F, U, L, A>, Type3<F, U, L, B>>
+    <A>(predicate: PredicateWithIndex<I, A>): <U, L>(
+      fa: Type3<F, U, L, A>
+    ) => Separated<Type3<F, U, L, A>, Type3<F, U, L, A>>
+  }
+  readonly partitionMapWithIndex: <A, RL, RR>(
+    f: (i: I, a: A) => Either<RL, RR>
+  ) => <U, L>(fa: Type3<F, U, L, A>) => Separated<Type3<F, U, L, RL>, Type3<F, U, L, RR>>
+}
+```
+
+# PipeableFoldable (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFoldable<F> {
+  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => (fa: HKT<F, A>) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => (fa: HKT<F, A>) => M
+  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => (fa: HKT<F, A>) => B
+}
+```
+
+# PipeableFoldable1 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFoldable1<F extends URIS> {
+  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => (fa: Type<F, A>) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => (fa: Type<F, A>) => M
+  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => (fa: Type<F, A>) => B
+}
+```
+
+# PipeableFoldable2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFoldable2<F extends URIS2> {
+  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => <L>(fa: Type2<F, L, A>) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => <L>(fa: Type2<F, L, A>) => M
+  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => <L>(fa: Type2<F, L, A>) => B
+}
+```
+
+# PipeableFoldable2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFoldable2C<F extends URIS2, L> {
+  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => (fa: Type2<F, L, A>) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => (fa: Type2<F, L, A>) => M
+  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => (fa: Type2<F, L, A>) => B
+}
+```
+
+# PipeableFoldable3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFoldable3<F extends URIS3> {
+  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => <U, L>(fa: Type3<F, U, L, A>) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => <U, L>(fa: Type3<F, U, L, A>) => M
+  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => <U, L>(fa: Type3<F, U, L, A>) => B
+}
+```
+
+# PipeableFoldableWithIndex (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFoldableWithIndex<F, I> extends PipeableFoldable<F> {
+  readonly reduceWithIndex: <A, B>(b: B, f: (i: I, b: B, a: A) => B) => (fa: HKT<F, A>) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <A>(f: (i: I, a: A) => M) => (fa: HKT<F, A>) => M
+  readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => (fa: HKT<F, A>) => B
+}
+```
+
+# PipeableFoldableWithIndex1 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFoldableWithIndex1<F extends URIS, I> extends PipeableFoldable1<F> {
+  readonly reduceWithIndex: <A, B>(b: B, f: (i: I, b: B, a: A) => B) => (fa: Type<F, A>) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <A>(f: (i: I, a: A) => M) => (fa: Type<F, A>) => M
+  readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => (fa: Type<F, A>) => B
+}
+```
+
+# PipeableFoldableWithIndex2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFoldableWithIndex2<F extends URIS2, I> extends PipeableFoldable2<F> {
+  readonly reduceWithIndex: <A, B>(b: B, f: (i: I, b: B, a: A) => B) => <L>(fa: Type2<F, L, A>) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <A>(f: (i: I, a: A) => M) => <L>(fa: Type2<F, L, A>) => M
+  readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => <L>(fa: Type2<F, L, A>) => B
+}
+```
+
+# PipeableFoldableWithIndex2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFoldableWithIndex2C<F extends URIS2, I, L> extends PipeableFoldable2C<F, L> {
+  readonly reduceWithIndex: <A, B>(b: B, f: (i: I, b: B, a: A) => B) => (fa: Type2<F, L, A>) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <A>(f: (i: I, a: A) => M) => (fa: Type2<F, L, A>) => M
+  readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => (fa: Type2<F, L, A>) => B
+}
+```
+
+# PipeableFoldableWithIndex3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFoldableWithIndex3<F extends URIS3, I> extends PipeableFoldable3<F> {
+  readonly reduceWithIndex: <A, B>(b: B, f: (i: I, b: B, a: A) => B) => <U, L>(fa: Type3<F, U, L, A>) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <A>(f: (i: I, a: A) => M) => <U, L>(fa: Type3<F, U, L, A>) => M
+  readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => <U, L>(fa: Type3<F, U, L, A>) => B
+}
+```
+
+# PipeableFunctor (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFunctor<F> {
+  readonly map: <A, B>(f: (a: A) => B) => (fa: HKT<F, A>) => HKT<F, B>
+}
+```
+
+# PipeableFunctor1 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFunctor1<F extends URIS> {
+  readonly map: <A, B>(f: (a: A) => B) => (fa: Type<F, A>) => Type<F, B>
+}
+```
+
+# PipeableFunctor2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFunctor2<F extends URIS2> {
+  readonly map: <A, B>(f: (a: A) => B) => <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+}
+```
+
+# PipeableFunctor2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFunctor2C<F extends URIS2, L> {
+  readonly map: <A, B>(f: (a: A) => B) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+}
+```
+
+# PipeableFunctor3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFunctor3<F extends URIS3> {
+  readonly map: <A, B>(f: (a: A) => B) => <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+}
+```
+
+# PipeableFunctorWithIndex (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFunctorWithIndex<F, I> extends PipeableFunctor<F> {
+  readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => (fa: HKT<F, A>) => HKT<F, B>
+}
+```
+
+# PipeableFunctorWithIndex1 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFunctorWithIndex1<F extends URIS, I> extends PipeableFunctor1<F> {
+  readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => (fa: Type<F, A>) => Type<F, B>
+}
+```
+
+# PipeableFunctorWithIndex2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFunctorWithIndex2<F extends URIS2, I> extends PipeableFunctor2<F> {
+  readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+}
+```
+
+# PipeableFunctorWithIndex2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFunctorWithIndex2C<F extends URIS2, I, L> extends PipeableFunctor2C<F, L> {
+  readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+}
+```
+
+# PipeableFunctorWithIndex3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableFunctorWithIndex3<F extends URIS3, I> extends PipeableFunctor3<F> {
+  readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+}
+```
+
+# PipeableProfunctor (interface)
+
+**Signature**
+
+```ts
+export interface PipeableProfunctor<F> {
+  readonly map: <L, A, B>(f: (a: A) => B) => (fa: HKT2<F, L, A>) => HKT2<F, L, B>
+  readonly promap: <A, B, C, D>(f: (a: A) => B, g: (c: C) => D) => (fbc: HKT2<F, B, C>) => HKT2<F, A, D>
+}
+```
+
+# PipeableProfunctor2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableProfunctor2<F extends URIS2> extends PipeableFunctor2<F> {
+  readonly promap: <A, B, C, D>(f: (a: A) => B, g: (c: C) => D) => (fbc: Type2<F, B, C>) => Type2<F, A, D>
+}
+```
+
+# PipeableProfunctor2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableProfunctor2C<F extends URIS2, L> extends PipeableFunctor2C<F, L> {
+  readonly promap: <A, C, D>(f: (a: A) => L, g: (c: C) => D) => (flc: Type2<F, L, C>) => Type2<F, A, D>
+}
+```
+
+# PipeableProfunctor3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableProfunctor3<F extends URIS3> extends PipeableFunctor3<F> {
+  readonly promap: <U, A, B, C, D>(f: (a: A) => B, g: (c: C) => D) => (fbc: Type3<F, U, B, C>) => Type3<F, U, A, D>
+}
+```
+
+# PipeableSemigroupoid (interface)
+
+**Signature**
+
+```ts
+export interface PipeableSemigroupoid<F> {
+  readonly compose: <L, A>(la: HKT2<F, L, A>) => <B>(ab: HKT2<F, A, B>) => HKT2<F, L, B>
+}
+```
+
+# PipeableSemigroupoid2 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableSemigroupoid2<F extends URIS2> {
+  readonly compose: <L, A>(la: Type2<F, L, A>) => <B>(ab: Type2<F, A, B>) => Type2<F, L, B>
+}
+```
+
+# PipeableSemigroupoid2C (interface)
+
+**Signature**
+
+```ts
+export interface PipeableSemigroupoid2C<F extends URIS2, L> {
+  readonly compose: <A>(la: Type2<F, L, A>) => <B>(ab: Type2<F, A, B>) => Type2<F, L, B>
+}
+```
+
+# PipeableSemigroupoid3 (interface)
+
+**Signature**
+
+```ts
+export interface PipeableSemigroupoid3<F extends URIS3> {
+  readonly compose: <U, L, A>(la: Type3<F, U, L, A>) => <B>(ab: Type3<F, U, A, B>) => Type3<F, U, L, B>
+}
+```
+
+# pipe (constant)
+
+A re-export of `function`'s `pipe`
+
+**Signature**
+
+```ts
+export const pipe = ...
+```
+
+Added in v2.0.0
+
+# apply (function)
+
+**Signature**
+
+```ts
+export function apply<A, B>(a: A, f: (a: A) => B): B { ... }
+```
+
+Added in v2.0.0
+
+# pipeable (function)
+
+**Signature**
+
+```ts
+export function pipeable<F extends URIS3, I>(
+  I: { URI: F } & I
+): (I extends Chain3<F>
+  ? PipeableChain3<F>
+  : I extends Apply3<F>
+  ? PipeableApply3<F>
+  : I extends Functor3<F>
+  ? PipeableFunctor3<F>
+  : {}) &
+  (I extends FunctorWithIndex3<F, infer Ix> ? PipeableFunctorWithIndex3<F, Ix> : {}) &
+  (I extends Bifunctor3<F> ? PipeableBifunctor3<F> : {}) &
+  (I extends Extend3<F> ? PipeableExtend3<F> : {}) &
+  (I extends FoldableWithIndex3<F, infer Ix>
+    ? PipeableFoldableWithIndex3<F, Ix>
+    : I extends Foldable3<F>
+    ? PipeableFoldable3<F>
+    : {}) &
+  (I extends Alt3<F> ? PipeableAlt3<F> : {}) &
+  (I extends FilterableWithIndex3<F, infer Ix>
+    ? PipeableFilterableWithIndex3<F, Ix>
+    : I extends Filterable3<F>
+    ? PipeableFilterable3<F>
+    : I extends Compactable3<F>
+    ? PipeableCompactable3<F>
+    : {}) &
+  (I extends Profunctor3<F> ? PipeableProfunctor3<F> : {}) &
+  (I extends Semigroupoid3<F> ? PipeableSemigroupoid3<F> : {})
+export function pipeable<F extends URIS2, I, L>(
+  I: { URI: F; _L: L } & I
+): (I extends Chain2C<F, L>
+  ? PipeableChain2C<F, L>
+  : I extends Apply2C<F, L>
+  ? PipeableApply2C<F, L>
+  : I extends Functor2C<F, L>
+  ? PipeableFunctor2C<F, L>
+  : {}) &
+  (I extends FunctorWithIndex2C<F, infer Ix, L> ? PipeableFunctorWithIndex2C<F, Ix, L> : {}) &
+  (I extends Extend2C<F, L> ? PipeableExtend2C<F, L> : {}) &
+  (I extends FoldableWithIndex2C<F, infer Ix, L>
+    ? PipeableFoldableWithIndex2C<F, Ix, L>
+    : I extends Foldable2C<F, L>
+    ? PipeableFoldable2C<F, L>
+    : {}) &
+  (I extends Alt2C<F, L> ? PipeableAlt2C<F, L> : {}) &
+  (I extends FilterableWithIndex2C<F, infer Ix, L>
+    ? PipeableFilterableWithIndex2C<F, Ix, L>
+    : I extends Filterable2C<F, L>
+    ? PipeableFilterable2C<F, L>
+    : I extends Compactable2C<F, L>
+    ? PipeableCompactable2C<F, L>
+    : {}) &
+  (I extends Profunctor2C<F, L> ? PipeableProfunctor2C<F, L> : {}) &
+  (I extends Semigroupoid2C<F, L> ? PipeableSemigroupoid2C<F, L> : {})
+export function pipeable<F extends URIS2, I>(
+  I: { URI: F } & I
+): (I extends Chain2<F>
+  ? PipeableChain2<F>
+  : I extends Apply2<F>
+  ? PipeableApply2<F>
+  : I extends Functor2<F>
+  ? PipeableFunctor2<F>
+  : {}) &
+  (I extends FunctorWithIndex2<F, infer Ix> ? PipeableFunctorWithIndex2<F, Ix> : {}) &
+  (I extends Bifunctor2<F> ? PipeableBifunctor2<F> : {}) &
+  (I extends Extend2<F> ? PipeableExtend2<F> : {}) &
+  (I extends FoldableWithIndex2<F, infer Ix>
+    ? PipeableFoldableWithIndex2<F, Ix>
+    : I extends Foldable2<F>
+    ? PipeableFoldable2<F>
+    : {}) &
+  (I extends Alt2<F> ? PipeableAlt2<F> : {}) &
+  (I extends FilterableWithIndex2<F, infer Ix>
+    ? PipeableFilterableWithIndex2<F, Ix>
+    : I extends Filterable2<F>
+    ? PipeableFilterable2<F>
+    : I extends Compactable2<F>
+    ? PipeableCompactable2<F>
+    : {}) &
+  (I extends Profunctor2<F> ? PipeableProfunctor2<F> : {}) &
+  (I extends Semigroupoid2<F> ? PipeableSemigroupoid2<F> : {})
+export function pipeable<F extends URIS, I>(
+  I: { URI: F } & I
+): (I extends Chain1<F>
+  ? PipeableChain1<F>
+  : I extends Apply1<F>
+  ? PipeableApply1<F>
+  : I extends Functor1<F>
+  ? PipeableFunctor1<F>
+  : {}) &
+  (I extends FunctorWithIndex1<F, infer Ix> ? PipeableFunctorWithIndex1<F, Ix> : {}) &
+  (I extends Extend1<F> ? PipeableExtend1<F> : {}) &
+  (I extends FoldableWithIndex1<F, infer Ix>
+    ? PipeableFoldableWithIndex1<F, Ix>
+    : I extends Foldable1<F>
+    ? PipeableFoldable1<F>
+    : {}) &
+  (I extends Alt1<F> ? PipeableAlt1<F> : {}) &
+  (I extends FilterableWithIndex1<F, infer Ix>
+    ? PipeableFilterableWithIndex1<F, Ix>
+    : I extends Filterable1<F>
+    ? PipeableFilterable1<F>
+    : I extends Compactable1<F>
+    ? PipeableCompactable1<F>
+    : {})
+export function pipeable<F, I>(
+  I: { URI: F } & I
+): (I extends Chain<F>
+  ? PipeableChain<F>
+  : I extends Apply<F>
+  ? PipeableApply<F>
+  : I extends Functor<F>
+  ? PipeableFunctor<F>
+  : {}) &
+  (I extends FunctorWithIndex<F, infer Ix> ? PipeableFunctorWithIndex<F, Ix> : {}) &
+  (I extends Bifunctor<F> ? PipeableBifunctor<F> : {}) &
+  (I extends Extend<F> ? PipeableExtend<F> : {}) &
+  (I extends FoldableWithIndex<F, infer Ix>
+    ? PipeableFoldableWithIndex<F, Ix>
+    : I extends Foldable<F>
+    ? PipeableFoldable<F>
+    : {}) &
+  (I extends Alt<F> ? PipeableAlt<F> : {}) &
+  (I extends FilterableWithIndex<F, infer Ix>
+    ? PipeableFilterableWithIndex<F, Ix>
+    : I extends Filterable<F>
+    ? PipeableFilterable<F>
+    : I extends Compactable<F>
+    ? PipeableCompactable<F>
+    : {}) &
+  (I extends Profunctor<F> ? PipeableProfunctor<F> : {}) &
+  (I extends Semigroupoid<F> ? PipeableSemigroupoid<F> : {}) { ... }
+```
+
+Added in v2.0.0
diff --git a/src/Chain.ts b/src/Chain.ts
index 68a0134b..a2338044 100644
--- a/src/Chain.ts
+++ b/src/Chain.ts
@@ -52,21 +52,3 @@ export interface Chain3<F extends URIS3> extends Apply3<F> {
 export interface Chain4<F extends URIS4> extends Apply4<F> {
   readonly chain: <X, U, L, A, B>(fa: Type4<F, X, U, L, A>, f: (a: A) => Type4<F, X, U, L, B>) => Type4<F, X, U, L, B>
 }
-
-/**
- * @since 2.0.0
- */
-export function flatMap<F extends URIS3>(
-  F: Chain3<F>
-): <U, L, A, B>(f: (a: A) => Type3<F, U, L, B>) => (fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
-export function flatMap<F extends URIS2>(
-  F: Chain2<F>
-): <L, A, B>(f: (a: A) => Type2<F, L, B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
-export function flatMap<F extends URIS2, L>(
-  F: Chain2C<F, L>
-): <A, B>(f: (a: A) => Type2<F, L, B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
-export function flatMap<F extends URIS>(F: Chain1<F>): <A, B>(f: (a: A) => Type<F, B>) => (fa: Type<F, A>) => Type<F, B>
-export function flatMap<F>(F: Chain<F>): <A, B>(f: (a: A) => HKT<F, B>) => (fa: HKT<F, A>) => HKT<F, B>
-export function flatMap<F>(F: Chain<F>): <A, B>(f: (a: A) => HKT<F, B>) => (fa: HKT<F, A>) => HKT<F, B> {
-  return f => fa => F.chain(fa, f)
-}
diff --git a/src/Functor.ts b/src/Functor.ts
index d3f04a45..09a7e1c8 100644
--- a/src/Functor.ts
+++ b/src/Functor.ts
@@ -167,21 +167,3 @@ export function getFunctorComposition<F, G>(F: Functor<F>, G: Functor<G>): Funct
     map: (fa, f) => F.map(fa, ga => G.map(ga, f))
   }
 }
-
-/**
- * @since 2.0.0
- */
-export function lift<F extends URIS3>(
-  F: Functor3<F>
-): <A, B>(f: (a: A) => B) => <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
-export function lift<F extends URIS2>(
-  F: Functor2<F>
-): <A, B>(f: (a: A) => B) => <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
-export function lift<F extends URIS2, L>(
-  F: Functor2C<F, L>
-): <A, B>(f: (a: A) => B) => (fa: Type2<F, L, A>) => Type2<F, L, B>
-export function lift<F extends URIS>(F: Functor1<F>): <A, B>(f: (a: A) => B) => (fa: Type<F, A>) => Type<F, B>
-export function lift<F>(F: Functor<F>): <A, B>(f: (a: A) => B) => (fa: HKT<F, A>) => HKT<F, B>
-export function lift<F>(F: Functor<F>): <A, B>(f: (a: A) => B) => (fa: HKT<F, A>) => HKT<F, B> {
-  return f => fa => F.map(fa, f)
-}
diff --git a/src/index.ts b/src/index.ts
index 86a5a6aa..f33ae50b 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -116,6 +116,8 @@ import * as ord from './Ord'
 export { ord }
 import * as ordering from './Ordering'
 export { ordering }
+import * as pipeable from './pipeable'
+export { pipeable }
 import * as plus from './Plus'
 export { plus }
 import * as profunctor from './Profunctor'
diff --git a/src/pipeable.ts b/src/pipeable.ts
new file mode 100644
index 00000000..2de37eac
--- /dev/null
+++ b/src/pipeable.ts
@@ -0,0 +1,749 @@
+import { Alt, Alt1, Alt2, Alt2C, Alt3 } from './Alt'
+import { Apply, Apply1, Apply2, Apply2C, Apply3 } from './Apply'
+import { Bifunctor, Bifunctor2, Bifunctor3 } from './Bifunctor'
+import { Chain, Chain1, Chain2, Chain2C, Chain3 } from './Chain'
+import { Compactable, Compactable1, Compactable2, Compactable2C, Compactable3, Separated } from './Compactable'
+import { Either } from './Either'
+import { Extend, Extend1, Extend2, Extend2C, Extend3 } from './Extend'
+import { Filterable, Filterable1, Filterable2, Filterable2C, Filterable3 } from './Filterable'
+import {
+  FilterableWithIndex,
+  FilterableWithIndex1,
+  FilterableWithIndex2,
+  FilterableWithIndex2C,
+  FilterableWithIndex3,
+  PredicateWithIndex,
+  RefinementWithIndex
+} from './FilterableWithIndex'
+import { Foldable, Foldable1, Foldable2, Foldable2C, Foldable3 } from './Foldable'
+import {
+  FoldableWithIndex,
+  FoldableWithIndex1,
+  FoldableWithIndex2,
+  FoldableWithIndex2C,
+  FoldableWithIndex3
+} from './FoldableWithIndex'
+import { identity, Predicate, Refinement, pipe as p } from './function'
+import { Functor, Functor1, Functor2, Functor2C, Functor3 } from './Functor'
+import {
+  FunctorWithIndex,
+  FunctorWithIndex1,
+  FunctorWithIndex2,
+  FunctorWithIndex2C,
+  FunctorWithIndex3
+} from './FunctorWithIndex'
+import { HKT, HKT2, Type, Type2, Type3, URIS, URIS2, URIS3 } from './HKT'
+import { Monoid } from './Monoid'
+import { Option } from './Option'
+import { Profunctor, Profunctor2, Profunctor2C, Profunctor3 } from './Profunctor'
+import { Semigroupoid, Semigroupoid2, Semigroupoid2C, Semigroupoid3 } from './Semigroupoid'
+
+/**
+ * @since 2.0.0
+ */
+export function apply<A, B>(a: A, f: (a: A) => B): B {
+  return f(a)
+}
+
+/**
+ * A re-export of `function`'s `pipe`
+ * @since 2.0.0
+ */
+export const pipe = p
+
+export interface PipeableFunctor<F> {
+  readonly map: <A, B>(f: (a: A) => B) => (fa: HKT<F, A>) => HKT<F, B>
+}
+
+export interface PipeableFunctor1<F extends URIS> {
+  readonly map: <A, B>(f: (a: A) => B) => (fa: Type<F, A>) => Type<F, B>
+}
+
+export interface PipeableFunctor2<F extends URIS2> {
+  readonly map: <A, B>(f: (a: A) => B) => <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+}
+
+export interface PipeableFunctor2C<F extends URIS2, L> {
+  readonly map: <A, B>(f: (a: A) => B) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+}
+
+export interface PipeableFunctor3<F extends URIS3> {
+  readonly map: <A, B>(f: (a: A) => B) => <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+}
+
+export interface PipeableFunctorWithIndex<F, I> extends PipeableFunctor<F> {
+  readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => (fa: HKT<F, A>) => HKT<F, B>
+}
+
+export interface PipeableFunctorWithIndex1<F extends URIS, I> extends PipeableFunctor1<F> {
+  readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => (fa: Type<F, A>) => Type<F, B>
+}
+
+export interface PipeableFunctorWithIndex2<F extends URIS2, I> extends PipeableFunctor2<F> {
+  readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+}
+
+export interface PipeableFunctorWithIndex2C<F extends URIS2, I, L> extends PipeableFunctor2C<F, L> {
+  readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+}
+
+export interface PipeableFunctorWithIndex3<F extends URIS3, I> extends PipeableFunctor3<F> {
+  readonly mapWithIndex: <A, B>(f: (i: I, a: A) => B) => <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+}
+
+export interface PipeableApply<F> extends PipeableFunctor<F> {
+  readonly ap: <A, B>(fab: HKT<F, (a: A) => B>) => (fa: HKT<F, A>) => HKT<F, B>
+  readonly apFirst: <B>(fb: HKT<F, B>) => <A>(fa: HKT<F, A>) => HKT<F, A>
+  readonly apSecond: <B>(fb: HKT<F, B>) => <A>(fa: HKT<F, A>) => HKT<F, B>
+}
+
+export interface PipeableApply1<F extends URIS> extends PipeableFunctor1<F> {
+  readonly ap: <A, B>(fab: Type<F, (a: A) => B>) => (fa: Type<F, A>) => Type<F, B>
+  readonly apFirst: <B>(fb: Type<F, B>) => <A>(fa: Type<F, A>) => Type<F, A>
+  readonly apSecond: <B>(fb: Type<F, B>) => <A>(fa: Type<F, A>) => Type<F, B>
+}
+
+export interface PipeableApply2<F extends URIS2> extends PipeableFunctor2<F> {
+  readonly ap: <L, A, B>(fab: Type2<F, L, (a: A) => B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly apFirst: <L, B>(fb: Type2<F, L, B>) => <A>(fa: Type2<F, L, A>) => Type2<F, L, A>
+  readonly apSecond: <L, B>(fb: Type2<F, L, B>) => <A>(fa: Type2<F, L, A>) => Type2<F, L, B>
+}
+
+export interface PipeableApply2C<F extends URIS2, L> extends PipeableFunctor2C<F, L> {
+  readonly ap: <A, B>(fab: Type2<F, L, (a: A) => B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly apFirst: <A>(fb: Type2<F, L, A>) => <B>(fb: Type2<F, L, B>) => Type2<F, L, A>
+  readonly apSecond: <A>(fb: Type2<F, L, A>) => <B>(fb: Type2<F, L, B>) => Type2<F, L, B>
+}
+
+export interface PipeableApply3<F extends URIS3> extends PipeableFunctor3<F> {
+  readonly ap: <U, L, A, B>(fab: Type3<F, U, L, (a: A) => B>) => (fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+  readonly apFirst: <U, L, B>(fb: Type3<F, U, L, B>) => <A>(fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+  readonly apSecond: <U, L, B>(fb: Type3<F, U, L, B>) => <A>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+}
+
+export interface PipeableChain<F> extends PipeableApply<F> {
+  readonly chain: <A, B>(f: (a: A) => HKT<F, B>) => (ma: HKT<F, A>) => HKT<F, B>
+  readonly flatten: <A>(mma: HKT<F, HKT<F, A>>) => HKT<F, A>
+}
+
+export interface PipeableChain1<F extends URIS> extends PipeableApply1<F> {
+  readonly chain: <A, B>(f: (a: A) => Type<F, B>) => (ma: Type<F, A>) => Type<F, B>
+  readonly flatten: <A>(mma: Type<F, Type<F, A>>) => Type<F, A>
+}
+
+export interface PipeableChain2<F extends URIS2> extends PipeableApply2<F> {
+  readonly chain: <L, A, B>(f: (a: A) => Type2<F, L, B>) => (ma: Type2<F, L, A>) => Type2<F, L, B>
+  readonly flatten: <L, A>(mma: Type2<F, L, Type2<F, L, A>>) => Type2<F, L, A>
+}
+
+export interface PipeableChain2C<F extends URIS2, L> extends PipeableApply2C<F, L> {
+  readonly chain: <A, B>(f: (a: A) => Type2<F, L, B>) => (ma: Type2<F, L, A>) => Type2<F, L, B>
+  readonly flatten: <A>(mma: Type2<F, L, Type2<F, L, A>>) => Type2<F, L, A>
+}
+
+export interface PipeableChain3<F extends URIS3> extends PipeableApply3<F> {
+  readonly chain: <U, L, A, B>(f: (a: A) => Type3<F, U, L, B>) => (ma: Type3<F, U, L, A>) => Type3<F, U, L, B>
+  readonly flatten: <U, L, A>(mma: Type3<F, U, L, Type3<F, U, L, A>>) => Type3<F, U, L, A>
+}
+
+export interface PipeableExtend<F> extends PipeableFunctor<F> {
+  readonly extend: <A, B>(f: (fa: HKT<F, A>) => B) => (ma: HKT<F, A>) => HKT<F, B>
+  readonly duplicate: <A>(ma: HKT<F, A>) => HKT<F, HKT<F, A>>
+}
+
+export interface PipeableExtend1<F extends URIS> extends PipeableFunctor1<F> {
+  readonly extend: <A, B>(f: (fa: Type<F, A>) => B) => (ma: Type<F, A>) => Type<F, B>
+  readonly duplicate: <A>(ma: Type<F, A>) => Type<F, Type<F, A>>
+}
+
+export interface PipeableExtend2<F extends URIS2> extends PipeableFunctor2<F> {
+  readonly extend: <L, A, B>(f: (fa: Type2<F, L, A>) => B) => (ma: Type2<F, L, A>) => Type2<F, L, B>
+  readonly duplicate: <L, A>(ma: Type2<F, L, A>) => Type2<F, L, Type2<F, L, A>>
+}
+
+export interface PipeableExtend2C<F extends URIS2, L> extends PipeableFunctor2C<F, L> {
+  readonly extend: <A, B>(f: (fa: Type2<F, L, A>) => B) => (ma: Type2<F, L, A>) => Type2<F, L, B>
+  readonly duplicate: <A>(ma: Type2<F, L, A>) => Type2<F, L, Type2<F, L, A>>
+}
+
+export interface PipeableExtend3<F extends URIS3> extends PipeableFunctor3<F> {
+  readonly extend: <U, L, A, B>(f: (fa: Type3<F, U, L, A>) => B) => (ma: Type3<F, U, L, A>) => Type3<F, U, L, B>
+  readonly duplicate: <U, L, A>(ma: Type3<F, U, L, A>) => Type3<F, U, L, Type3<F, U, L, A>>
+}
+
+export interface PipeableBifunctor<F> {
+  readonly bimap: <L, A, M, B>(f: (l: L) => M, g: (a: A) => B) => (fa: HKT2<F, L, A>) => HKT2<F, M, B>
+  readonly mapLeft: <L, A, M>(f: (l: L) => M) => (fa: HKT2<F, L, A>) => HKT2<F, M, A>
+}
+
+export interface PipeableBifunctor2<F extends URIS2> {
+  readonly bimap: <L, A, M, B>(f: (l: L) => M, g: (a: A) => B) => (fa: Type2<F, L, A>) => Type2<F, M, B>
+  readonly mapLeft: <L, A, M>(f: (l: L) => M) => (fa: Type2<F, L, A>) => Type2<F, M, A>
+}
+
+export interface PipeableBifunctor3<F extends URIS3> {
+  readonly bimap: <L, A, M, B>(f: (l: L) => M, g: (a: A) => B) => <U>(fa: Type3<F, U, L, A>) => Type3<F, U, M, B>
+  readonly mapLeft: <L, A, M>(f: (l: L) => M) => <U>(fa: Type3<F, U, L, A>) => Type3<F, U, M, A>
+}
+
+export interface PipeableFoldable<F> {
+  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => (fa: HKT<F, A>) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => (fa: HKT<F, A>) => M
+  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => (fa: HKT<F, A>) => B
+}
+
+export interface PipeableFoldable1<F extends URIS> {
+  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => (fa: Type<F, A>) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => (fa: Type<F, A>) => M
+  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => (fa: Type<F, A>) => B
+}
+
+export interface PipeableFoldable2<F extends URIS2> {
+  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => <L>(fa: Type2<F, L, A>) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => <L>(fa: Type2<F, L, A>) => M
+  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => <L>(fa: Type2<F, L, A>) => B
+}
+
+export interface PipeableFoldable2C<F extends URIS2, L> {
+  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => (fa: Type2<F, L, A>) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => (fa: Type2<F, L, A>) => M
+  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => (fa: Type2<F, L, A>) => B
+}
+
+export interface PipeableFoldable3<F extends URIS3> {
+  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => <U, L>(fa: Type3<F, U, L, A>) => B
+  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => <U, L>(fa: Type3<F, U, L, A>) => M
+  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => <U, L>(fa: Type3<F, U, L, A>) => B
+}
+
+export interface PipeableFoldableWithIndex<F, I> extends PipeableFoldable<F> {
+  readonly reduceWithIndex: <A, B>(b: B, f: (i: I, b: B, a: A) => B) => (fa: HKT<F, A>) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <A>(f: (i: I, a: A) => M) => (fa: HKT<F, A>) => M
+  readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => (fa: HKT<F, A>) => B
+}
+
+export interface PipeableFoldableWithIndex1<F extends URIS, I> extends PipeableFoldable1<F> {
+  readonly reduceWithIndex: <A, B>(b: B, f: (i: I, b: B, a: A) => B) => (fa: Type<F, A>) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <A>(f: (i: I, a: A) => M) => (fa: Type<F, A>) => M
+  readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => (fa: Type<F, A>) => B
+}
+
+export interface PipeableFoldableWithIndex2<F extends URIS2, I> extends PipeableFoldable2<F> {
+  readonly reduceWithIndex: <A, B>(b: B, f: (i: I, b: B, a: A) => B) => <L>(fa: Type2<F, L, A>) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <A>(f: (i: I, a: A) => M) => <L>(fa: Type2<F, L, A>) => M
+  readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => <L>(fa: Type2<F, L, A>) => B
+}
+
+export interface PipeableFoldableWithIndex2C<F extends URIS2, I, L> extends PipeableFoldable2C<F, L> {
+  readonly reduceWithIndex: <A, B>(b: B, f: (i: I, b: B, a: A) => B) => (fa: Type2<F, L, A>) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <A>(f: (i: I, a: A) => M) => (fa: Type2<F, L, A>) => M
+  readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => (fa: Type2<F, L, A>) => B
+}
+
+export interface PipeableFoldableWithIndex3<F extends URIS3, I> extends PipeableFoldable3<F> {
+  readonly reduceWithIndex: <A, B>(b: B, f: (i: I, b: B, a: A) => B) => <U, L>(fa: Type3<F, U, L, A>) => B
+  readonly foldMapWithIndex: <M>(M: Monoid<M>) => <A>(f: (i: I, a: A) => M) => <U, L>(fa: Type3<F, U, L, A>) => M
+  readonly reduceRightWithIndex: <A, B>(b: B, f: (i: I, a: A, b: B) => B) => <U, L>(fa: Type3<F, U, L, A>) => B
+}
+
+export interface PipeableAlt<F> {
+  readonly alt: <A>(that: () => HKT<F, A>) => (fa: HKT<F, A>) => HKT<F, A>
+}
+
+export interface PipeableAlt1<F extends URIS> {
+  readonly alt: <A>(that: () => Type<F, A>) => (fa: Type<F, A>) => Type<F, A>
+}
+
+export interface PipeableAlt2<F extends URIS2> {
+  readonly alt: <L, A>(that: () => Type2<F, L, A>) => (fa: Type2<F, L, A>) => Type2<F, L, A>
+}
+
+export interface PipeableAlt2C<F extends URIS2, L> {
+  readonly alt: <A>(that: () => Type2<F, L, A>) => (fa: Type2<F, L, A>) => Type2<F, L, A>
+}
+
+export interface PipeableAlt3<F extends URIS3> {
+  readonly alt: <U, L, A>(that: () => Type3<F, U, L, A>) => (fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+}
+
+export interface PipeableCompactable<F> {
+  readonly compact: <A>(fa: HKT<F, Option<A>>) => HKT<F, A>
+  readonly separate: <A, B>(fa: HKT<F, Either<A, B>>) => Separated<HKT<F, A>, HKT<F, B>>
+}
+
+export interface PipeableCompactable1<F extends URIS> {
+  readonly compact: <A>(fa: Type<F, Option<A>>) => Type<F, A>
+  readonly separate: <A, B>(fa: Type<F, Either<A, B>>) => Separated<Type<F, A>, Type<F, B>>
+}
+
+export interface PipeableCompactable2<F extends URIS2> {
+  readonly compact: <L, A>(fa: Type2<F, L, Option<A>>) => Type2<F, L, A>
+  readonly separate: <L, A, B>(fa: Type2<F, L, Either<A, B>>) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+}
+
+export interface PipeableCompactable2C<F extends URIS2, L> {
+  readonly compact: <A>(fa: Type2<F, L, Option<A>>) => Type2<F, L, A>
+  readonly separate: <A, B>(fa: Type2<F, L, Either<A, B>>) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+}
+
+export interface PipeableCompactable3<F extends URIS3> {
+  readonly compact: <U, L, A>(fa: Type3<F, U, L, Option<A>>) => Type3<F, U, L, A>
+  readonly separate: <U, L, A, B>(fa: Type3<F, U, L, Either<A, B>>) => Separated<Type3<F, U, L, A>, Type3<F, U, L, B>>
+}
+
+export interface PipeableFilterable<F> extends PipeableCompactable<F> {
+  readonly filter: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: HKT<F, A>) => HKT<F, B>
+    <A>(predicate: Predicate<A>): (fa: HKT<F, A>) => HKT<F, A>
+  }
+  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => (fa: HKT<F, A>) => HKT<F, B>
+  readonly partition: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: HKT<F, A>) => Separated<HKT<F, A>, HKT<F, B>>
+    <A>(predicate: Predicate<A>): (fa: HKT<F, A>) => Separated<HKT<F, A>, HKT<F, A>>
+  }
+  readonly partitionMap: <A, RL, RR>(
+    f: (a: A) => Either<RL, RR>
+  ) => (fa: HKT<F, A>) => Separated<HKT<F, RL>, HKT<F, RR>>
+}
+
+export interface PipeableFilterable1<F extends URIS> extends PipeableCompactable1<F> {
+  readonly filter: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: Type<F, A>) => Type<F, B>
+    <A>(predicate: Predicate<A>): (fa: Type<F, A>) => Type<F, A>
+  }
+  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => (fa: Type<F, A>) => Type<F, B>
+  readonly partition: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: Type<F, A>) => Separated<Type<F, A>, Type<F, B>>
+    <A>(predicate: Predicate<A>): (fa: Type<F, A>) => Separated<Type<F, A>, Type<F, A>>
+  }
+  readonly partitionMap: <A, RL, RR>(
+    f: (a: A) => Either<RL, RR>
+  ) => (fa: Type<F, A>) => Separated<Type<F, RL>, Type<F, RR>>
+}
+
+export interface PipeableFilterable2<F extends URIS2> extends PipeableCompactable2<F> {
+  readonly filter: {
+    <A, B extends A>(refinement: Refinement<A, B>): <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+    <A>(predicate: Predicate<A>): <L>(fa: Type2<F, L, A>) => Type2<F, L, A>
+  }
+  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly partition: {
+    <A, B extends A>(refinement: Refinement<A, B>): <L>(fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+    <A>(predicate: Predicate<A>): <L>(fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, A>>
+  }
+  readonly partitionMap: <A, RL, RR>(
+    f: (a: A) => Either<RL, RR>
+  ) => <L>(fa: Type2<F, L, A>) => Separated<Type2<F, L, RL>, Type2<F, L, RR>>
+}
+
+export interface PipeableFilterable2C<F extends URIS2, L> extends PipeableCompactable2C<F, L> {
+  readonly filter: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: Type2<F, L, A>) => Type2<F, L, B>
+    <A>(predicate: Predicate<A>): (fa: Type2<F, L, A>) => Type2<F, L, A>
+  }
+  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly partition: {
+    <A, B extends A>(refinement: Refinement<A, B>): (fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+    <A>(predicate: Predicate<A>): (fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, A>>
+  }
+  readonly partitionMap: <A, RL, RR>(
+    f: (a: A) => Either<RL, RR>
+  ) => (fa: Type2<F, L, A>) => Separated<Type2<F, L, RL>, Type2<F, L, RR>>
+}
+
+export interface PipeableFilterable3<F extends URIS3> extends PipeableCompactable3<F> {
+  readonly filter: {
+    <A, B extends A>(refinement: Refinement<A, B>): <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+    <A>(predicate: Predicate<A>): <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+  }
+  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+  readonly partition: {
+    <A, B extends A>(refinement: Refinement<A, B>): <U, L>(
+      fa: Type3<F, U, L, A>
+    ) => Separated<Type3<F, U, L, A>, Type3<F, U, L, B>>
+    <A>(predicate: Predicate<A>): <U, L>(fa: Type3<F, U, L, A>) => Separated<Type3<F, U, L, A>, Type3<F, U, L, A>>
+  }
+  readonly partitionMap: <A, RL, RR>(
+    f: (a: A) => Either<RL, RR>
+  ) => <U, L>(fa: Type3<F, U, L, A>) => Separated<Type3<F, U, L, RL>, Type3<F, U, L, RR>>
+}
+
+export interface PipeableFilterableWithIndex<F, I> extends PipeableFilterable<F> {
+  readonly filterWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (fa: HKT<F, A>) => HKT<F, B>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: HKT<F, A>) => HKT<F, A>
+  }
+  readonly filterMapWithIndex: <A, B>(f: (i: I, a: A) => Option<B>) => (fa: HKT<F, A>) => HKT<F, B>
+  readonly partitionWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (fa: HKT<F, A>) => Separated<HKT<F, A>, HKT<F, B>>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: HKT<F, A>) => Separated<HKT<F, A>, HKT<F, A>>
+  }
+  readonly partitionMapWithIndex: <A, RL, RR>(
+    f: (i: I, a: A) => Either<RL, RR>
+  ) => (fa: HKT<F, A>) => Separated<HKT<F, RL>, HKT<F, RR>>
+}
+
+export interface PipeableFilterableWithIndex1<F extends URIS, I> extends PipeableFilterable1<F> {
+  readonly filterWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (fa: Type<F, A>) => Type<F, B>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: Type<F, A>) => Type<F, A>
+  }
+  readonly filterMapWithIndex: <A, B>(f: (i: I, a: A) => Option<B>) => (fa: Type<F, A>) => Type<F, B>
+  readonly partitionWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (fa: Type<F, A>) => Separated<Type<F, A>, Type<F, B>>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: Type<F, A>) => Separated<Type<F, A>, Type<F, A>>
+  }
+  readonly partitionMapWithIndex: <A, RL, RR>(
+    f: (i: I, a: A) => Either<RL, RR>
+  ) => (fa: Type<F, A>) => Separated<Type<F, RL>, Type<F, RR>>
+}
+
+export interface PipeableFilterableWithIndex2<F extends URIS2, I> extends PipeableFilterable2<F> {
+  readonly filterWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+    <A>(predicate: PredicateWithIndex<I, A>): <L>(fa: Type2<F, L, A>) => Type2<F, L, A>
+  }
+  readonly filterMapWithIndex: <A, B>(f: (i: I, a: A) => Option<B>) => <L>(fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly partitionWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): <L>(
+      fa: Type2<F, L, A>
+    ) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+    <A>(predicate: PredicateWithIndex<I, A>): <L>(fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, A>>
+  }
+  readonly partitionMapWithIndex: <A, RL, RR>(
+    f: (i: I, a: A) => Either<RL, RR>
+  ) => <L>(fa: Type2<F, L, A>) => Separated<Type2<F, L, RL>, Type2<F, L, RR>>
+}
+
+export interface PipeableFilterableWithIndex2C<F extends URIS2, I, L> extends PipeableFilterable2C<F, L> {
+  readonly filterWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (fa: Type2<F, L, A>) => Type2<F, L, B>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: Type2<F, L, A>) => Type2<F, L, A>
+  }
+  readonly filterMapWithIndex: <A, B>(f: (i: I, a: A) => Option<B>) => (fa: Type2<F, L, A>) => Type2<F, L, B>
+  readonly partitionWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): (
+      fa: Type2<F, L, A>
+    ) => Separated<Type2<F, L, A>, Type2<F, L, B>>
+    <A>(predicate: PredicateWithIndex<I, A>): (fa: Type2<F, L, A>) => Separated<Type2<F, L, A>, Type2<F, L, A>>
+  }
+  readonly partitionMapWithIndex: <A, RL, RR>(
+    f: (i: I, a: A) => Either<RL, RR>
+  ) => (fa: Type2<F, L, A>) => Separated<Type2<F, L, RL>, Type2<F, L, RR>>
+}
+
+export interface PipeableFilterableWithIndex3<F extends URIS3, I> extends PipeableFilterable3<F> {
+  readonly filterWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, B>
+    <A>(predicate: PredicateWithIndex<I, A>): <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+  }
+  readonly filterMapWithIndex: <A, B>(
+    f: (i: I, a: A) => Option<B>
+  ) => <U, L>(fa: Type3<F, U, L, A>) => Type3<F, U, L, A>
+  readonly partitionWithIndex: {
+    <A, B extends A>(refinement: RefinementWithIndex<I, A, B>): <U, L>(
+      fa: Type3<F, U, L, A>
+    ) => Separated<Type3<F, U, L, A>, Type3<F, U, L, B>>
+    <A>(predicate: PredicateWithIndex<I, A>): <U, L>(
+      fa: Type3<F, U, L, A>
+    ) => Separated<Type3<F, U, L, A>, Type3<F, U, L, A>>
+  }
+  readonly partitionMapWithIndex: <A, RL, RR>(
+    f: (i: I, a: A) => Either<RL, RR>
+  ) => <U, L>(fa: Type3<F, U, L, A>) => Separated<Type3<F, U, L, RL>, Type3<F, U, L, RR>>
+}
+
+export interface PipeableProfunctor<F> {
+  readonly map: <L, A, B>(f: (a: A) => B) => (fa: HKT2<F, L, A>) => HKT2<F, L, B>
+  readonly promap: <A, B, C, D>(f: (a: A) => B, g: (c: C) => D) => (fbc: HKT2<F, B, C>) => HKT2<F, A, D>
+}
+
+export interface PipeableProfunctor2<F extends URIS2> extends PipeableFunctor2<F> {
+  readonly promap: <A, B, C, D>(f: (a: A) => B, g: (c: C) => D) => (fbc: Type2<F, B, C>) => Type2<F, A, D>
+}
+
+export interface PipeableProfunctor2C<F extends URIS2, L> extends PipeableFunctor2C<F, L> {
+  readonly promap: <A, C, D>(f: (a: A) => L, g: (c: C) => D) => (flc: Type2<F, L, C>) => Type2<F, A, D>
+}
+
+export interface PipeableProfunctor3<F extends URIS3> extends PipeableFunctor3<F> {
+  readonly promap: <U, A, B, C, D>(f: (a: A) => B, g: (c: C) => D) => (fbc: Type3<F, U, B, C>) => Type3<F, U, A, D>
+}
+
+export interface PipeableSemigroupoid<F> {
+  readonly compose: <L, A>(la: HKT2<F, L, A>) => <B>(ab: HKT2<F, A, B>) => HKT2<F, L, B>
+}
+
+export interface PipeableSemigroupoid2<F extends URIS2> {
+  readonly compose: <L, A>(la: Type2<F, L, A>) => <B>(ab: Type2<F, A, B>) => Type2<F, L, B>
+}
+
+export interface PipeableSemigroupoid2C<F extends URIS2, L> {
+  readonly compose: <A>(la: Type2<F, L, A>) => <B>(ab: Type2<F, A, B>) => Type2<F, L, B>
+}
+
+export interface PipeableSemigroupoid3<F extends URIS3> {
+  readonly compose: <U, L, A>(la: Type3<F, U, L, A>) => <B>(ab: Type3<F, U, A, B>) => Type3<F, U, L, B>
+}
+
+const isFunctor = <F>(I: any): I is Functor<F> => typeof I.map === 'function'
+const isFunctorWithIndex = <F>(I: any): I is FunctorWithIndex<F, unknown> => typeof I.mapWithIndex === 'function'
+const isApply = <F>(I: any): I is Apply<F> => typeof I.ap === 'function'
+const isChain = <F>(I: any): I is Chain<F> => typeof I.chain === 'function'
+const isBifunctor = <F>(I: any): I is Bifunctor<F> => typeof I.bimap === 'function'
+const isExtend = <F>(I: any): I is Extend<F> => typeof I.extend === 'function'
+const isFoldable = <F>(I: any): I is Foldable<F> => typeof I.reduce === 'function'
+const isFoldableWithIndex = <F>(I: any): I is FoldableWithIndex<F, unknown> => typeof I.reduceWithIndex === 'function'
+const isAlt = <F>(I: any): I is Alt<F> => typeof I.alt === 'function'
+const isCompactable = <F>(I: any): I is Compactable<F> => typeof I.compact === 'function'
+const isFilterable = <F>(I: any): I is Filterable<F> => typeof I.filter === 'function'
+const isFilterableWithIndex = <F>(I: any): I is FilterableWithIndex<F, unknown> =>
+  typeof I.filterWithIndex === 'function'
+const isProfunctor = <F>(I: any): I is Profunctor<F> => typeof I.promap === 'function'
+const isSemigroupoid = <F>(I: any): I is Semigroupoid<F> => typeof I.compose === 'function'
+
+/**
+ * @since 2.0.0
+ */
+export function pipeable<F extends URIS3, I>(
+  I: { URI: F } & I
+): (I extends Chain3<F>
+  ? PipeableChain3<F>
+  : I extends Apply3<F>
+  ? PipeableApply3<F>
+  : I extends Functor3<F>
+  ? PipeableFunctor3<F>
+  : {}) &
+  (I extends FunctorWithIndex3<F, infer Ix> ? PipeableFunctorWithIndex3<F, Ix> : {}) &
+  (I extends Bifunctor3<F> ? PipeableBifunctor3<F> : {}) &
+  (I extends Extend3<F> ? PipeableExtend3<F> : {}) &
+  (I extends FoldableWithIndex3<F, infer Ix>
+    ? PipeableFoldableWithIndex3<F, Ix>
+    : I extends Foldable3<F>
+    ? PipeableFoldable3<F>
+    : {}) &
+  (I extends Alt3<F> ? PipeableAlt3<F> : {}) &
+  (I extends FilterableWithIndex3<F, infer Ix>
+    ? PipeableFilterableWithIndex3<F, Ix>
+    : I extends Filterable3<F>
+    ? PipeableFilterable3<F>
+    : I extends Compactable3<F>
+    ? PipeableCompactable3<F>
+    : {}) &
+  (I extends Profunctor3<F> ? PipeableProfunctor3<F> : {}) &
+  (I extends Semigroupoid3<F> ? PipeableSemigroupoid3<F> : {})
+export function pipeable<F extends URIS2, I, L>(
+  I: { URI: F; _L: L } & I
+): (I extends Chain2C<F, L>
+  ? PipeableChain2C<F, L>
+  : I extends Apply2C<F, L>
+  ? PipeableApply2C<F, L>
+  : I extends Functor2C<F, L>
+  ? PipeableFunctor2C<F, L>
+  : {}) &
+  (I extends FunctorWithIndex2C<F, infer Ix, L> ? PipeableFunctorWithIndex2C<F, Ix, L> : {}) &
+  (I extends Extend2C<F, L> ? PipeableExtend2C<F, L> : {}) &
+  (I extends FoldableWithIndex2C<F, infer Ix, L>
+    ? PipeableFoldableWithIndex2C<F, Ix, L>
+    : I extends Foldable2C<F, L>
+    ? PipeableFoldable2C<F, L>
+    : {}) &
+  (I extends Alt2C<F, L> ? PipeableAlt2C<F, L> : {}) &
+  (I extends FilterableWithIndex2C<F, infer Ix, L>
+    ? PipeableFilterableWithIndex2C<F, Ix, L>
+    : I extends Filterable2C<F, L>
+    ? PipeableFilterable2C<F, L>
+    : I extends Compactable2C<F, L>
+    ? PipeableCompactable2C<F, L>
+    : {}) &
+  (I extends Profunctor2C<F, L> ? PipeableProfunctor2C<F, L> : {}) &
+  (I extends Semigroupoid2C<F, L> ? PipeableSemigroupoid2C<F, L> : {})
+export function pipeable<F extends URIS2, I>(
+  I: { URI: F } & I
+): (I extends Chain2<F>
+  ? PipeableChain2<F>
+  : I extends Apply2<F>
+  ? PipeableApply2<F>
+  : I extends Functor2<F>
+  ? PipeableFunctor2<F>
+  : {}) &
+  (I extends FunctorWithIndex2<F, infer Ix> ? PipeableFunctorWithIndex2<F, Ix> : {}) &
+  (I extends Bifunctor2<F> ? PipeableBifunctor2<F> : {}) &
+  (I extends Extend2<F> ? PipeableExtend2<F> : {}) &
+  (I extends FoldableWithIndex2<F, infer Ix>
+    ? PipeableFoldableWithIndex2<F, Ix>
+    : I extends Foldable2<F>
+    ? PipeableFoldable2<F>
+    : {}) &
+  (I extends Alt2<F> ? PipeableAlt2<F> : {}) &
+  (I extends FilterableWithIndex2<F, infer Ix>
+    ? PipeableFilterableWithIndex2<F, Ix>
+    : I extends Filterable2<F>
+    ? PipeableFilterable2<F>
+    : I extends Compactable2<F>
+    ? PipeableCompactable2<F>
+    : {}) &
+  (I extends Profunctor2<F> ? PipeableProfunctor2<F> : {}) &
+  (I extends Semigroupoid2<F> ? PipeableSemigroupoid2<F> : {})
+export function pipeable<F extends URIS, I>(
+  I: { URI: F } & I
+): (I extends Chain1<F>
+  ? PipeableChain1<F>
+  : I extends Apply1<F>
+  ? PipeableApply1<F>
+  : I extends Functor1<F>
+  ? PipeableFunctor1<F>
+  : {}) &
+  (I extends FunctorWithIndex1<F, infer Ix> ? PipeableFunctorWithIndex1<F, Ix> : {}) &
+  (I extends Extend1<F> ? PipeableExtend1<F> : {}) &
+  (I extends FoldableWithIndex1<F, infer Ix>
+    ? PipeableFoldableWithIndex1<F, Ix>
+    : I extends Foldable1<F>
+    ? PipeableFoldable1<F>
+    : {}) &
+  (I extends Alt1<F> ? PipeableAlt1<F> : {}) &
+  (I extends FilterableWithIndex1<F, infer Ix>
+    ? PipeableFilterableWithIndex1<F, Ix>
+    : I extends Filterable1<F>
+    ? PipeableFilterable1<F>
+    : I extends Compactable1<F>
+    ? PipeableCompactable1<F>
+    : {})
+export function pipeable<F, I>(
+  I: { URI: F } & I
+): (I extends Chain<F>
+  ? PipeableChain<F>
+  : I extends Apply<F>
+  ? PipeableApply<F>
+  : I extends Functor<F>
+  ? PipeableFunctor<F>
+  : {}) &
+  (I extends FunctorWithIndex<F, infer Ix> ? PipeableFunctorWithIndex<F, Ix> : {}) &
+  (I extends Bifunctor<F> ? PipeableBifunctor<F> : {}) &
+  (I extends Extend<F> ? PipeableExtend<F> : {}) &
+  (I extends FoldableWithIndex<F, infer Ix>
+    ? PipeableFoldableWithIndex<F, Ix>
+    : I extends Foldable<F>
+    ? PipeableFoldable<F>
+    : {}) &
+  (I extends Alt<F> ? PipeableAlt<F> : {}) &
+  (I extends FilterableWithIndex<F, infer Ix>
+    ? PipeableFilterableWithIndex<F, Ix>
+    : I extends Filterable<F>
+    ? PipeableFilterable<F>
+    : I extends Compactable<F>
+    ? PipeableCompactable<F>
+    : {}) &
+  (I extends Profunctor<F> ? PipeableProfunctor<F> : {}) &
+  (I extends Semigroupoid<F> ? PipeableSemigroupoid<F> : {})
+export function pipeable<F, I>(I: { URI: F } & I): any {
+  const r: any = {}
+  if (isFunctor<F>(I)) {
+    const map: PipeableFunctor<F>['map'] = f => fa => I.map(fa, f)
+    r.map = map
+  }
+  if (isFunctorWithIndex<F>(I)) {
+    const mapWithIndex: PipeableFunctorWithIndex<F, unknown>['mapWithIndex'] = f => fa => I.mapWithIndex(fa, f)
+    r.mapWithIndex = mapWithIndex
+  }
+  if (isApply<F>(I)) {
+    const ap: PipeableApply<F>['ap'] = fab => fa => I.ap(fab, fa)
+    const apFirst: PipeableApply<F>['apFirst'] = fb => fa => I.ap(I.map(fa, a => () => a), fb)
+    r.ap = ap
+    r.apFirst = apFirst
+    r.apSecond = <B>(fb: HKT<F, B>) => <A>(fa: HKT<F, A>): HKT<F, B> => I.ap(I.map(fa, () => (b: B) => b), fb)
+  }
+  if (isChain<F>(I)) {
+    const chain: PipeableChain<F>['chain'] = f => ma => I.chain(ma, f)
+    const flatten: PipeableChain<F>['flatten'] = mma => I.chain(mma, identity)
+    r.chain = chain
+    r.flatten = flatten
+  }
+  if (isBifunctor<F>(I)) {
+    const bimap: PipeableBifunctor<F>['bimap'] = (f, g) => fa => I.bimap(fa, f, g)
+    const mapLeft: PipeableBifunctor<F>['mapLeft'] = f => fa => I.mapLeft(fa, f)
+    r.bimap = bimap
+    r.mapLeft = mapLeft
+  }
+  if (isExtend<F>(I)) {
+    const extend: PipeableExtend<F>['extend'] = f => wa => I.extend(wa, f)
+    const duplicate: PipeableExtend<F>['duplicate'] = wa => I.extend(wa, identity)
+    r.extend = extend
+    r.duplicate = duplicate
+  }
+  if (isFoldable<F>(I)) {
+    const reduce: PipeableFoldable<F>['reduce'] = (b, f) => fa => I.reduce(fa, b, f)
+    const foldMap: PipeableFoldable<F>['foldMap'] = M => {
+      const foldMapM = I.foldMap(M)
+      return f => fa => foldMapM(fa, f)
+    }
+    const reduceRight: PipeableFoldable<F>['reduceRight'] = (b, f) => fa => I.reduceRight(fa, b, f)
+    r.reduce = reduce
+    r.foldMap = foldMap
+    r.reduceRight = reduceRight
+  }
+  if (isFoldableWithIndex<F>(I)) {
+    const reduceWithIndex: PipeableFoldableWithIndex<F, unknown>['reduceWithIndex'] = (b, f) => fa =>
+      I.reduceWithIndex(fa, b, f)
+    const foldMapWithIndex: PipeableFoldableWithIndex<F, unknown>['foldMapWithIndex'] = M => {
+      const foldMapM = I.foldMapWithIndex(M)
+      return f => fa => foldMapM(fa, f)
+    }
+    const reduceRightWithIndex: PipeableFoldableWithIndex<F, unknown>['reduceRightWithIndex'] = (b, f) => fa =>
+      I.reduceRightWithIndex(fa, b, f)
+    r.reduceWithIndex = reduceWithIndex
+    r.foldMapWithIndex = foldMapWithIndex
+    r.reduceRightWithIndex = reduceRightWithIndex
+  }
+  if (isAlt<F>(I)) {
+    const alt: PipeableAlt<F>['alt'] = that => fa => I.alt(fa, that)
+    r.alt = alt
+  }
+  if (isCompactable<F>(I)) {
+    const compact: PipeableCompactable<F>['compact'] = fa => I.compact(fa)
+    const separate: PipeableCompactable<F>['separate'] = fa => I.separate(fa)
+    r.compact = compact
+    r.separate = separate
+  }
+  if (isFilterable<F>(I)) {
+    const filter: PipeableFilterable<F>['filter'] = <A>(predicate: Predicate<A>) => (fa: HKT<F, A>) =>
+      I.filter(fa, predicate)
+    const filterMap: PipeableFilterable<F>['filterMap'] = f => fa => I.filterMap(fa, f)
+    const partition: PipeableFilterable<F>['partition'] = <A>(predicate: Predicate<A>) => (fa: HKT<F, A>) =>
+      I.partition(fa, predicate)
+    const partitionMap: PipeableFilterable<F>['partitionMap'] = f => fa => I.partitionMap(fa, f)
+    r.filter = filter
+    r.filterMap = filterMap
+    r.partition = partition
+    r.partitionMap = partitionMap
+  }
+  if (isFilterableWithIndex<F>(I)) {
+    const filterWithIndex: PipeableFilterableWithIndex<F, unknown>['filterWithIndex'] = <A>(
+      predicate: PredicateWithIndex<unknown, A>
+    ) => (fa: HKT<F, A>) => I.filterWithIndex(fa, predicate)
+    const filterMapWithIndex: PipeableFilterableWithIndex<F, unknown>['filterMapWithIndex'] = f => fa =>
+      I.filterMapWithIndex(fa, f)
+    const partitionWithIndex: PipeableFilterableWithIndex<F, unknown>['partitionWithIndex'] = <A>(
+      predicate: PredicateWithIndex<unknown, A>
+    ) => (fa: HKT<F, A>) => I.partitionWithIndex(fa, predicate)
+    const partitionMapWithIndex: PipeableFilterableWithIndex<F, unknown>['partitionMapWithIndex'] = f => fa =>
+      I.partitionMapWithIndex(fa, f)
+    r.filterWithIndex = filterWithIndex
+    r.filterMapWithIndex = filterMapWithIndex
+    r.partitionWithIndex = partitionWithIndex
+    r.partitionMapWithIndex = partitionMapWithIndex
+  }
+  if (isProfunctor<F>(I)) {
+    const promap: PipeableProfunctor<F>['promap'] = (f, g) => fa => I.promap(fa, f, g)
+    r.promap = promap
+  }
+  if (isSemigroupoid<F>(I)) {
+    const compose: PipeableSemigroupoid<F>['compose'] = that => fa =>
+      I.compose(
+        fa,
+        that
+      )
+    r.compose = compose
+  }
+  return r
+}


Test patch:
diff --git a/test/Chain.ts b/test/Chain.ts
deleted file mode 100644
index 3e0038e5..00000000
--- a/test/Chain.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import * as assert from 'assert'
-import { head } from '../src/Array'
-import { flatMap } from '../src/Chain'
-import { option, some, none } from '../src/Option'
-
-describe('Functor', () => {
-  it('flatMap', () => {
-    const f = flatMap(option)(head)
-    assert.deepStrictEqual(f(some([1, 2, 3])), some(1))
-    assert.deepStrictEqual(f(some([])), none)
-  })
-})
diff --git a/test/Functor.ts b/test/Functor.ts
index c0a782cb..bed93776 100644
--- a/test/Functor.ts
+++ b/test/Functor.ts
@@ -1,6 +1,6 @@
 import * as assert from 'assert'
 import { array } from '../src/Array'
-import { getFunctorComposition, lift } from '../src/Functor'
+import { getFunctorComposition } from '../src/Functor'
 import * as option from '../src/Option'
 
 describe('Functor', () => {
@@ -9,10 +9,4 @@ describe('Functor', () => {
     const double = (a: number) => a * 2
     assert.deepStrictEqual(arrayOption.map([option.some(1)], double), [option.some(2)])
   })
-
-  it('lift', () => {
-    const double = (a: number) => a * 2
-    const f = lift(option.option)(double)
-    assert.deepStrictEqual(f(option.some(2)), option.some(4))
-  })
 })
diff --git a/test/pipeable.ts b/test/pipeable.ts
new file mode 100644
index 00000000..48507ca8
--- /dev/null
+++ b/test/pipeable.ts
@@ -0,0 +1,125 @@
+import * as assert from 'assert'
+import { array } from '../src/Array'
+import { pipeable, apply } from '../src/pipeable'
+import { either, right, left } from '../src/Either'
+import { monoidSum, fold } from '../src/Monoid'
+import { some, none, isSome, Option, option } from '../src/Option'
+import { reader } from '../src/Reader'
+
+describe('pipeable', () => {
+  it('apply', () => {
+    assert.deepStrictEqual(apply(1, n => n + 1), 2)
+  })
+
+  it('{}', () => {
+    const r = pipeable<'{}', {}>({ URI: '{}' })
+    assert.deepStrictEqual(r, {})
+  })
+
+  it('Functor', () => {
+    const { map } = pipeable(array)
+    assert.deepStrictEqual(map((n: number) => n * 2)([1, 2, 3]), [2, 4, 6])
+  })
+
+  it('FunctorWithIndex', () => {
+    const { mapWithIndex } = pipeable(array)
+    assert.deepStrictEqual(mapWithIndex((i, n: number) => n * 2 + i)([1, 2, 3]), [2, 5, 8])
+  })
+
+  it('Apply', () => {
+    const { ap, apFirst, apSecond } = pipeable(array)
+    assert.deepStrictEqual(ap([(n: number) => n * 2])([1, 2, 3]), [2, 4, 6])
+    assert.deepStrictEqual(apFirst([2])([1]), [1])
+    assert.deepStrictEqual(apSecond([2])([1]), [2])
+  })
+
+  it('Chain', () => {
+    const { chain, flatten } = pipeable(array)
+    assert.deepStrictEqual(chain((n: number) => [n * 2])([1, 2, 3]), [2, 4, 6])
+    assert.deepStrictEqual(flatten([[1], [2], [3]]), [1, 2, 3])
+  })
+
+  it('Bifunctor', () => {
+    const { bimap, mapLeft } = pipeable(either)
+    assert.deepStrictEqual(bimap((s: string) => s.length, (n: number) => n * 2)(right(1)), right(2))
+    assert.deepStrictEqual(bimap((s: string) => s.length, (n: number) => n * 2)(left('aa')), left(2))
+    assert.deepStrictEqual(mapLeft((s: string) => s.length)(right(1)), right(1))
+    assert.deepStrictEqual(mapLeft((s: string) => s.length)(left('aa')), left(2))
+  })
+
+  it('Extend', () => {
+    const { extend, duplicate } = pipeable(array)
+    assert.deepStrictEqual(extend((as: Array<number>) => fold(monoidSum)(as))([1, 2, 3]), [6, 5, 3])
+    assert.deepStrictEqual(duplicate([1, 2, 3]), [[1, 2, 3], [2, 3], [3]])
+  })
+
+  it('Foldable', () => {
+    const { reduce, foldMap, reduceRight } = pipeable(array)
+    assert.deepStrictEqual(reduce(0, (acc, n: number) => acc + n)([1, 2, 3]), 6)
+    assert.deepStrictEqual(foldMap(monoidSum)((n: number) => n)([1, 2, 3]), 6)
+    assert.deepStrictEqual(reduceRight(0, (n: number, acc) => -acc + n)([1, 2, 3]), 2)
+  })
+
+  it('FoldableWithIndex', () => {
+    const { reduceWithIndex, foldMapWithIndex, reduceRightWithIndex } = pipeable(array)
+    assert.deepStrictEqual(reduceWithIndex(0, (i, acc, n: number) => acc + n + i)([1, 2, 3]), 9)
+    assert.deepStrictEqual(foldMapWithIndex(monoidSum)((i, n: number) => n + i)([1, 2, 3]), 9)
+    assert.deepStrictEqual(reduceRightWithIndex(0, (i, n: number, acc) => -acc + n + i)([1, 2, 3]), 3)
+  })
+
+  it('Alt', () => {
+    const { alt } = pipeable(array)
+    assert.deepStrictEqual(alt(() => [4, 5, 6])([1, 2, 3]), [1, 2, 3, 4, 5, 6])
+  })
+
+  it('Compactable', () => {
+    const { compact, separate } = pipeable(array)
+    assert.deepStrictEqual(compact([some(1), none, some(2)]), [1, 2])
+    assert.deepStrictEqual(separate([right(1), left('a'), right(2)]), { left: ['a'], right: [1, 2] })
+  })
+
+  it('Filterable', () => {
+    const { filter, filterMap, partition, partitionMap } = pipeable(array)
+    assert.deepStrictEqual(filter(isSome)([some(1), none, some(2)]), [some(1), some(2)])
+    assert.deepStrictEqual(filterMap(<A>(a: Option<A>) => a)([some(1), none, some(2)]), [1, 2])
+    assert.deepStrictEqual(partition(isSome)([some(1), none, some(2)]), { left: [none], right: [some(1), some(2)] })
+    assert.deepStrictEqual(partitionMap((n: number) => (n > 2 ? right(n) : left(String(n))))([1, 2, 3]), {
+      left: ['1', '2'],
+      right: [3]
+    })
+  })
+
+  it('FilterableWithIndex', () => {
+    const { filterWithIndex, filterMapWithIndex, partitionWithIndex, partitionMapWithIndex } = pipeable(array)
+    assert.deepStrictEqual(filterWithIndex((i, a: Option<number>) => i > 1 && isSome(a))([some(1), none, some(2)]), [
+      some(2)
+    ])
+    assert.deepStrictEqual(
+      filterMapWithIndex((i, a: Option<number>) => option.map(a, n => n + i))([some(1), none, some(2)]),
+      [1, 4]
+    )
+    assert.deepStrictEqual(partitionWithIndex((i, a: Option<number>) => i > 1 && isSome(a))([some(1), none, some(2)]), {
+      left: [some(1), none],
+      right: [some(2)]
+    })
+    assert.deepStrictEqual(
+      partitionMapWithIndex((i, n: number) => (i < 2 && n > 1 ? right(n) : left(String(n))))([1, 2, 3]),
+      {
+        left: ['1', '3'],
+        right: [2]
+      }
+    )
+  })
+
+  it('Profunctor', () => {
+    const { promap } = pipeable(reader)
+    const f = promap((s: string) => s + 'a', (n: number) => n > 2)((s: string) => s.length)
+    assert.strictEqual(f('a'), false)
+    assert.strictEqual(f('aa'), true)
+  })
+
+  it('Semigroupoid', () => {
+    const { compose } = pipeable(reader)
+    assert.strictEqual(compose((s: string) => s.length)(n => n * 2)('aa'), 4)
+  })
+})