From 1120edd77e24125cc9f5a9819f7f27d99e82feb2 Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Mon, 16 Dec 2024 19:36:03 +0530 Subject: [PATCH 1/2] Use `Exit.succeed` in more places --- core/shared/src/main/scala/zio/ZIO.scala | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/core/shared/src/main/scala/zio/ZIO.scala b/core/shared/src/main/scala/zio/ZIO.scala index d3ce4570972a..8d4c90563e19 100644 --- a/core/shared/src/main/scala/zio/ZIO.scala +++ b/core/shared/src/main/scala/zio/ZIO.scala @@ -188,7 +188,7 @@ sealed trait ZIO[-R, +E, +A] * Maps the success value of this effect to the specified constant value. */ def as[B](b: => B)(implicit trace: Trace): ZIO[R, E, B] = - self.map(_ => b) + self.flatMap(_ => Exit.succeed(b)) /** * Maps the success value of this effect to a left value. @@ -684,14 +684,14 @@ sealed trait ZIO[-R, +E, +A] * function passed to `fold`. */ def fold[B](failure: E => B, success: A => B)(implicit ev: CanFail[E], trace: Trace): URIO[R, B] = - foldZIO(e => ZIO.succeed(failure(e)), a => ZIO.succeed(success(a))) + foldZIO(e => Exit.succeed(failure(e)), a => Exit.succeed(success(a))) /** * A more powerful version of `fold` that allows recovering from any kind of * failure except external interruption. */ def foldCause[B](failure: Cause[E] => B, success: A => B)(implicit trace: Trace): URIO[R, B] = - foldCauseZIO(c => ZIO.succeed(failure(c)), a => ZIO.succeed(success(a))) + foldCauseZIO(c => Exit.succeed(failure(c)), a => Exit.succeed(success(a))) /** * A more powerful version of `foldZIO` that allows recovering from any kind @@ -970,7 +970,7 @@ sealed trait ZIO[-R, +E, +A] * Returns an effect whose success is mapped by the specified `f` function. */ def map[B](f: A => B)(implicit trace: Trace): ZIO[R, E, B] = - flatMap(a => ZIO.succeed(f(a))) + flatMap(a => Exit.succeed(f(a))) /** * Returns an effect whose success is mapped by the specified side effecting @@ -984,7 +984,7 @@ sealed trait ZIO[-R, +E, +A] * the specified pair of functions, `f` and `g`. */ def mapBoth[E2, B](f: E => E2, g: A => B)(implicit ev: CanFail[E], trace: Trace): ZIO[R, E2, B] = - foldZIO(e => Exit.fail(f(e)), a => ZIO.succeed(g(a))) + foldZIO(e => Exit.fail(f(e)), a => Exit.succeed(g(a))) /** * Returns an effect with its error channel mapped using the specified @@ -3094,7 +3094,7 @@ object ZIO extends ZIOCompanionPlatformSpecific with ZIOCompanionVersionSpecific * For effectful conditionals, see [[ZIO.ifZIO]] */ def cond[E, A](predicate: => Boolean, result: => A, error: => E)(implicit trace: Trace): IO[E, A] = - ZIO.suspendSucceed(if (predicate) ZIO.succeed(result) else ZIO.fail(error)) + ZIO.suspendSucceed(if (predicate) Exit.succeed(result) else ZIO.fail(error)) /** * Uses the current config provider to load the specified config, or fail with @@ -5609,7 +5609,7 @@ object ZIO extends ZIOCompanionPlatformSpecific with ZIOCompanionVersionSpecific final class EnvironmentWithPartiallyApplied[R](private val dummy: Boolean = true) extends AnyVal { def apply[A](f: ZEnvironment[R] => A)(implicit trace: Trace): URIO[R, A] = - ZIO.environmentWithZIO(env => ZIO.succeed(f(env))) + ZIO.environmentWithZIO(env => Exit.succeed(f(env))) } final class EnvironmentWithZIOPartiallyApplied[R](private val dummy: Boolean = true) extends AnyVal { @@ -6145,7 +6145,7 @@ object ZIO extends ZIOCompanionPlatformSpecific with ZIOCompanionVersionSpecific else MakeUninterruptible def make(implicit trace: Trace): ZIO[Any, Nothing, InterruptibilityRestorer] = - ZIO.checkInterruptible(status => ZIO.succeed(InterruptibilityRestorer(status))) + ZIO.checkInterruptible(status => Exit.succeed(InterruptibilityRestorer(status))) case object MakeInterruptible extends InterruptibilityRestorer { def apply[R, E, A](effect: => ZIO[R, E, A])(implicit trace: Trace): ZIO[R, E, A] = @@ -6435,14 +6435,6 @@ sealed trait Exit[+E, +A] extends ZIO[Any, E, A] { self => final def flattenExit[E1 >: E, B](implicit ev: A <:< Exit[E1, B]): Exit[E1, B] = Exit.flatten(self.mapExit(ev)) - /** - * Folds over the failure value or the success value to yield an effect that - * does not fail, but succeeds with the value returned by the left or right - * function passed to `fold`. - */ - override final def fold[B](failure: E => B, success: A => B)(implicit ev: CanFail[E], trace: Trace): UIO[B] = - foldZIO(e => Exit.succeed(failure(e)), a => Exit.succeed(success(a))) - /** * A more powerful version of `fold` that allows recovering from any kind of * failure except external interruption. From 72277d6f862876317002ba349fc0462ef261c2bc Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Tue, 17 Dec 2024 06:09:10 +0530 Subject: [PATCH 2/2] Add tests for methods on Exit --- .../shared/src/test/scala/zio/ZIOSpec.scala | 22 +++++++++++++++++++ core/shared/src/main/scala/zio/ZIO.scala | 10 ++------- project/MimaSettings.scala | 4 +++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/core-tests/shared/src/test/scala/zio/ZIOSpec.scala b/core-tests/shared/src/test/scala/zio/ZIOSpec.scala index a3a21c16bda9..6e9ed420093f 100644 --- a/core-tests/shared/src/test/scala/zio/ZIOSpec.scala +++ b/core-tests/shared/src/test/scala/zio/ZIOSpec.scala @@ -4650,6 +4650,28 @@ object ZIOSpec extends ZIOBaseSpec { result <- effects.get } yield assert(result)(equalTo(List("Closed"))) } + ), + suite("Exit")( + test("map returns an Exit") { + val exit = Exit.succeed(1).map(_ + 1) + assertTrue(exit == Exit.Success(2)) + }, + test("flatMap(success) returns an exit") { + val exit = Exit.succeed(1).flatMap(a => Exit.succeed(a + 1)) + assertTrue(exit == Exit.Success(2)) + }, + test("flatMap(failure) returns an exit") { + val exit = Exit.succeed(1).flatMap(a => Exit.fail(a + 1)) + assertTrue(exit == Exit.fail(2)) + }, + test("fold(success) returns an exit") { + val exit = (Exit.succeed(1): IO[Int, Int]).fold(_ - 1, _ + 1) + assertTrue(exit == Exit.Success(2)) + }, + test("fold(failure) returns an exit") { + val exit = (Exit.fail(1): IO[Int, Int]).fold(_ - 1, _ + 1) + assertTrue(exit == Exit.Success(0)) + } ) ) diff --git a/core/shared/src/main/scala/zio/ZIO.scala b/core/shared/src/main/scala/zio/ZIO.scala index 8d4c90563e19..ceee7aa6d362 100644 --- a/core/shared/src/main/scala/zio/ZIO.scala +++ b/core/shared/src/main/scala/zio/ZIO.scala @@ -683,7 +683,7 @@ sealed trait ZIO[-R, +E, +A] * does not fail, but succeeds with the value returned by the left or right * function passed to `fold`. */ - def fold[B](failure: E => B, success: A => B)(implicit ev: CanFail[E], trace: Trace): URIO[R, B] = + final def fold[B](failure: E => B, success: A => B)(implicit ev: CanFail[E], trace: Trace): URIO[R, B] = foldZIO(e => Exit.succeed(failure(e)), a => Exit.succeed(success(a))) /** @@ -969,7 +969,7 @@ sealed trait ZIO[-R, +E, +A] /** * Returns an effect whose success is mapped by the specified `f` function. */ - def map[B](f: A => B)(implicit trace: Trace): ZIO[R, E, B] = + final def map[B](f: A => B)(implicit trace: Trace): ZIO[R, E, B] = flatMap(a => Exit.succeed(f(a))) /** @@ -6518,12 +6518,6 @@ sealed trait Exit[+E, +A] extends ZIO[Any, E, A] { self => final def isSuccess: Boolean = self.isInstanceOf[Success[?]] - /** - * Returns an effect whose success is mapped by the specified `f` function. - */ - override final def map[B](f: A => B)(implicit trace: Trace): ZIO[Any, E, B] = - mapExit(f) - /** * Maps over the value type. */ diff --git a/project/MimaSettings.scala b/project/MimaSettings.scala index ab3a55da5e48..25ceb352f844 100644 --- a/project/MimaSettings.scala +++ b/project/MimaSettings.scala @@ -24,7 +24,9 @@ object MimaSettings { exclude[Problem]("zio.Scope#ReleaseMap*"), exclude[Problem]("zio.Scope$ReleaseMap*"), exclude[MissingClassProblem]("zio.Scope$Running*"), - exclude[MissingClassProblem]("zio.Scope$Exited*") + exclude[MissingClassProblem]("zio.Scope$Exited*"), + exclude[NewMixinForwarderProblem]("zio.Exit.fold"), + exclude[NewMixinForwarderProblem]("zio.Exit.map") ), mimaFailOnProblem := failOnProblem )