我正在使用cats,想知道如何用它来转换数据:
val data = NonEmptyList[Either[Error, User]]
到
val target: Either[Error, NonEmptyList[User]] = howToConvert(data)
通常,当您想要将类型构造函数翻过来时,您可能正在寻找
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]