Repository: gcanti/fp-ts
Pull request #1758 (2022-09-01 13:37:41)

Traversable: add more overloadings to traverse / sequence helpers


Patch:
diff --git a/docs/modules/Traversable.ts.md b/docs/modules/Traversable.ts.md
index b95eb0d7..0c2d6eb6 100644
--- a/docs/modules/Traversable.ts.md
+++ b/docs/modules/Traversable.ts.md
@@ -76,10 +76,49 @@ Added in v2.0.0
 **Signature**
 
 ```ts
+export declare function sequence<T extends URIS, G extends URIS2>(
+  T: Traversable1<T>,
+  G: Traversable2<G>
+): {
+  <F extends URIS4>(F: Applicative4<F>): <GE, S, R, FE, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind4<F, S, R, FE, A>>>
+  ) => Kind4<F, S, R, FE, Kind<T, Kind2<G, GE, A>>>
+  <F extends URIS3>(F: Applicative3<F>): <GE, R, FE, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind3<F, R, FE, A>>>
+  ) => Kind3<F, R, FE, Kind<T, Kind2<G, GE, A>>>
+  <F extends URIS3, FE>(F: Applicative3C<F, FE>): <GE, R, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind3<F, R, FE, A>>>
+  ) => Kind3<F, R, FE, Kind<T, Kind2<G, GE, A>>>
+  <F extends URIS2>(F: Applicative2<F>): <GE, FE, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind2<F, FE, A>>>
+  ) => Kind2<F, FE, Kind<T, Kind2<G, GE, A>>>
+  <F extends URIS2, FE>(F: Applicative2C<F, FE>): <GE, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind2<F, FE, A>>>
+  ) => Kind2<F, FE, Kind<T, Kind2<G, GE, A>>>
+  <F extends URIS>(F: Applicative1<F>): <GE, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind<F, A>>>
+  ) => Kind<F, Kind<T, Kind2<G, GE, A>>>
+  <F>(F: Applicative<F>): <A>(tgfa: HKT<T, HKT<G, HKT<F, A>>>) => HKT<F, HKT<T, HKT<G, A>>>
+}
 export declare function sequence<T extends URIS, G extends URIS>(
   T: Traversable1<T>,
   G: Traversable1<G>
 ): {
+  <F extends URIS4>(F: Applicative4<F>): <S, R, E, A>(
+    tgfa: Kind<T, Kind<G, Kind4<F, S, R, E, A>>>
+  ) => Kind4<F, S, R, E, Kind<T, Kind<G, A>>>
+  <F extends URIS3>(F: Applicative3<F>): <R, E, A>(
+    tgfa: Kind<T, Kind<G, Kind3<F, R, E, A>>>
+  ) => Kind3<F, R, E, Kind<T, Kind<G, A>>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <R, A>(
+    tgfa: Kind<T, Kind<G, Kind3<F, R, E, A>>>
+  ) => Kind3<F, R, E, Kind<T, Kind<G, A>>>
+  <F extends URIS2>(F: Applicative2<F>): <E, A>(
+    tgfa: Kind<T, Kind<G, Kind2<F, E, A>>>
+  ) => Kind2<F, E, Kind<T, Kind<G, A>>>
+  <F extends URIS2, E>(F: Applicative2C<F, E>): <A>(
+    tgfa: Kind<T, Kind<G, Kind2<F, E, A>>>
+  ) => Kind2<F, E, Kind<T, Kind<G, A>>>
   <F extends URIS>(F: Applicative1<F>): <A>(tgfa: Kind<T, Kind<G, Kind<F, A>>>) => Kind<F, Kind<T, Kind<G, A>>>
   <F>(F: Applicative<F>): <A>(tgfa: HKT<T, HKT<G, HKT<F, A>>>) => HKT<F, HKT<T, HKT<G, A>>>
 }
@@ -98,10 +137,51 @@ Added in v2.10.0
 **Signature**
 
 ```ts
