Repository: gcanti/fp-ts (ts)

Issue:
Suggestion: rename `Tuple.mapLeft` to `Tuple.mapRight` or `Tuple.mapSnd`
## 🐛 Bug report

### Current Behavior

I find the naming of `Tuple.mapLeft` a bit confusing, because it maps the second tuple item (i.e. the right), not the first (i.e. the left).

### Expected behavior

Intuitive naming.

### Reproducible example

### Suggested solution(s)

<!-- How could we solve this bug? What changes would need to made to fp-ts? -->

### Additional context

<!-- Add any other context about the problem here.  -->

### Your environment

Which versions of fp-ts are affected by this issue? Did this work in previous versions of fp-ts?

<!-- PLEASE FILL THIS OUT -->

| Software   | Version(s) |
| ---------- | ---------- |
| fp-ts      |            |
| TypeScript |            |


Pull request:
Tuple / ReadonlyTuple: rename `map` to `mapFst` and `mapLeft` to `map…
…Snd`, closes #1312


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5685e8e7..99d34ecd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,13 @@ high state of flux, you're at risk of it changing without notice.
     - move `assign` to `object` module and rename to `getAssignSemigroup`
   - `ReaderT`
     - remove `get`, `put`, `modify`, `gets` (they will be derived from the `FromState` type-class in `2.11`)
+- **Deprecation**
+  - `Tuple`
+    - deprecate `mapLeft` in favour of `mapSnd`
+    - deprecate `map` in favour of `mapFst`
+  - `ReadonlyTuple`
+    - deprecate `mapLeft` in favour of `mapSnd`
+    - deprecate `map` in favour of `mapFst`
 - **Polish**
   - `Array` / `ReadonlyArray`
     - assert arrays as non-empty when using `some`, #1424 (@thewilkybarkid)
