You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用fp-ts时如何从TaskEither数组中收集Left值?

如何收集TaskEither数组中的所有Left值(避免短路)

我有一个向订阅者广播事件的函数,返回结果为TaskEither<Error, void>[]。之前一直用sequenceArray将其转换为TaskEither<Error, void[]>,但现在希望收集所有Left值(错误),而不是关注Right值。尝试过swap(sequenceArray(results.map(swap))),但这个方法不奏效——因为sequenceArray遇到Left就会短路,最终出错时只能得到void,无法收集所有错误。


解决方案:逐个执行并汇总错误

要实现不短路的错误收集,需要先把每个TaskEither转换为普通Task(确保所有任务都执行),再过滤汇总错误:

  1. 转换TaskEither为Task
    用fold将每个TaskEither<Error, void>转为Task<Error | undefined>,Left返回错误,Right返回undefined标记无错误:
import { TaskEither, fold } from 'fp-ts/TaskEither';
import { Task, of } from 'fp-ts/Task';

const toErrorTask = (te: TaskEither<Error, void>): Task<Error | undefined> =>
  fold(
    (err) => of(err),
    () => of(undefined)
  )(te);
  1. 执行所有Task并收集结果
    用sequenceArray执行所有转换后的Task,这一步不会短路:
import { sequenceArray } from 'fp-ts/Array';

const taskArray = results.map(toErrorTask);
const rawResults = sequenceArray(taskArray); // Task<(Error | undefined)[]>
  1. 过滤出错误数组
    过滤掉undefined,得到仅包含错误的数组:
import { map } from 'fp-ts/Task';
import { filter } from 'fp-ts/Array';
import { isDefined } from 'fp-ts/Option';

const collectedErrors = map(filter(isDefined))(rawResults); // Task<Error[]>
  1. (可选)转为TaskEither
    如果需要把错误数组放到TaskEither的Right中:
import { right } from 'fp-ts/TaskEither';
import { chain } from 'fp-ts/Task';

const errorsTE = chain((errs) => right(errs))(collectedErrors); // TaskEither<never, Error[]>

原方法失效的原因

sequenceArray是短路式的:只要数组中有一个TaskEither是Left,整个结果会直接返回该Left,不会执行后续任务。而上述方法通过先转换为普通Task,确保所有任务都被执行,再汇总错误,完美解决了短路问题。

内容的提问来源于stack exchange,提问作者Adam A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 08:35:25