我经常做类似的事情:
import cats.effect.Sync
import cats.implicits._
case class User(name: String)
case object Error extends Exception
def validate[F[_]: Sync](name: String): F[Either[Error, User]] = Sync[F].pure(User(name).asRight)
def doSomething[F[_]: Sync]: F[User] = for {
maybeUser <- validate("Name")
user <- maybeUser.fold(Sync[F].raiseError[User](_), Sync[F].pure(_))
} yield user
简而言之,它表示如果Either
为left
,则使用raiseError
,如果它是right
仅返回值。
是否有更方便的方法来“展开” Either
?
使用猫liftTo
语法中的Either
:maybeUser.liftTo[F]
。
您还可以直接在rethrow
上使用cats MonadError
语法中的F[Either[Error, User]]
:
def doSomething[F[_]: Sync]: F[User] = validate[F]("Name").rethrow
请注意,您实际上并不需要Sync
-MonadError[*[_], Throwable]
就足够了。