本文详解如何使用 `flatmap` 正确串联多个返回 `either` 的函数,实现错误短路传播与值安全传递,避免 `map` 导致的嵌套 `either>` 类型问题。
在函数式编程中,Vavr 的 Either 是处理可能失败操作的理想抽象——它显式区分成功(Right)与失败(Left)路径。但初学者常误用 map 进行链式调用,导致类型不匹配:map 会将 Either 中的 A 映射为 Either,最终得到 Either>,而非期望的扁平化 Either。
正确的方式是使用 flatMap ——它专为“单子(monadic)绑定”设计:接受一个返回 Either 的函数,并自动展开(flatten)结果,保持类型始终为 Either。
以下是你原始代码的修正版本:
private Either getPath(Arg arg) {
return Try.of(() -> Files.createTempFile("prefix", ".txt"))
.toEither()
.mapLeft(e -> new MyError("Failed to create temp path", e));
}
private Either getContent(Path path) {
return Try.of(() -> Files.readString(path))
.toEither()
.mapLeft(e -> new MyError("Failed to read file content", e));
}
public Either handle(Arg arg) {
return Either.right(arg)
.flatMap(this::getPath) // ✅ 若 getPath 返回 Left,立即终止并透传错误
.flatMap(this::getContent); // ✅ 仅当 getPath 返回 Right(Path) 时才执行
}
关键点解析: