使用无标记最终将错误更改为错误的优雅方法
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
简而言之,这意味着如果 Either
是 left
则使用 raiseError
,如果它是 right
则只是 return 值。
有没有更方便的方法"unwrap"Either
?
使用来自 cats Either
语法的 liftTo
:maybeUser.liftTo[F]
.
您也可以使用 rethrow
,来自 cats MonadError
语法,直接在 F[Either[Error, User]]
:
def doSomething[F[_]: Sync]: F[User] = validate[F]("Name").rethrow
请注意,您实际上不需要 Sync
- MonadError[*[_], Throwable]
就足够了。
我经常做这样的事情:
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
则只是 return 值。
有没有更方便的方法"unwrap"Either
?
使用来自 cats Either
语法的 liftTo
:maybeUser.liftTo[F]
.
您也可以使用 rethrow
,来自 cats MonadError
语法,直接在 F[Either[Error, User]]
:
def doSomething[F[_]: Sync]: F[User] = validate[F]("Name").rethrow
请注意,您实际上不需要 Sync
- MonadError[*[_], Throwable]
就足够了。