Skip to content

Commit b6ba437

Browse files
committed
add attemptCase to ApplicativeErrorOps
1 parent 4f92efe commit b6ba437

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

core/src/main/scala/cats/syntax/applicativeError.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package syntax
33

44
import cats.data.Validated.{Invalid, Valid}
55
import cats.data.{EitherT, Validated}
6+
import either._
7+
8+
import scala.reflect.ClassTag
69

710
trait ApplicativeErrorSyntax {
811
implicit final def catsSyntaxApplicativeErrorId[E](e: E): ApplicativeErrorIdOps[E] =
@@ -83,6 +86,9 @@ final class ApplicativeErrorOps[F[_], E, A](private val fa: F[A]) extends AnyVal
8386
def attempt(implicit F: ApplicativeError[F, E]): F[Either[E, A]] =
8487
F.attempt(fa)
8588

89+
def attemptCase[EE](implicit F: ApplicativeError[F, E], tag: ClassTag[EE], ev: EE <:< E): F[Either[EE, A]] =
90+
F.recover(F.map(fa)(_.asRight[EE])) { case e: EE => e.asLeft[A] }
91+
8692
def attemptT(implicit F: ApplicativeError[F, E]): EitherT[F, E, A] =
8793
F.attemptT(fa)
8894

tests/src/test/scala/cats/tests/ApplicativeErrorSuite.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,21 @@ class ApplicativeErrorSuite extends CatsSuite {
2323
failed.attempt should ===(Option(Left(())))
2424
}
2525

26+
test("attemptCase[EE] syntax creates an F[Either[EE, A]]") {
27+
trait Err
28+
case class ErrA() extends Err
29+
case class ErrB() extends Err
30+
31+
implicit val eqForErr: Eq[Err] = Eq.fromUniversalEquals[Err]
32+
implicit val eqForErrA: Eq[ErrA] = Eq.fromUniversalEquals[ErrA]
33+
implicit val eqForErrB: Eq[ErrB] = Eq.fromUniversalEquals[ErrB]
34+
35+
val failed: Either[Err, Int] = ErrA().raiseError[Either[Err, ?], Int]
36+
37+
failed.attemptCase[ErrA] should ===(ErrA().asLeft[Int].asRight[Err])
38+
failed.attemptCase[ErrB] should ===(Either.left[Err, Either[ErrB, Int]](ErrA()))
39+
}
40+
2641
test("attemptT syntax creates an EitherT") {
2742
failed.attemptT should ===(EitherT[Option, Unit, Int](Option(Left(()))))
2843
}

0 commit comments

Comments
 (0)