如何使用猫将 `NonEmptyList[Either[Error, User]]` 转换为 `Either[Error, NonEmptyList[User]]`?

问题描述 投票:0回答:1

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

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

val target: Either[Error, NonEmptyList[User]] = howToConvert(data)
scala list scala-cats either
1个回答
6
投票

通常,当您想要将类型构造函数翻过来时,您可能正在寻找

sequence

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

scala> import cats.data.NonEmptyList, cats.syntax.all._
import cats.data.NonEmptyList
import cats.syntax.all._

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)

通常,当您需要使用

sequence
时,这表明您应该在代码中稍早一点使用
traverse
而不是
map
,即

scala> val data: NonEmptyList[User] = NonEmptyList.of(2, 3, 4)
val data: cats.data.NonEmptyList[User] = NonEmptyList(2, 3, 4)

scala> data.traverse(user => if (user % 2 == 0) Right(user) else Left("error1"))
val res3: scala.util.Either[String,cats.data.NonEmptyList[User]] = Left(error1)

只有当由于某种原因你使用的 scala 版本早于 2.13 时,下面的解释才有意义。

如果您在 Scala >= 2.11.9 中打开了

-Ypartial-unification
,您可以让编译器推断一切:

data.sequence

否则:

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

或者如果您有 type lambda 插件:

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

或者如果您没有该插件,但您不喜欢输入别名:

data.sequence[({type L[A] = Either[Error, A]})#L, User]
© www.soinside.com 2019 - 2024. All rights reserved.