From f6a44a54b2ebb2501ca00199f492303e443e2e73 Mon Sep 17 00:00:00 2001 From: Igor Fedorov Date: Mon, 8 Apr 2024 18:27:21 +0300 Subject: [PATCH 1/3] feature/add fold* to EitherOps --- .../src/test/scala/tofu/syntax/FEitherSuite.scala | 14 ++++++++++++++ .../src/main/scala/tofu/syntax/feither.scala | 11 +++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) 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..9540d8250 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,20 @@ 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) + } + } + "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..7245c0848 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) } @@ -168,10 +176,9 @@ object feither { productF(eb).flatMap(_.traverse(f.tupled)) } - def mergeF[A >: R](implicit ev: L <:< A, F: Functor[F]): F[A] = { + def mergeF[A >: R](implicit ev: L <:< A, F: Functor[F]): F[A] = { e.map(_.fold(ev, identity(_: A))) } - def reRaise(implicit R: FindRaise.Aux[L, F], M: Monad[F]): F[R] = FindRaise.unwrap(R).reRaise(e) } From 4482ffd1fa267de23d94d525a2ef01028624f77d Mon Sep 17 00:00:00 2001 From: Igor Fedorov Date: Mon, 8 Apr 2024 18:29:56 +0300 Subject: [PATCH 2/3] feature/add fold* to EitherOps --- modules/kernel/src/main/scala/tofu/syntax/feither.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/kernel/src/main/scala/tofu/syntax/feither.scala b/modules/kernel/src/main/scala/tofu/syntax/feither.scala index 7245c0848..c0960ef3b 100644 --- a/modules/kernel/src/main/scala/tofu/syntax/feither.scala +++ b/modules/kernel/src/main/scala/tofu/syntax/feither.scala @@ -106,6 +106,7 @@ object feither { def foldIn[C](lMap: L => C, rMap: R => C)(implicit F: Functor[F]): F[C] = { e.map(_.fold(lMap, rMap)) + e.map(_.fold(lMap, rMap)) } def foldF[C](lMap: L => F[C], rMap: R => F[C])(implicit F: Monad[F]): F[C] = { @@ -176,9 +177,10 @@ object feither { productF(eb).flatMap(_.traverse(f.tupled)) } - def mergeF[A >: R](implicit ev: L <:< A, F: Functor[F]): F[A] = { + def mergeF[A >: R](implicit ev: L <:< A, F: Functor[F]): F[A] = { e.map(_.fold(ev, identity(_: A))) } + def reRaise(implicit R: FindRaise.Aux[L, F], M: Monad[F]): F[R] = FindRaise.unwrap(R).reRaise(e) } From 91a2f7b97bf3b29a6c03b1425f29b80f764e8097 Mon Sep 17 00:00:00 2001 From: Igor Fedorov Date: Mon, 8 Apr 2024 20:55:06 +0300 Subject: [PATCH 3/3] feature/add test case with None --- .../ce2/src/test/scala/tofu/syntax/FEitherSuite.scala | 11 +++++++++++ .../kernel/src/main/scala/tofu/syntax/feither.scala | 1 - 2 files changed, 11 insertions(+), 1 deletion(-) 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 9540d8250..615eebaca 100644 --- a/modules/core/ce2/src/test/scala/tofu/syntax/FEitherSuite.scala +++ b/modules/core/ce2/src/test/scala/tofu/syntax/FEitherSuite.scala @@ -418,6 +418,17 @@ class FEitherSuite extends AnyWordSpec with Matchers { 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 { diff --git a/modules/kernel/src/main/scala/tofu/syntax/feither.scala b/modules/kernel/src/main/scala/tofu/syntax/feither.scala index c0960ef3b..2bc11c8c2 100644 --- a/modules/kernel/src/main/scala/tofu/syntax/feither.scala +++ b/modules/kernel/src/main/scala/tofu/syntax/feither.scala @@ -106,7 +106,6 @@ object feither { def foldIn[C](lMap: L => C, rMap: R => C)(implicit F: Functor[F]): F[C] = { e.map(_.fold(lMap, rMap)) - e.map(_.fold(lMap, rMap)) } def foldF[C](lMap: L => F[C], rMap: R => F[C])(implicit F: Monad[F]): F[C] = {