From 1c3699f8baa12c321ef0af48857c8861f9ee58ec Mon Sep 17 00:00:00 2001 From: Igor Fedorov Date: Tue, 9 Apr 2024 12:41:25 +0300 Subject: [PATCH] feature/add fold* to EitherOps (#1234) * feature/add fold* to EitherOps * feature/add fold* to EitherOps * feature/add test case with None --------- Co-authored-by: Igor Fedorov --- .../test/scala/tofu/syntax/FEitherSuite.scala | 25 +++++++++++++++++++ .../src/main/scala/tofu/syntax/feither.scala | 8 ++++++ 2 files changed, 33 insertions(+) diff --git a/modules/core/ce2/src/test/scala/tofu/syntax/FEitherSuite.scala b/modules/core/ce2/src/test/scala/tofu/syntax/FEitherSuite.scala index 283ca7a0d..615eebaca 100644 --- a/modules/core/ce2/src/test/scala/tofu/syntax/FEitherSuite.scala +++ b/modules/core/ce2/src/test/scala/tofu/syntax/FEitherSuite.scala @@ -406,6 +406,31 @@ class FEitherSuite extends AnyWordSpec with Matchers { } } + "EitherFOps#foldIn" should { + "map left or right to C" in { + defaultRight.foldIn(_.length, c => c * c) mustBe Some(16) + defaultLeft.foldIn(c => c * c, _.length) mustBe Some(16) + } + } + + "EitherFOps#foldF" should { + "map left or right to F[C]" in { + defaultRight.foldF(s => Some(s.length), c => Some(c * c)) mustBe Some(16) + defaultLeft.foldF(c => Some(c * c), s => Some(s.length)) mustBe Some(16) + } + + "fold to None" in { + defaultRight.foldF(_ => None, _ => None) mustBe None + defaultLeft.foldF(_ => None, _ => None) mustBe None + } + + "fold on None" in { + val emptyF = Option.empty[Either[String, Int]] + emptyF.foldF(_ => None, _ => None) mustBe None + emptyF.foldIn(_ => 1, _ => 1) mustBe None + } + } + "EitherFOps#ensure" should { "return None" in { diff --git a/modules/kernel/src/main/scala/tofu/syntax/feither.scala b/modules/kernel/src/main/scala/tofu/syntax/feither.scala index 698cca68e..2bc11c8c2 100644 --- a/modules/kernel/src/main/scala/tofu/syntax/feither.scala +++ b/modules/kernel/src/main/scala/tofu/syntax/feither.scala @@ -104,6 +104,14 @@ object feither { e.flatMap(_.wideLeft[L1].flatTraverse(f)) } + def foldIn[C](lMap: L => C, rMap: R => C)(implicit F: Functor[F]): F[C] = { + e.map(_.fold(lMap, rMap)) + } + + def foldF[C](lMap: L => F[C], rMap: R => F[C])(implicit F: Monad[F]): F[C] = { + e.flatMap(_.fold(lMap, rMap)) + } + def swapF(implicit F: Functor[F]): F[Either[R, L]] = { F.map(e)(_.swap) }