I'm relatively new to functional programming and very new to fp-ts, so I'm having a struggle wrapping my head around the util functions provided. I'm currently trying to figure out how to handle TaskEither
s as fallbacks in an array.
I have a function to fetch data for some id
, that returns Error
or Success
:
declare function getData(id: number): TaskEither<Error, Success>
What I want is a function that will iterate through some array of id
s (ex. [1, 2, 3, 4]
), requesting data for each one. It should stop at the first TaskEither
that succeeds and return Right<Success>
. If all of the TaskEither
s fail, it should collect their errors into a Left<Error[]>
.
import { map } from 'fp-ts/lib/Array';
const program: TaskEither<Error[], Success>
= pipe(
[1, 2, 3, 4],
map(getData),
/*
* Now I have a TaskEither<Error, Success>[]
* What comes next?
*/
);
I tried something similar, but there are some obvious problems (noted below):
import { map, sequence } from 'fp-ts/lib/Array';
import { map as mapTaskEither } from 'fp-ts/lib/TaskEither'
const program: TaskEither<Error, Success>
= pipe(
[1, 2, 3, 4],
map(getData),
sequence(taskEither), // Now this gets to a TaskEither<Error, Success[]>
mapTaskEither(successes => successes[0])
);
Problems with this approach
- It runs
getData
on all of the IDs, without short-circuiting on the first success - It errors if any of the
getData
s errors. So ifgetData(4)
errors, the overallprogram
will error even ifgetData(1)
succeeded - It does not collect the errors into an array of
Error[]