5

I often do things like:

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

In nutshell, it means if Either is left then use raiseError, if it's right just return value.

Is there a more convenient way to "unwrap" Either?

Krzysztof Atłasik
  • 21,985
  • 6
  • 54
  • 76
Stu Redman
  • 262
  • 2
  • 9

1 Answers1

5

Use liftTo from the cats Either syntax: maybeUser.liftTo[F].

You can also use rethrow, from the cats MonadError syntax, directly on F[Either[Error, User]]:

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

Note that you don't actually need Sync - MonadError[*[_], Throwable] is sufficient.

Ben
  • 1,414
  • 2
  • 13
  • 18