Skip to content

Commit 6de31de

Browse files
authored
Merge pull request #4293 from gemini/md-eithert-biSemiflatTap
2 parents 46b15ae + bde7b16 commit 6de31de

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

core/src/main/scala/cats/data/EitherT.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,14 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) {
513513
def leftSemiflatTap[C](f: A => F[C])(implicit F: Monad[F]): EitherT[F, A, B] =
514514
leftSemiflatMap(a => F.as(f(a), a))
515515

516+
def biSemiflatTap[C, D](fa: A => F[C], fb: B => F[D])(implicit F: FlatMap[F]): EitherT[F, A, B] =
517+
EitherT(F.flatMap(value) {
518+
case l @ Left(a) =>
519+
F.as(fa(a), l)
520+
case r @ Right(b) =>
521+
F.as(fb(b), r)
522+
})
523+
516524
def compare(that: EitherT[F, A, B])(implicit o: Order[F[Either[A, B]]]): Int =
517525
o.compare(value, that.value)
518526

tests/shared/src/test/scala/cats/tests/EitherTSuite.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,33 @@ class EitherTSuite extends CatsSuite {
655655
}
656656
}
657657

658+
test("biSemiflatTap does not change the return value") {
659+
type TestEffect[A] = State[List[Int], A]
660+
forAll {
661+
(eithert: EitherT[TestEffect, String, Int],
662+
fa: String => TestEffect[Int],
663+
fb: Int => TestEffect[Int],
664+
initial: List[Int]
665+
) =>
666+
assert(eithert.biSemiflatTap(v => fa(v), v => fb(v)).value.runA(initial) === eithert.value.runA(initial))
667+
}
668+
}
669+
670+
test("biSemiflatTap consistent with leftSemiflatTap and semiFlatTap") {
671+
type TestEffect[A] = State[List[Int], A]
672+
forAll {
673+
(eithert: EitherT[TestEffect, String, Int],
674+
fa: String => TestEffect[Int],
675+
fb: Int => TestEffect[Int],
676+
initial: List[Int]
677+
) =>
678+
assert(
679+
eithert.biSemiflatTap(fa, fb).value.runS(initial) ===
680+
eithert.leftSemiflatTap(fa).semiflatTap(fb).value.runS(initial)
681+
)
682+
}
683+
}
684+
658685
test("biSemiflatMap consistent with leftSemiflatMap and semiFlatmap") {
659686
forAll { (eithert: EitherT[List, String, Int], fa: String => List[Int], fb: Int => List[String]) =>
660687
assert(eithert.biSemiflatMap(fa, fb) === (eithert.leftSemiflatMap(fa).semiflatMap(fb)))

0 commit comments

Comments
 (0)