You can use only one type of monad in for understanding, since it is just syntactic sugar for flatMap
and map
.
If you have a monad stack (e.g. Future[Option[A]]
), you can use a monad transformer, but this is not applicable here.
: Option
Try
Option
Try
Either[String, A]
.
def tryToEither[L, R](t: Try[R])(left: Throwable => L): Either[L, R] =
t.transform(r => Success(Right(r)), th => Success(Left(left(th)))).get
def edit(id: Int, userId: Int, text: String) = {
val updatedPost = for {
p1 <- find(id).toRight("Not found").right
p2 <- tryToEither(permitted(p1, userId))(_ => "Not Authorized").right
} yield p2.copy(text = text)
updatedPost match {
case Left(msg) => println(msg)
case Right(_) => println("success")
}
}
String
, Either[Error, A]
.
sealed trait Error extends Exception
case class PostNotFound(userId: Int) extends Error
case object NotAuthorized extends Error