I'm very new to Functional Programming and specially fp-ts
.
What I'm struggling recently is playing with arrays and chaining them into different Monads and at the same time preserving some details related to each step.
Let's say we have a program that
- fetchs some data as string
- parses the string into array of
ITitle
if possible; type can beOption<ITitle[]>
- maps them into an array of possible
ITitle
performing some async updates; type can beTaskEither<IError, ITitle>
- Prints the result (if available) including the failures with their specific errors
// error definition
enum ErrorType {
NotFound = 'NOT_FOUND',
Timeout = 'TIMEOUT',
ParseFailure = 'PARSE_FAILURE',
UpdateFailure = 'UPDATE_FAILURE',
Unknown = 'UNKNOWN',
}
// our types
interface ITitle {
title: string;
meta: unknown;
}
interface IError {
msg: string;
type: ErrorType;
}
// helper functions
declare function findTitles(): TaskEither<IError, string>;
declare function parseTitles(items: string): Option<ITitle[]>; // or Either<IError, ITitle[]> whatever fits best
declare function updateTitle(title: ITitle): TaskEither<IError, ITitle>;
Update:
I'm updating the question with more specific details where the problem is:
const program = pipe(
findTitles(),
TE.map(parseTitles), // Now we get TaskEither<IError, Option<ITitle[]>>;
TE.chain(titles =>
// Problem is var titles is still wrapped in Option and this won't work
// What if the titles is Either<IError, ITitle[]>?
// How do we preserve the error if titles is an Either?
array.traverse(taskEither)(titles, title => updateTitle(title))
),
// How to log the result including the errors?
// Or in another word how do we run traverse and fold the Eithers?
)