如何在Vavr中组合Either对象,避免嵌套flatMap结构?
当然有!Vavr Either的扁平组合方案(无需嵌套flatMap或转Validation)
你完全不用忍受嵌套flatMap的繁琐写法,Vavr的Either本身作为applicative functor,支持类似Validation的扁平组合方式,同时还能保留Either的"短路"特性(遇到第一个Left就立即返回,不继续处理后续值),完全符合你的需求。
下面给你两种常用的简洁写法:
方法1:利用Curried函数 + Either.ap()
这种写法最接近你提到的Validation.combine().ap()的风格,核心是把目标方法转成柯里化形式,然后通过ap()依次传入每个Either的Right值:
// 1. 先把你的方法转成柯里化的函数形式 Function3<String, String, String, Either<MyError, String>> curriedMethod = (v1, v2, v3) -> methodRequiringAllInputs(v1, v2, v3); // 2. 用ap()组合三个Either,写法扁平无嵌套 Either<MyError, String> result = curriedMethod.curried() // 转成柯里化函数:String -> String -> String -> Either<...> .apply(either1) // 传入第一个Either,得到 Either<MyError, String -> String -> Either<...>> .ap(either2) // 传入第二个Either,得到 Either<MyError, String -> Either<...>> .ap(either3); // 传入第三个Either,最终得到结果
方法2:用Either.sequence()转成Tuple后处理
如果你的Either数量较多,这种方式更直观:先把多个Either合并成一个Either<MyError, TupleX<...>>,再调用目标方法:
// 1. 把三个Either放到一个集合里 Iterable<Either<MyError, String>> eithers = List.of(either1, either2, either3); // 2. 转成包含Tuple的Either:只要有一个Left就返回该Left,否则返回包含所有Right值的Tuple Either<MyError, Tuple3<String, String, String>> combined = Either.sequence(eithers) .map(list -> Tuple.of(list.get(0), list.get(1), list.get(2))); // 3. 调用目标方法 Either<MyError, String> result = combined.map(tuple -> methodRequiringAllInputs(tuple._1, tuple._2, tuple._3));
关键说明
- 两种写法都和你原来的嵌套flatMap行为完全一致:只要任意一个Either是
Left<MyError>,整个表达式会立即返回这个Left,不会执行后续的方法调用(短路特性)。 - 不需要把Either转成Validation,完全保留Either的语义。
- 这些方法在Vavr 0.10及以上版本都支持。
内容的提问来源于stack exchange,提问作者Johan
相关产品推荐
相关产品推荐

