如何用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
相关产品推荐
相关产品推荐

