如何将 `Either[Error, Option[Either[Error, Account]]]` 转换为 `Either[Error, Option[Account]]` with typelevel cats?

How to turn `Either[Error, Option[Either[Error, Account]]]` to `Either[Error, Option[Account]]` with typelevel cats?

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

来自

val data = Either[Error, Option[Either[Error, Account]]]

val target: Either[Error, Option[Account]] = howToConvert(data)

如果有任何 Error 发生,结果将是 Left(error),第一个出现的错误。

我现在可以用:

data match {
  case Left(e) => Left(e)
  case Right(Some(Right(y))) => Right(Some(y))
  case Right(Some(Left(e))) => Left(e)
  case Right(None) => Right(None)
}

但我正在寻找一些简单的方法

这是一种 "easy" 方式,它只假定右偏 Either (Scala 2.12) 或猫的语法

val target: Either[Error, Option[Account]] =
    data.flatMap(_.map(_.map(Some(_))).getOrElse(Right(None)))

最简单的方法是sequence里面的Option,这样你就得到一个Either[Error, Either[Error, Option[Account]]],然后把它压平。 使用 cat 语法,这真的很简单:

import cats.implicits._

val target: Either[Error, Option[Account]] =
  data.flatMap(_.sequence)

澄清一下,sequence 转换类型构造函数 "inside out",意味着内部 Option[Either[Error, Account]] 转换为 Either[Error, Option[Account]]