使用无标记最终将错误更改为错误的优雅方法

Elegant way to change either to error with tagless final

我经常做这样的事情:

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

简而言之,这意味着如果 Eitherleft 则使用 raiseError,如果它是 right 则只是 return 值。

有没有更方便的方法"unwrap"Either?

使用来自 cats Either 语法的 liftTomaybeUser.liftTo[F].

您也可以使用 rethrow,来自 cats MonadError 语法,直接在 F[Either[Error, User]]:

def doSomething[F[_]: Sync]: F[User] = validate[F]("Name").rethrow

请注意,您实际上不需要 Sync - MonadError[*[_], Throwable] 就足够了。