如何使用Dartz拼接多个Left值,得到返回Left列表的Either结果?
Dartz累积多Either所有Left的实现方案
Dartz没有直接对应mapN且自动收集所有Left的开箱即用方法,不过可以通过内置的Validation类型快速实现该需求,无需自己手写遍历逻辑。
实现原理
Either的mapN默认是短路逻辑,遇到第一个Left就直接返回,不匹配错误累积的场景。而Validation类型的设计目标就是处理表单校验这类需要同时返回所有错误的场景,它的组合逻辑会自动累积所有的Left值,正好匹配你的需求。
示例代码
import 'package:dartz/dartz.dart'; void main() { // 模拟5个待处理的Either实例 final either1 = Left<String, int>("参数1校验失败"); final either2 = Right<String, int>(2); final either3 = Left<String, int>("参数3校验失败"); final either4 = Right<String, int>(4); final either5 = Left<String, int>("参数5校验失败"); // 1. 将所有Either转成支持错误累积的Validation类型,把单个错误包装成非空列表 final v1 = either1.leftMap((l) => NonEmptyList.of(l)).toValidation(); final v2 = either2.leftMap((l) => NonEmptyList.of(l)).toValidation(); final v3 = either3.leftMap((l) => NonEmptyList.of(l)).toValidation(); final v4 = either4.leftMap((l) => NonEmptyList.of(l)).toValidation(); final v5 = either5.leftMap((l) => NonEmptyList.of(l)).toValidation(); // 2. 用map5组合所有Validation,自动累积所有错误 final resultValidation = map5(v1, v2, v3, v4, v5, (a, b, c, d, e) => a + b + c + d + e); // 3. 转换为你需要的Either<List<L>, R>格式 final Either<List<String>, int> result = resultValidation.fold( (errorList) => Left(errorList.toList()), (value) => Right(value), ); // 输出示例:Left([参数1校验失败, 参数3校验失败, 参数5校验失败]) print(result); }
补充说明
- 示例中使用
NonEmptyList是因为Dartz内置了它的Semigroup实例,会自动拼接多个错误列表,如果你不需要强制错误列表非空,也可以自己定义普通List的Semigroup实现,逻辑一致。 - 如果你需要处理动态数量的Either,可以先将所有实例转换为Validation后调用
sequence方法,再转换为目标格式即可。 - 频繁使用该逻辑的场景可以自行封装工具函数,比如
accumulateMap2到accumulateMapN,简化重复代码。
内容的提问来源于stack exchange,提问作者LeYAUable
相关产品推荐
相关产品推荐

