我对函数式编程非常陌生,特别是fp-ts
.
我最近苦苦挣扎的是使用数组并将它们链接到不同的 Monad 中,同时保留与每个步骤相关的一些细节。
假设我们有一个程序
- 获取一些数据作为字符串
ITitle
如果可能,将字符串解析为数组;类型可以是Option<ITitle[]>
ITitle
将它们映射到可能执行一些异步更新的数组中;类型可以是TaskEither<IError, ITitle>
- 打印结果(如果可用),包括失败及其特定错误
// 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>;
更新:
我正在用更具体的问题更新问题:
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?
)