【问题标题】:How to convert a `NonEmptyList[Either[Error, User]]` to `Either[Error, NonEmptyList[User]]` with cats?如何使用猫将 `NonEmptyList[Either[Error, User]]` 转换为 `Either[Error, NonEmptyList[User]]`?
【发布时间】:2018-01-14 14:05:59
【问题描述】:

我正在使用cats,想知道如何用它来转换数据:

val data = NonEmptyList[Either[Error, User]]

val target: Either[Error, NonEmptyList[User]] = howToConvert(data)

【问题讨论】:

  • 我认为您的任务未指定。如果你有几个错误怎么办?它们应该如何聚合成一个错误?此外,如果您有一些未失败的Users 和一些Errors,您期望得到什么?一些Error或成功的列表Users?
  • @SergGr 感谢您的提问。如果有几个错误,我只希望最终结果有第一个
  • 如果同时存在Errors 和有效Users?
  • @SergGr,那么它将是Left(error)

标签: scala list scala-cats either


【解决方案1】:

通常,当您想将类型构造函数从内到外时,您可能正在寻找sequence。如果你在 Scala >= 2.11.9 中打开了-Ypartial-unification,你可以让编译器推断一切:

data.sequence

否则:

type EitherError[A] = Either[Error, A]
data.sequence[EitherError, User]

或者如果你有type lambda plugin:

data.sequence[Either[Error, ?], User]

或者如果你没有插件,但你不喜欢类型别名:

data.sequence[({type L[A] = Either[Error, A]})#L, User]

它将执行预期的操作,即返回第一个错误,或者如果没有错误,则返回所有用户。如果我们假装用户是整数,错误是字符串:

scala> import cats.data.NonEmptyList, cats.implicits._
import cats.data.NonEmptyList
import cats.implicits._

scala> val data: NonEmptyList[Either[Error, User]] = NonEmptyList.of(Right(2), Left("error1"), Right(4))
data: cats.data.NonEmptyList[Either[Error,User]] = NonEmptyList(Right(2), Left(error1), Right(4))

scala> data.sequence
res4: Either[Error,cats.data.NonEmptyList[User]] = Left(error1)

【讨论】:

  • 优秀的答案!我最终选择了第一种方式,感谢您向我展示了另外两种方式
  • 贾斯珀,对真正问题的通灵阅读做得很好 - 100% 成功。
猜你喜欢
  • 2018-06-23
  • 2020-08-13
  • 1970-01-01
  • 2019-04-03
  • 2020-06-18
  • 1970-01-01
  • 1970-01-01
  • 2013-05-01
  • 1970-01-01
相关资源
最近更新 更多