You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:26:50