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

如何用fp-ts重构测试代码并拆分TaskEither数组的左右结果?

解决fp-ts中展开Either嵌套数组并分离结果的问题

首先,你当前的核心问题是处理Task<Array<Either<E, Array<Function>>>>类型,需要把Right中的数组展开,同时分离Left和Right结果。之前用sequence无效是因为它的作用是将Array<Task<...>>转换为Task<Array<...>>,并不处理Either内部的嵌套数组,所以得换用map+flatMap结合Either的折叠操作来实现。

步骤1:展开Right中的嵌套数组

我们需要将每个Either<E, Array<Fn>>转换为Array<Either<E, Fn>>:

  • 对于Left值:直接包装为单元素数组(保留错误上下文)
  • 对于Right中的数组:将每个元素单独包装为Right,生成一个Right数组

然后对整个大数组执行flat操作,就能得到Array<Either<E, Fn>>,再包裹回Task中。

示例代码:

import { Task } from 'fp-ts/Task';
import { Either, left, right, fold } from 'fp-ts/Either';

// 定义你的错误类型和测试函数类型
type TestError = Error;
type TestFn = () => Promise<boolean>;

// 假设这是你当前得到的原结果
const originalTask: Task<Array<Either<TestError, Array<TestFn>>>> = /* 你的原代码逻辑 */;

// 展开嵌套数组,得到Task<Array<Either<TestError, TestFn>>>
const flattenedTask: Task<Array<Either<TestError, TestFn>>> = originalTask.map(results =>
  results.flatMap(either =>
    fold(
      // Left分支:保留错误,转为单元素数组
      (err) => [left(err)],
      // Right分支:将数组中每个测试函数包装为Right
      (testFns) => testFns.map(right)
    )(either)
  )
);

步骤2:分离Left和Right结果

使用fp-ts/Array中的partition函数,结合isLeft来拆分数组,分别提取错误和测试函数:

import { partition } from 'fp-ts/Array';
import { isLeft } from 'fp-ts/Either';

// 分离错误和测试函数,得到包含两个数组的对象
const separatedTask: Task<{ errors: TestError[], tests: TestFn[] }> = flattenedTask.map(results => {
  const [errorEithers, testEithers] = partition(isLeft)(results);
  return {
    errors: errorEithers.map(e => e.left),
    tests: testEithers.map(e => e.right)
  };
});

后续统计与执行

拿到分离后的结果后,你就可以直接通过errors.length统计加载失败的数量,tests.length统计成功加载的测试函数数量。执行测试时,还可以继续用fp-ts的工具(比如TaskEither)来捕获每个测试的执行错误,最终汇总所有测试的通过/失败数。

内容的提问来源于stack exchange,提问作者Ricardo Silva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:25:20