Skip to content

Commit

Permalink
attemptTap (#3459)
Browse files Browse the repository at this point in the history
* attemptTap

* add to typeclass

* Add attemptTap example

* Fix doc
  • Loading branch information
Raas Ahsan authored Jul 5, 2020
1 parent 714f0da commit b74f104
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
27 changes: 27 additions & 0 deletions core/src/main/scala/cats/MonadError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,33 @@ trait MonadError[F[_], E] extends ApplicativeError[F, E] with Monad[F] {
def redeemWith[A, B](fa: F[A])(recover: E => F[B], bind: A => F[B]): F[B] =
flatMap(attempt(fa))(_.fold(recover, bind))

/**
* Reifies the value or error of the source and performs an effect on the result,
* then recovers the original value or error back into `F`.
*
* Note that if the effect returned by `f` fails, the resulting effect will fail too.
*
* Alias for `fa.attempt.flatTap(f).rethrow` for convenience.
*
* Example:
* {{{
* scala> import cats.implicits._
* scala> import scala.util.{Try, Success, Failure}
*
* scala> def checkError(result: Either[Throwable, Int]): Try[String] = result.fold(_ => Failure(new java.lang.Exception), _ => Success("success"))
*
* scala> val a: Try[Int] = Failure(new Throwable("failed"))
* scala> a.attemptTap(checkError)
* res0: scala.util.Try[Int] = Failure(java.lang.Exception)
*
* scala> val b: Try[Int] = Success(1)
* scala> b.attemptTap(checkError)
* res1: scala.util.Try[Int] = Success(1)
* }}}
*/
def attemptTap[A, B](fa: F[A])(f: Either[E, A] => F[B]): F[A] =
rethrow(flatTap(attempt(fa))(f))

override def adaptError[A](fa: F[A])(pf: PartialFunction[E, E]): F[A] =
recoverWith(fa)(pf.andThen(raiseError[A] _))
}
Expand Down
3 changes: 3 additions & 0 deletions core/src/main/scala/cats/syntax/monadError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ final class MonadErrorOps[F[_], E, A](private val fa: F[A]) extends AnyVal {

def redeemWith[B](recover: E => F[B], bind: A => F[B])(implicit F: MonadError[F, E]): F[B] =
F.redeemWith[A, B](fa)(recover, bind)

def attemptTap[B](f: Either[E, A] => F[B])(implicit F: MonadError[F, E]): F[A] =
F.attemptTap(fa)(f)
}

final class MonadErrorRethrowOps[F[_], E, A](private val fea: F[Either[E, A]]) extends AnyVal {
Expand Down

0 comments on commit b74f104

Please sign in to comment.