diff --git a/docs/modules/ReadonlyTuple.ts.md b/docs/modules/ReadonlyTuple.ts.md
index ac25dd02..30ae3942 100644
--- a/docs/modules/ReadonlyTuple.ts.md
+++ b/docs/modules/ReadonlyTuple.ts.md
@@ -14,7 +14,7 @@ Added in v2.5.0
 
 - [Bifunctor](#bifunctor)
   - [bimap](#bimap)
-  - [mapLeft](#mapleft)
+  - [mapSnd](#mapsnd)
 - [Extend](#extend)
   - [extend](#extend)
 - [Extract](#extract)
@@ -24,7 +24,7 @@ Added in v2.5.0
   - [reduce](#reduce)
   - [reduceRight](#reduceright)
 - [Functor](#functor)
-  - [map](#map)
+  - [mapFst](#mapfst)
 - [Semigroupoid](#semigroupoid)
   - [compose](#compose)
 - [combinators](#combinators)
@@ -52,6 +52,8 @@ Added in v2.5.0
 - [utils](#utils)
   - [sequence](#sequence)
   - [traverse](#traverse)
+  - [~~mapLeft~~](#mapleft)
+  - [~~map~~](#map)
 
 ---
 
@@ -64,22 +66,27 @@ Map a pair of functions over the two type arguments of the bifunctor.
 **Signature**
 
 ```ts
-export declare const bimap: <E, G, A, B>(f: (e: E) => G, g: (a: A) => B) => (fa: readonly [A, E]) => readonly [B, G]
+export declare const bimap: <E, G, A, B>(
+  mapSnd: (e: E) => G,
+  mapFst: (a: A) => B
+) => (fa: readonly [A, E]) => readonly [B, G]
 ```
 
 Added in v2.5.0
 
-## mapLeft
+## mapSnd
 
-Map a function over the first type argument of a bifunctor.
+Map a function over the second component of a `ReadonlyTuple`.
+
+This is the `mapLeft` operation of the `Bifunctor` instance.
 
 **Signature**
 
 ```ts
-export declare const mapLeft: <E, G>(f: (e: E) => G) => <A>(fa: readonly [A, E]) => readonly [A, G]
+export declare const mapSnd: <E, G>(f: (e: E) => G) => <A>(fa: readonly [A, E]) => readonly [A, G]
 ```
 
-Added in v2.5.0
+Added in v2.10.0
 
 # Extend
 
@@ -139,18 +146,19 @@ Added in v2.5.0
 
 # Functor
 
-## map
+## mapFst
 
-`map` can be used to turn functions `(a: A) => B` into functions `(fa: F<A>) => F<B>` whose argument and return types
-use the type constructor `F` to represent some computational context.
+Map a function over the first component of a `ReadonlyTuple`.
+
+This is the `map` operation of the `Functor` instance.
 
 **Signature**
 
 ```ts
-export declare const map: <A, B>(f: (a: A) => B) => <E>(fa: readonly [A, E]) => readonly [B, E]
+export declare const mapFst: <A, B>(f: (a: A) => B) => <E>(fa: readonly [A, E]) => readonly [B, E]
 ```
 
-Added in v2.5.0
+Added in v2.10.0
 
 # Semigroupoid
 
@@ -391,3 +399,27 @@ export declare const traverse: PipeableTraverse2<'ReadonlyTuple'>
 ```
 
 Added in v2.6.3
+
+## ~~mapLeft~~
+
+Use `mapSnd` instead.
+
+**Signature**
+
+```ts
+export declare const mapLeft: <E, G>(f: (e: E) => G) => <A>(fa: readonly [A, E]) => readonly [A, G]
+```
+
+Added in v2.5.0
+
+## ~~map~~
+
+Use `mapFst` instead.
+
+**Signature**
+
+```ts
+export declare const map: <A, B>(f: (a: A) => B) => <E>(fa: readonly [A, E]) => readonly [B, E]
+```
+
+Added in v2.5.0
diff --git a/docs/modules/Tuple.ts.md b/docs/modules/Tuple.ts.md
index 37aabe9a..a9fe65b5 100644
--- a/docs/modules/Tuple.ts.md
+++ b/docs/modules/Tuple.ts.md
@@ -14,7 +14,7 @@ Added in v2.0.0
 
 - [Bifunctor](#bifunctor)
   - [bimap](#bimap)
-  - [mapLeft](#mapleft)
+  - [mapSnd](#mapsnd)
 - [Extend](#extend)
   - [extend](#extend)
 - [Extract](#extract)
@@ -24,7 +24,7 @@ Added in v2.0.0
   - [reduce](#reduce)
   - [reduceRight](#reduceright)
 - [Functor](#functor)
-  - [map](#map)
+  - [mapFst](#mapfst)
 - [Semigroupoid](#semigroupoid)
   - [compose](#compose)
 - [combinators](#combinators)
@@ -52,6 +52,8 @@ Added in v2.0.0
 - [utils](#utils)
   - [sequence](#sequence)
   - [traverse](#traverse)
+  - [~~mapLeft~~](#mapleft)
+  - [~~map~~](#map)
 
 ---
 
@@ -64,22 +66,24 @@ Map a pair of functions over the two type arguments of the bifunctor.
 **Signature**
 
 ```ts
-export declare const bimap: <E, G, A, B>(f: (e: E) => G, g: (a: A) => B) => (fa: [A, E]) => [B, G]
+export declare const bimap: <E, G, A, B>(mapSnd: (e: E) => G, mapFst: (a: A) => B) => (fa: [A, E]) => [B, G]
 ```
 
 Added in v2.0.0
 
-## mapLeft
+## mapSnd
 
-Map a function over the first type argument of a bifunctor.
+Map a function over the second component of a `Tuple`.
+
+This is the `mapLeft` operation of the `Bifunctor` instance.
 
 **Signature**
 
 ```ts
-export declare const mapLeft: <E, G>(f: (e: E) => G) => <A>(fa: [A, E]) => [A, G]
+export declare const mapSnd: <E, G>(f: (e: E) => G) => <A>(fa: [A, E]) => [A, G]
 ```
 
-Added in v2.0.0
+Added in v2.10.0
 
 # Extend
 
@@ -139,15 +143,16 @@ Added in v2.0.0
 
 # Functor
 
-## map
+## mapFst
 
-`map` can be used to turn functions `(a: A) => B` into functions `(fa: F<A>) => F<B>` whose argument and return types
-use the type constructor `F` to represent some computational context.
+Map a function over the first component of a `Tuple`.
+
+This is the `map` operation of the `Functor` instance.
 
 **Signature**
 
 ```ts
-export declare const map: <A, B>(f: (a: A) => B) => <E>(fa: [A, E]) => [B, E]
+export declare const mapFst: <A, B>(f: (a: A) => B) => <E>(fa: [A, E]) => [B, E]
 ```
 
 Added in v2.0.0
@@ -391,3 +396,27 @@ export declare const traverse: PipeableTraverse2<'Tuple'>
 ```
 
 Added in v2.6.3
+
+## ~~mapLeft~~
+
+Use `mapSnd` instead.
+
+**Signature**
+
+```ts
+export declare const mapLeft: <E, G>(f: (e: E) => G) => <A>(fa: [A, E]) => [A, G]
+```
+
+Added in v2.0.0
+
+## ~~map~~
+
+Use `mapFst` instead.
+
+**Signature**
+
+```ts
+export declare const map: <A, B>(f: (a: A) => B) => <E>(fa: [A, E]) => [B, E]
+```
+
+Added in v2.0.0
diff --git a/src/ReadonlyTuple.ts b/src/ReadonlyTuple.ts
index a47d58de..5c2b4cbe 100644
--- a/src/ReadonlyTuple.ts
+++ b/src/ReadonlyTuple.ts
@@ -146,11 +146,11 @@ export function getChainRec<M>(M: Monoid<M>): ChainRec2C<URI, M> {
 /* istanbul ignore next */
 const _compose: Semigroupoid2<URI>['compose'] = (bc, ab) => pipe(bc, compose(ab))
 /* istanbul ignore next */
-const _map: Functor2<URI>['map'] = (fa, f) => pipe(fa, map(f))
+const _map: Functor2<URI>['map'] = (fa, f) => pipe(fa, mapFst(f))
 /* istanbul ignore next */
 const _bimap: Bifunctor2<URI>['bimap'] = (fa, f, g) => pipe(fa, bimap(f, g))
 /* istanbul ignore next */
-const _mapLeft: Bifunctor2<URI>['mapLeft'] = (fa, f) => pipe(fa, mapLeft(f))
+const _mapLeft: Bifunctor2<URI>['mapLeft'] = (fa, f) => pipe(fa, mapSnd(f))
 /* istanbul ignore next */
 const _extend: Extend2<URI>['extend'] = (wa, f) => pipe(wa, extend(f))
 /* istanbul ignore next */
@@ -180,18 +180,33 @@ const _traverse = <F>(
  * @category Bifunctor
  * @since 2.5.0
  */
-export const bimap: <E, G, A, B>(f: (e: E) => G, g: (a: A) => B) => (fa: readonly [A, E]) => readonly [B, G] = (
-  f,
-  g
-) => (fa) => [g(fst(fa)), f(snd(fa))]
+export const bimap: <E, G, A, B>(
+  mapSnd: (e: E) => G,
+  mapFst: (a: A) => B
+) => (fa: readonly [A, E]) => readonly [B, G] = (f, g) => (fa) => [g(fst(fa)), f(snd(fa))]
 
 /**
- * Map a function over the first type argument of a bifunctor.
+ * Map a function over the first component of a `ReadonlyTuple`.
+ *
+ * This is the `map` operation of the `Functor` instance.
+ *
+ * @category Functor
+ * @since 2.10.0
+ */
+export const mapFst: <A, B>(f: (a: A) => B) => <E>(fa: readonly [A, E]) => readonly [B, E] = (f) => (fa) => [
+  f(fst(fa)),
+  snd(fa)
+]
+
+/**
+ * Map a function over the second component of a `ReadonlyTuple`.
+ *
+ * This is the `mapLeft` operation of the `Bifunctor` instance.
  *
  * @category Bifunctor
- * @since 2.5.0
+ * @since 2.10.0
  */
-export const mapLeft: <E, G>(f: (e: E) => G) => <A>(fa: readonly [A, E]) => readonly [A, G] = (f) => (fa) => [
+export const mapSnd: <E, G>(f: (e: E) => G) => <A>(fa: readonly [A, E]) => readonly [A, G] = (f) => (fa) => [
   fst(fa),
   f(snd(fa))
 ]
@@ -229,18 +244,6 @@ export const duplicate: <E, A>(wa: readonly [A, E]) => readonly [readonly [A, E]
   /*#__PURE__*/
   extend(identity)
 
-/**
- * `map` can be used to turn functions `(a: A) => B` into functions `(fa: F<A>) => F<B>` whose argument and return types
- * use the type constructor `F` to represent some computational context.
- *
- * @category Functor
- * @since 2.5.0
- */
-export const map: <A, B>(f: (a: A) => B) => <E>(fa: readonly [A, E]) => readonly [B, E] = (f) => (fa) => [
-  f(fst(fa)),
-  snd(fa)
-]
-
 /**
  * @category Foldable
  * @since 2.5.0
@@ -381,6 +384,22 @@ export const Traversable: Traversable2<URI> = {
 // deprecated
 // -------------------------------------------------------------------------------------
 
+/**
+ * Use `mapFst` instead.
+ *
+ * @since 2.5.0
+ * @deprecated
+ */
+export const map: <A, B>(f: (a: A) => B) => <E>(fa: readonly [A, E]) => readonly [B, E] = mapFst
+
+/**
+ * Use `mapSnd` instead.
+ *
+ * @since 2.5.0
+ * @deprecated
+ */
+export const mapLeft: <E, G>(f: (e: E) => G) => <A>(fa: readonly [A, E]) => readonly [A, G] = mapSnd
+
 /**
  * Use small, specific instances instead.
  *
diff --git a/src/Tuple.ts b/src/Tuple.ts
index bb9b7c58..dbe382b5 100644
--- a/src/Tuple.ts
+++ b/src/Tuple.ts
@@ -143,11 +143,11 @@ export function getChainRec<M>(M: Monoid<M>): ChainRec2C<URI, M> {
 /* istanbul ignore next */
 const _compose: Semigroupoid2<URI>['compose'] = (bc, ab) => pipe(bc, compose(ab))
 /* istanbul ignore next */
-const _map: Functor2<URI>['map'] = (fa, f) => pipe(fa, map(f))
+const _map: Functor2<URI>['map'] = (fa, f) => pipe(fa, mapFst(f))
 /* istanbul ignore next */
 const _bimap: Bifunctor2<URI>['bimap'] = (fa, f, g) => pipe(fa, bimap(f, g))
 /* istanbul ignore next */
-const _mapLeft: Bifunctor2<URI>['mapLeft'] = (fa, f) => pipe(fa, mapLeft(f))
+const _mapLeft: Bifunctor2<URI>['mapLeft'] = (fa, f) => pipe(fa, mapSnd(f))
 /* istanbul ignore next */
 const _extend: Extend2<URI>['extend'] = (wa, f) => pipe(wa, extend(f))
 /* istanbul ignore next */
@@ -175,18 +175,29 @@ function _traverse<F>(F: Applicative<F>): <A, S, B>(ta: [A, S], f: (a: A) => HKT
  * @category Bifunctor
  * @since 2.0.0
  */
-export const bimap: <E, G, A, B>(f: (e: E) => G, g: (a: A) => B) => (fa: [A, E]) => [B, G] = (f, g) => (fa) => [
-  g(fst(fa)),
-  f(snd(fa))
-]
+export const bimap: <E, G, A, B>(mapSnd: (e: E) => G, mapFst: (a: A) => B) => (fa: [A, E]) => [B, G] = (f, g) => (
+  fa
+) => [g(fst(fa)), f(snd(fa))]
 
 /**
- * Map a function over the first type argument of a bifunctor.
+ * Map a function over the first component of a `Tuple`.
  *
- * @category Bifunctor
+ * This is the `map` operation of the `Functor` instance.
+ *
+ * @category Functor
  * @since 2.0.0
  */
-export const mapLeft: <E, G>(f: (e: E) => G) => <A>(fa: [A, E]) => [A, G] = (f) => (fa) => [fst(fa), f(snd(fa))]
+export const mapFst: <A, B>(f: (a: A) => B) => <E>(fa: [A, E]) => [B, E] = (f) => (fa) => [f(fst(fa)), snd(fa)]
+
+/**
+ * Map a function over the second component of a `Tuple`.
+ *
+ * This is the `mapLeft` operation of the `Bifunctor` instance.
+ *
+ * @category Bifunctor
+ * @since 2.10.0
+ */
+export const mapSnd: <E, G>(f: (e: E) => G) => <A>(fa: [A, E]) => [A, G] = (f) => (fa) => [fst(fa), f(snd(fa))]
 
 /**
  * @category Semigroupoid
@@ -222,15 +233,6 @@ export const extract: <E, A>(wa: [A, E]) => A = RT.extract
  */
 export const foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => <E>(fa: [A, E]) => M = RT.foldMap
 
-/**
- * `map` can be used to turn functions `(a: A) => B` into functions `(fa: F<A>) => F<B>` whose argument and return types
- * use the type constructor `F` to represent some computational context.
- *
- * @category Functor
- * @since 2.0.0
- */
-export const map: <A, B>(f: (a: A) => B) => <E>(fa: [A, E]) => [B, E] = (f) => (fa) => [f(fst(fa)), snd(fa)]
-
 /**
  * @category Foldable
  * @since 2.0.0
@@ -361,6 +363,22 @@ export const Traversable: Traversable2<URI> = {
 // deprecated
 // -------------------------------------------------------------------------------------
 
+/**
+ * Use `mapFst` instead.
+ *
+ * @since 2.0.0
+ * @deprecated
+ */
+export const map: <A, B>(f: (a: A) => B) => <E>(fa: [A, E]) => [B, E] = mapFst
+
+/**
+ * Use `mapSnd` instead.
+ *
+ * @since 2.0.0
+ * @deprecated
+ */
+export const mapLeft: <E, G>(f: (e: E) => G) => <A>(fa: [A, E]) => [A, G] = mapSnd
+
 /**
  * Use small, specific instances instead.
  *


Test patch:
diff --git a/test/ReadonlyTuple.ts b/test/ReadonlyTuple.ts
index 12bbbfa7..f467c05c 100644
--- a/test/ReadonlyTuple.ts
+++ b/test/ReadonlyTuple.ts
@@ -13,8 +13,8 @@ describe('ReadonlyTuple', () => {
       U.deepStrictEqual(pipe([true, 2] as const, _.compose([1, 'a'])), [true, 'a'])
     })
 
-    it('map', () => {
-      U.deepStrictEqual(pipe([1, 'a'] as const, _.map(U.double)), [2, 'a'])
+    it('mapFst', () => {
+      U.deepStrictEqual(pipe([1, 'a'] as const, _.mapFst(U.double)), [2, 'a'])
     })
 
     it('extract', () => {
@@ -30,8 +30,8 @@ describe('ReadonlyTuple', () => {
       U.deepStrictEqual(pipe([1, 'a'], _.bimap(S.size, U.double)), [2, 1])
     })
 
-    it('mapLeft', () => {
-      U.deepStrictEqual(pipe([1, 'a'] as const, _.mapLeft(S.size)), [1, 1])
+    it('mapSnd', () => {
+      U.deepStrictEqual(pipe([1, 'a'] as const, _.mapSnd(S.size)), [1, 1])
     })
 
     it('duplicate', () => {
diff --git a/test/Tuple.ts b/test/Tuple.ts
index 0da5f7d6..c28094ab 100644
--- a/test/Tuple.ts
+++ b/test/Tuple.ts
@@ -13,8 +13,8 @@ describe('Tuple', () => {
       U.deepStrictEqual(pipe([true, 2] as [boolean, number], _.compose([1, 'a'])), [true, 'a'])
     })
 
-    it('map', () => {
-      U.deepStrictEqual(pipe([1, 'a'] as [number, string], _.map(U.double)), [2, 'a'])
+    it('mapFst', () => {
+      U.deepStrictEqual(pipe([1, 'a'] as [number, string], _.mapFst(U.double)), [2, 'a'])
     })
 
     it('extract', () => {
@@ -30,8 +30,8 @@ describe('Tuple', () => {
       U.deepStrictEqual(pipe([1, 'a'], _.bimap(S.size, U.double)), [2, 1])
     })
 
-    it('mapLeft', () => {
-      U.deepStrictEqual(pipe([1, 'a'] as [number, string], _.mapLeft(S.size)), [1, 1])
+    it('mapSnd', () => {
+      U.deepStrictEqual(pipe([1, 'a'] as [number, string], _.mapSnd(S.size)), [1, 1])
     })
 
     it('duplicate', () => {