如何用Cats将NonEmptyList[Either[Error, User]]转为Either[Error, NonEmptyList[User]]
如何在Cats中转换
NonEmptyList[Either[Error, User]]到Either[Error, NonEmptyList[User]] 嘿,这个转换在Cats库中其实非常简洁,核心就是用sequence方法——它专门用来处理这种“翻转”嵌套数据结构的场景。
步骤1:确保导入必要的依赖和隐式实例
首先,你需要导入Cats的核心数据类型和隐式转换,这样才能让sequence方法生效:
import cats.data.NonEmptyList import cats.implicits._ // 这会引入针对NonEmptyList的Traverse实例,以及针对Either的Applicative实例
步骤2:直接使用sequence完成转换
sequence方法的作用就是把F[G[A]]类型的结构翻转成G[F[A]],这里:
F是NonEmptyList(它实现了Traverse类型类,支持遍历操作)G是Either(它实现了Applicative类型类,支持上下文相关的组合操作)
所以你的转换代码可以直接写成:
val data: NonEmptyList[Either[Error, User]] = // 你的数据源 val target: Either[Error, NonEmptyList[User]] = data.sequence
它的工作逻辑
- 如果
data里的所有Either都是Right(User),sequence会把所有User收集到一个NonEmptyList中,返回Right(NonEmptyList[User]) - 如果
data中存在任意一个Left(Error),sequence会立即返回第一个遇到的Left(Error),不会继续处理后续元素——这完全符合你想要的“只要有错误就返回错误,否则返回完整用户列表”的语义
示例验证
用简单的字符串类型演示效果更直观:
// 全有效数据的情况 val validUsers: NonEmptyList[Either[String, String]] = NonEmptyList.of(Right("Alice"), Right("Bob")) val validResult = validUsers.sequence // 输出:Right(NonEmptyList(Alice, Bob)) // 包含错误数据的情况 val invalidUsers: NonEmptyList[Either[String, String]] = NonEmptyList.of(Right("Alice"), Left("Invalid user ID"), Right("Bob")) val invalidResult = invalidUsers.sequence // 输出:Left(Invalid user ID)
额外说明
如果你需要收集所有错误(而不是只返回第一个),那可能需要用traverse配合Validated类型,但这是另一种场景——你的需求正好匹配sequence的默认行为。
内容的提问来源于stack exchange,提问作者Freewind
相关产品推荐
相关产品推荐

