From 522e12919597f989e3e74ac3d308a7c902a761a3 Mon Sep 17 00:00:00 2001 From: danicheg Date: Sat, 15 Jun 2024 14:39:41 +0400 Subject: [PATCH 1/9] Add mapOrKeepIn to F[Option[A]] syntax --- shared/src/main/scala/mouse/foption.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared/src/main/scala/mouse/foption.scala b/shared/src/main/scala/mouse/foption.scala index 781d0a7..2b127b2 100644 --- a/shared/src/main/scala/mouse/foption.scala +++ b/shared/src/main/scala/mouse/foption.scala @@ -103,6 +103,9 @@ final class FOptionOps[F[_], A](private val foa: F[Option[A]]) extends AnyVal { def mapIn[B](f: A => B)(implicit F: Functor[F]): F[Option[B]] = F.map(foa)(_.map(f)) + def mapOrKeepIn[B >: A](pf: PartialFunction[A, B])(implicit F: Functor[F]): F[Option[B]] = + F.map(foa)(_.map(a => pf.applyOrElse(a, identity[B]))) + def asIn[B](b: => B)(implicit F: Functor[F]): F[Option[B]] = mapIn(_ => b) From f181b4d7dc5829bf785294f95ef806760eb66520 Mon Sep 17 00:00:00 2001 From: danicheg Date: Sat, 15 Jun 2024 14:47:08 +0400 Subject: [PATCH 2/9] Add flatMapOrKeepIn to F[Option[A]] syntax --- shared/src/main/scala/mouse/foption.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared/src/main/scala/mouse/foption.scala b/shared/src/main/scala/mouse/foption.scala index 2b127b2..4a1d3aa 100644 --- a/shared/src/main/scala/mouse/foption.scala +++ b/shared/src/main/scala/mouse/foption.scala @@ -70,6 +70,9 @@ final class FOptionOps[F[_], A](private val foa: F[Option[A]]) extends AnyVal { def flatMapIn[B](f: A => Option[B])(implicit F: Functor[F]): F[Option[B]] = F.map(foa)(_.flatMap(f)) + def flatMapOrKeepIn[B >: A](pfa: PartialFunction[A, Option[B]])(implicit F: Monad[F]): F[Option[B]] = + F.map(foa)(_.flatMap(a => pfa.applyOrElse(a, Option[B](_)))) + def flatMapF[B](f: A => F[Option[B]])(implicit F: Monad[F]): F[Option[B]] = F.flatMap(foa)(_.fold(F.pure(Option.empty[B]))(f)) From 328c1d5fa5ebc03f4ebdacce27c723f4f2cfd05f Mon Sep 17 00:00:00 2001 From: danicheg Date: Sat, 15 Jun 2024 14:51:17 +0400 Subject: [PATCH 3/9] Add a test for FOptionSyntax.mapOrKeepIn --- shared/src/test/scala/mouse/FOptionSyntaxTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shared/src/test/scala/mouse/FOptionSyntaxTest.scala b/shared/src/test/scala/mouse/FOptionSyntaxTest.scala index d640bb1..e4e25b3 100644 --- a/shared/src/test/scala/mouse/FOptionSyntaxTest.scala +++ b/shared/src/test/scala/mouse/FOptionSyntaxTest.scala @@ -125,6 +125,12 @@ class FOptionSyntaxTest extends MouseSuite { assertEquals(List(Option.empty[Int]).mapIn(_ + 1), List(Option.empty[Int])) } + test("FOptionSyntax.mapOrKeepIn") { + assertEquals(List(Option(1)).mapOrKeepIn { case 1 => 2 }, List(Option(2))) + assertEquals(List(Option(1)).mapOrKeepIn { case 2 => 1 }, List(Option(1))) + assertEquals(List(Option.empty[Int]).mapOrKeepIn { case 1 => 2 }, List(Option.empty[Int])) + } + test("FOptionSyntax.asIn") { assertEquals(List(Option(1)).asIn(1), List(Option(1))) assertEquals(List(Option.empty[Int]).asIn(1), List(Option.empty[Int])) From bf8eab429f56af57f6f8cef389643084103375d6 Mon Sep 17 00:00:00 2001 From: danicheg Date: Sat, 15 Jun 2024 14:53:50 +0400 Subject: [PATCH 4/9] Add a test for FOptionSyntax.flatMapOrKeepIn --- shared/src/test/scala/mouse/FOptionSyntaxTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shared/src/test/scala/mouse/FOptionSyntaxTest.scala b/shared/src/test/scala/mouse/FOptionSyntaxTest.scala index e4e25b3..b670dd7 100644 --- a/shared/src/test/scala/mouse/FOptionSyntaxTest.scala +++ b/shared/src/test/scala/mouse/FOptionSyntaxTest.scala @@ -67,6 +67,12 @@ class FOptionSyntaxTest extends MouseSuite { assertEquals(List(Option.empty[Int]).flatMapIn(a => Option(a * 2)), List(Option.empty[Int])) } + test("FOptionSyntax.flatMapOrKeepIn") { + assertEquals(List(Option(1)).flatMapOrKeepIn { case 1 => Option(2) }, List(Option(2))) + assertEquals(List(Option(1)).flatMapOrKeepIn { case 2 => Option(1) }, List(Option(1))) + assertEquals(List(Option.empty[Int]).flatMapOrKeepIn { case 1 => Option(2) }, List(Option.empty[Int])) + } + test("FOptionSyntax.flatMapF") { assertEquals(List(Option(1)).flatMapF(a => List(Option(a * 2))), List(Option(2))) assertEquals(List(Option.empty[Int]).flatMapF(a => List(Option(a * 2))), List(Option.empty[Int])) From 60a6250e87019f4104f994ff9f369e7d9d938915 Mon Sep 17 00:00:00 2001 From: danicheg Date: Sat, 15 Jun 2024 14:58:26 +0400 Subject: [PATCH 5/9] Add mapOrKeepIn to F[Either[L,R]] syntax --- shared/src/main/scala/mouse/feither.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared/src/main/scala/mouse/feither.scala b/shared/src/main/scala/mouse/feither.scala index e2f9f54..cbc0622 100644 --- a/shared/src/main/scala/mouse/feither.scala +++ b/shared/src/main/scala/mouse/feither.scala @@ -117,6 +117,9 @@ final class FEitherOps[F[_], L, R](private val felr: F[Either[L, R]]) extends An def mapIn[A](f: R => A)(implicit F: Functor[F]): F[Either[L, A]] = F.map(felr)(_.map(f)) + def mapOrKeepIn[A >: R](pf: PartialFunction[R, A])(implicit F: Functor[F]): F[Either[L, A]] = + F.map(felr)(_.map(a => pf.applyOrElse(a, identity[A]))) + def asIn[B](b: => B)(implicit F: Functor[F]): F[Either[L, B]] = mapIn(_ => b) From daf1d9d959cc07d8815dcde9adfb7c027a296b04 Mon Sep 17 00:00:00 2001 From: danicheg Date: Sat, 15 Jun 2024 15:05:03 +0400 Subject: [PATCH 6/9] Weaken the constraint for FOptionOps#flatMapOrKeepIn --- shared/src/main/scala/mouse/foption.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/main/scala/mouse/foption.scala b/shared/src/main/scala/mouse/foption.scala index 4a1d3aa..0a0dcfa 100644 --- a/shared/src/main/scala/mouse/foption.scala +++ b/shared/src/main/scala/mouse/foption.scala @@ -70,7 +70,7 @@ final class FOptionOps[F[_], A](private val foa: F[Option[A]]) extends AnyVal { def flatMapIn[B](f: A => Option[B])(implicit F: Functor[F]): F[Option[B]] = F.map(foa)(_.flatMap(f)) - def flatMapOrKeepIn[B >: A](pfa: PartialFunction[A, Option[B]])(implicit F: Monad[F]): F[Option[B]] = + def flatMapOrKeepIn[B >: A](pfa: PartialFunction[A, Option[B]])(implicit F: Functor[F]): F[Option[B]] = F.map(foa)(_.flatMap(a => pfa.applyOrElse(a, Option[B](_)))) def flatMapF[B](f: A => F[Option[B]])(implicit F: Monad[F]): F[Option[B]] = From 8ea54a93c282fad0f74ca4f3dfb3477fad466ed6 Mon Sep 17 00:00:00 2001 From: danicheg Date: Sat, 15 Jun 2024 15:12:20 +0400 Subject: [PATCH 7/9] Add flatMapOrKeepIn to F[Either[L,R]] syntax --- shared/src/main/scala/mouse/feither.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared/src/main/scala/mouse/feither.scala b/shared/src/main/scala/mouse/feither.scala index cbc0622..b718fad 100644 --- a/shared/src/main/scala/mouse/feither.scala +++ b/shared/src/main/scala/mouse/feither.scala @@ -48,6 +48,9 @@ final class FEitherOps[F[_], L, R](private val felr: F[Either[L, R]]) extends An def flatMapIn[A >: L, B](f: R => Either[A, B])(implicit F: Functor[F]): F[Either[A, B]] = F.map(felr)(_.flatMap(f)) + def flatMapOrKeepIn[A >: L, B >: R](pfa: PartialFunction[R, Either[A, B]])(implicit F: Functor[F]): F[Either[A, B]] = + F.map(felr)(_.flatMap(a => pfa.applyOrElse(a, Right[A, B](_)))) + def flatMapF[A >: L, B](f: R => F[Either[A, B]])(implicit F: Monad[F]): F[Either[A, B]] = F.flatMap(felr) { case l @ Left(_) => F.pure(l.asInstanceOf[Left[A, B]]) From 3797bf1acad3e1114123985570f8a3a0fcc68711 Mon Sep 17 00:00:00 2001 From: danicheg Date: Sat, 15 Jun 2024 15:14:50 +0400 Subject: [PATCH 8/9] Add a test for FEitherSyntax.mapOrKeepIn --- shared/src/test/scala/mouse/FEitherSyntaxTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shared/src/test/scala/mouse/FEitherSyntaxTest.scala b/shared/src/test/scala/mouse/FEitherSyntaxTest.scala index 29b2144..d7d36bd 100644 --- a/shared/src/test/scala/mouse/FEitherSyntaxTest.scala +++ b/shared/src/test/scala/mouse/FEitherSyntaxTest.scala @@ -133,6 +133,12 @@ class FEitherSyntaxTest extends MouseSuite { assertEquals(leftValue.mapIn(_ * 2), leftValue) } + test("FEitherSyntax.mapOrKeepIn") { + assertEquals(rightValue.mapOrKeepIn { case 42 => 84 }, List(84.asRight[String])) + assertEquals(rightValue.mapOrKeepIn { case 84 => 42 }, rightValue) + assertEquals(leftValue.mapOrKeepIn { case 42 => 84 }, leftValue) + } + test("FEitherSyntax.asIn") { assertEquals(rightValue.asIn(2), List(2.asRight[String])) assertEquals(leftValue.asIn(2), leftValue) From 44806a0b252d19b9139aff65d0d411d9e4ed1863 Mon Sep 17 00:00:00 2001 From: danicheg Date: Sat, 15 Jun 2024 15:18:49 +0400 Subject: [PATCH 9/9] Add a test for FEitherSyntax.flatMapOrKeepIn --- shared/src/test/scala/mouse/FEitherSyntaxTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shared/src/test/scala/mouse/FEitherSyntaxTest.scala b/shared/src/test/scala/mouse/FEitherSyntaxTest.scala index d7d36bd..ea79008 100644 --- a/shared/src/test/scala/mouse/FEitherSyntaxTest.scala +++ b/shared/src/test/scala/mouse/FEitherSyntaxTest.scala @@ -45,6 +45,12 @@ class FEitherSyntaxTest extends MouseSuite { assertEquals(leftValue.flatMapIn(i => (i * 2).asRight[String]), leftValue) } + test("FEitherSyntax.flatMapOrKeepIn") { + assertEquals(rightValue.flatMapOrKeepIn { case 42 => 84.asRight[String] }, List(84.asRight[String])) + assertEquals(rightValue.flatMapOrKeepIn { case 84 => 42.asRight[String] }, rightValue) + assertEquals(leftValue.flatMapOrKeepIn { case 42 => 84.asRight[String] }, leftValue) + } + test("FEitherSyntax.leftWidenIn") { val initial: Option[Either[List[Int], String]] = Option(List(1).asLeft[String]) val expected: Option[Either[Seq[Int], String]] = Option(Seq(1).asLeft[String])