+export declare function traverse<T extends URIS, G extends URIS2>(
+  T: Traversable1<T>,
+  G: Traversable2<G>
+): {
+  <F extends URIS4>(F: Applicative4<F>): <A, S, R, FE, B>(
+    f: (a: A) => Kind4<F, S, R, FE, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind4<F, S, R, FE, Kind<T, Kind2<G, GE, B>>>
+  <F extends URIS3>(F: Applicative3<F>): <A, R, FE, B>(
+    f: (a: A) => Kind3<F, R, FE, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind3<F, R, FE, Kind<T, Kind2<G, GE, B>>>
+  <F extends URIS3, FE>(F: Applicative3C<F, FE>): <A, R, B>(
+    f: (a: A) => Kind3<F, R, FE, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind3<F, R, FE, Kind<T, Kind2<G, GE, B>>>
+  <F extends URIS2>(F: Applicative2<F>): <A, FE, B>(
+    f: (a: A) => Kind2<F, FE, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind2<F, FE, Kind<T, Kind2<G, GE, B>>>
+  <F extends URIS2, FE>(F: Applicative2C<F, FE>): <A, B>(
+    f: (a: A) => Kind2<F, FE, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind2<F, FE, Kind<T, Kind2<G, GE, B>>>
+  <F extends URIS>(F: Applicative1<F>): <A, B>(
+    f: (a: A) => Kind<F, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind<F, Kind<T, Kind2<G, GE, B>>>
+  <F>(F: Applicative<F>): <A, B>(
+    f: (a: A) => HKT<F, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => HKT<F, Kind<T, Kind2<G, GE, B>>>
+}
 export declare function traverse<T extends URIS, G extends URIS>(
   T: Traversable1<T>,
   G: Traversable1<G>
 ): {
+  <F extends URIS4>(F: Applicative4<F>): <A, S, R, E, B>(
+    f: (a: A) => Kind4<F, S, R, E, B>
+  ) => (tga: Kind<T, Kind<G, A>>) => Kind4<F, S, R, E, Kind<T, Kind<G, B>>>
+  <F extends URIS3>(F: Applicative3<F>): <A, R, E, B>(
+    f: (a: A) => Kind3<F, R, E, B>
+  ) => (tga: Kind<T, Kind<G, A>>) => Kind3<F, R, E, Kind<T, Kind<G, B>>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <A, R, B>(
+    f: (a: A) => Kind3<F, R, E, B>
+  ) => (tga: Kind<T, Kind<G, A>>) => Kind3<F, R, E, Kind<T, Kind<G, B>>>
+  <F extends URIS2>(F: Applicative2<F>): <A, E, B>(
+    f: (a: A) => Kind2<F, E, B>
+  ) => (tga: Kind<T, Kind<G, A>>) => Kind2<F, E, Kind<T, Kind<G, B>>>
+  <F extends URIS2, E>(F: Applicative2C<F, E>): <A, B>(
+    f: (a: A) => Kind2<F, E, B>
+  ) => (tga: Kind<T, Kind<G, A>>) => Kind2<F, E, Kind<T, Kind<G, B>>>
   <F extends URIS>(F: Applicative1<F>): <A, B>(
     f: (a: A) => Kind<F, B>
   ) => (tga: Kind<T, Kind<G, A>>) => Kind<F, Kind<T, Kind<G, B>>>
diff --git a/dtslint/ts3.5/Traversable.ts b/dtslint/ts3.5/Traversable.ts
new file mode 100644
index 00000000..ec7714f4
--- /dev/null
+++ b/dtslint/ts3.5/Traversable.ts
@@ -0,0 +1,18 @@
+import * as RA from '../../src/ReadonlyArray'
+import * as E from '../../src/Either'
+import * as _ from '../../src/Traversable'
+import * as TE from '../../src/TaskEither'
+
+//
+// traversable
+//
+
+// $ExpectType <A, FE, B>(f: (a: A) => TaskEither<FE, B>) => <GE>(tga: readonly Either<GE, A>[]) => TaskEither<FE, readonly Either<GE, B>[]>
+_.traverse(RA.Traversable, E.Traversable)(TE.ApplicativePar)
+
+//
+// traversable
+//
+
+// $ExpectType <GE, FE, A>(tgfa: readonly Either<GE, TaskEither<FE, A>>[]) => TaskEither<FE, readonly Either<GE, A>[]>
+_.sequence(RA.Traversable, E.Traversable)(TE.ApplicativePar)
diff --git a/src/Traversable.ts b/src/Traversable.ts
index fa5bc05e..fb624f62 100644
--- a/src/Traversable.ts
+++ b/src/Traversable.ts
@@ -354,10 +354,51 @@ export interface Sequence3<T extends URIS3> {
  * @category combinators
  * @since 2.10.0
  */
+export function traverse<T extends URIS, G extends URIS2>(
+  T: Traversable1<T>,
+  G: Traversable2<G>
+): {
+  <F extends URIS4>(F: Applicative4<F>): <A, S, R, FE, B>(
+    f: (a: A) => Kind4<F, S, R, FE, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind4<F, S, R, FE, Kind<T, Kind2<G, GE, B>>>
+  <F extends URIS3>(F: Applicative3<F>): <A, R, FE, B>(
+    f: (a: A) => Kind3<F, R, FE, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind3<F, R, FE, Kind<T, Kind2<G, GE, B>>>
+  <F extends URIS3, FE>(F: Applicative3C<F, FE>): <A, R, B>(
+    f: (a: A) => Kind3<F, R, FE, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind3<F, R, FE, Kind<T, Kind2<G, GE, B>>>
+  <F extends URIS2>(F: Applicative2<F>): <A, FE, B>(
+    f: (a: A) => Kind2<F, FE, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind2<F, FE, Kind<T, Kind2<G, GE, B>>>
+  <F extends URIS2, FE>(F: Applicative2C<F, FE>): <A, B>(
+    f: (a: A) => Kind2<F, FE, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind2<F, FE, Kind<T, Kind2<G, GE, B>>>
+  <F extends URIS>(F: Applicative1<F>): <A, B>(
+    f: (a: A) => Kind<F, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => Kind<F, Kind<T, Kind2<G, GE, B>>>
+  <F>(F: Applicative<F>): <A, B>(
+    f: (a: A) => HKT<F, B>
+  ) => <GE>(tga: Kind<T, Kind2<G, GE, A>>) => HKT<F, Kind<T, Kind2<G, GE, B>>>
+}
 export function traverse<T extends URIS, G extends URIS>(
   T: Traversable1<T>,
   G: Traversable1<G>
 ): {
+  <F extends URIS4>(F: Applicative4<F>): <A, S, R, E, B>(
+    f: (a: A) => Kind4<F, S, R, E, B>
+  ) => (tga: Kind<T, Kind<G, A>>) => Kind4<F, S, R, E, Kind<T, Kind<G, B>>>
+  <F extends URIS3>(F: Applicative3<F>): <A, R, E, B>(
+    f: (a: A) => Kind3<F, R, E, B>
+  ) => (tga: Kind<T, Kind<G, A>>) => Kind3<F, R, E, Kind<T, Kind<G, B>>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <A, R, B>(
+    f: (a: A) => Kind3<F, R, E, B>
+  ) => (tga: Kind<T, Kind<G, A>>) => Kind3<F, R, E, Kind<T, Kind<G, B>>>
+  <F extends URIS2>(F: Applicative2<F>): <A, E, B>(
+    f: (a: A) => Kind2<F, E, B>
+  ) => (tga: Kind<T, Kind<G, A>>) => Kind2<F, E, Kind<T, Kind<G, B>>>
+  <F extends URIS2, E>(F: Applicative2C<F, E>): <A, B>(
+    f: (a: A) => Kind2<F, E, B>
+  ) => (tga: Kind<T, Kind<G, A>>) => Kind2<F, E, Kind<T, Kind<G, B>>>
   <F extends URIS>(F: Applicative1<F>): <A, B>(
     f: (a: A) => Kind<F, B>
   ) => (tga: Kind<T, Kind<G, A>>) => Kind<F, Kind<T, Kind<G, B>>>
@@ -384,10 +425,49 @@ export function traverse<T, G>(
  * @category combinators
  * @since 2.10.0
  */
+export function sequence<T extends URIS, G extends URIS2>(
+  T: Traversable1<T>,
+  G: Traversable2<G>
+): {
+  <F extends URIS4>(F: Applicative4<F>): <GE, S, R, FE, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind4<F, S, R, FE, A>>>
+  ) => Kind4<F, S, R, FE, Kind<T, Kind2<G, GE, A>>>
+  <F extends URIS3>(F: Applicative3<F>): <GE, R, FE, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind3<F, R, FE, A>>>
+  ) => Kind3<F, R, FE, Kind<T, Kind2<G, GE, A>>>
+  <F extends URIS3, FE>(F: Applicative3C<F, FE>): <GE, R, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind3<F, R, FE, A>>>
+  ) => Kind3<F, R, FE, Kind<T, Kind2<G, GE, A>>>
+  <F extends URIS2>(F: Applicative2<F>): <GE, FE, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind2<F, FE, A>>>
+  ) => Kind2<F, FE, Kind<T, Kind2<G, GE, A>>>
+  <F extends URIS2, FE>(F: Applicative2C<F, FE>): <GE, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind2<F, FE, A>>>
+  ) => Kind2<F, FE, Kind<T, Kind2<G, GE, A>>>
+  <F extends URIS>(F: Applicative1<F>): <GE, A>(
+    tgfa: Kind<T, Kind2<G, GE, Kind<F, A>>>
+  ) => Kind<F, Kind<T, Kind2<G, GE, A>>>
+  <F>(F: Applicative<F>): <A>(tgfa: HKT<T, HKT<G, HKT<F, A>>>) => HKT<F, HKT<T, HKT<G, A>>>
+}
 export function sequence<T extends URIS, G extends URIS>(
   T: Traversable1<T>,
   G: Traversable1<G>
 ): {
+  <F extends URIS4>(F: Applicative4<F>): <S, R, E, A>(
+    tgfa: Kind<T, Kind<G, Kind4<F, S, R, E, A>>>
+  ) => Kind4<F, S, R, E, Kind<T, Kind<G, A>>>
+  <F extends URIS3>(F: Applicative3<F>): <R, E, A>(
+    tgfa: Kind<T, Kind<G, Kind3<F, R, E, A>>>
+  ) => Kind3<F, R, E, Kind<T, Kind<G, A>>>
+  <F extends URIS3, E>(F: Applicative3C<F, E>): <R, A>(
+    tgfa: Kind<T, Kind<G, Kind3<F, R, E, A>>>
+  ) => Kind3<F, R, E, Kind<T, Kind<G, A>>>
+  <F extends URIS2>(F: Applicative2<F>): <E, A>(
+    tgfa: Kind<T, Kind<G, Kind2<F, E, A>>>
+  ) => Kind2<F, E, Kind<T, Kind<G, A>>>
+  <F extends URIS2, E>(F: Applicative2C<F, E>): <A>(
+    tgfa: Kind<T, Kind<G, Kind2<F, E, A>>>
+  ) => Kind2<F, E, Kind<T, Kind<G, A>>>
   <F extends URIS>(F: Applicative1<F>): <A>(tgfa: Kind<T, Kind<G, Kind<F, A>>>) => Kind<F, Kind<T, Kind<G, A>>>
   <F>(F: Applicative<F>): <A>(tgfa: HKT<T, HKT<G, HKT<F, A>>>) => HKT<F, HKT<T, HKT<G, A>>>
 }


Test patch:
diff --git a/test/Traversable.ts b/test/Traversable.ts
index 3800e6be..99bae34f 100644
--- a/test/Traversable.ts
+++ b/test/Traversable.ts
@@ -1,7 +1,9 @@
 import * as U from './util'
 import * as RA from '../src/ReadonlyArray'
 import * as O from '../src/Option'
-import { getTraversableComposition } from '../src/Traversable'
+import * as _ from '../src/Traversable'
+import * as E from '../src/Either'
+import { identity, pipe } from '../src/function'
 
 export const ArrayOptionURI = 'ArrayOption'
 
@@ -9,7 +11,7 @@ export type ArrayOptionURI = typeof ArrayOptionURI
 
 describe('Traversable', () => {
   it('getTraversableComposition', () => {
-    const T = getTraversableComposition(RA.Traversable, O.Traversable)
+    const T = _.getTraversableComposition(RA.Traversable, O.Traversable)
     U.deepStrictEqual(
       T.map([O.some(1), O.some(2), O.none], (n) => n * 2),
       [O.some(2), O.some(4), O.none]
@@ -26,4 +28,14 @@ describe('Traversable', () => {
     U.deepStrictEqual(T.sequence(O.Applicative)([O.some(O.some(1)), O.none]), O.some([O.some(1), O.none]))
     U.deepStrictEqual(T.sequence(O.Applicative)([O.some(O.some(1)), O.some(O.none)]), O.none)
   })
+
+  it('traverse', () => {
+    const traverse = _.traverse(RA.Traversable, RA.Traversable)(E.Applicative)
+    U.deepStrictEqual(pipe([[E.right(1)]], traverse(identity)), E.right([[1]]))
+  })
+
+  it('sequence', () => {
+    const sequence = _.sequence(RA.Traversable, RA.Traversable)(E.Applicative)
+    U.deepStrictEqual(pipe([[E.right(1)]], sequence), E.right([[1]]))
+  })
 })