管理函数式编程和fp-ts中的错误

时间:2020-04-05 20:12:02

标签: typescript functional-programming fp-ts

我对函数式编程非常陌生,尤其是fp-ts

我最近在挣扎的是使用数组并将它们链接到不同的Monad中,同时保留与每个步骤有关的一些细节。

假设我们有一个程序,

  1. 以字符串形式获取一些数据
  2. 如果可能,将字符串解析为ITitle数组;类型可以为Option<ITitle[]>
  3. 将它们映射到可能执行某些异步更新的ITitle数组中;类型可以为TaskEither<IError, ITitle>
  4. 打印结果(如果有),包括带有特定错误的故障
// 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?
)

1 个答案:

答案 0 :(得分:2)

TE.map(parseTitles)给我们一个TaskEither<IError, Option<ITitle[]>>,问题出在chain回调中,其中titles仍然包裹在Option中,这不起作用

您可以使用fromOption添加另一个将chain展开为Option的{​​{1}}:

TaskEither

fromEither

const program = pipe(
  findTitles(),
  TE.map(parseTitles), // Now we have TaskEither<IError, Option<ITitle[]>>;
  TE.chain(TE.fromOption(() => ErrorType.NotFound)) // Now we have TaskEither<IError, ITitle[]>
  TE.chain(titles =>
    array.traverse(taskEither)(titles, title => updateTitle(title))
  ),
)
相关问题