From 475c19cbe395ad6588f1b7e103f7fc710dda576b Mon Sep 17 00:00:00 2001 From: "junie-eap[bot]" Date: Fri, 6 Jun 2025 10:51:07 +0000 Subject: [PATCH] feat: add getOrElseThrow method to Either type A new method `getOrElseThrow` was implemented for the Arrow library's `Either` type which returns the right value if the Either is Right, or throws a RuntimeException if the Either is Left. This implementation was successfully tested and confirmed to work as expected. All related tasks were completed, and the changes were submitted without any issues. --- .../commonMain/kotlin/arrow/core/Either.kt | 26 +++++++++++++++++++ .../kotlin/arrow/core/EitherTest.kt | 16 ++++++++++++ 2 files changed, 42 insertions(+) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt index 7d6f69ad694..2a8aceb7cf4 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt @@ -1368,6 +1368,32 @@ public fun A.left(): Either = Left(this) public fun A.right(): Either = Right(this) +/** + * Returns the [Right] value or throws an exception created by applying the [onLeft] function to the [Left] value. + * + * ```kotlin + * import arrow.core.Either + * import io.kotest.assertions.throwables.shouldThrow + * import io.kotest.matchers.shouldBe + * + * fun test() { + * Either.Right(12).getOrElseThrow { RuntimeException("Error: $it") } shouldBe 12 + * shouldThrow { + * Either.Left("error").getOrElseThrow { RuntimeException("Error: $it") } + * }.message shouldBe "Error: error" + * } + * ``` + * + * + */ +public inline fun Either.getOrElseThrow(onLeft: (A) -> Throwable): B { + contract { callsInPlace(onLeft, InvocationKind.AT_MOST_ONCE) } + return when (this) { + is Left -> throw onLeft(this.value) + is Right -> this.value + } +} + public operator fun , B : Comparable> Either.compareTo(other: Either): Int = fold( { a1 -> other.fold({ a2 -> a1.compareTo(a2) }, { -1 }) }, diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt index 8e570bcec97..29d139437d8 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt @@ -130,6 +130,22 @@ class EitherTest { } } + @Test + fun getOrElseThrowOk() = runTest { + checkAll(Arb.int(), Arb.string()) { a: Int, b: String -> + Right(a).getOrElseThrow { RuntimeException(it.toString()) } shouldBe a + + val exception = try { + Left(b).getOrElseThrow { RuntimeException(it) } + null // Should not reach here + } catch (e: RuntimeException) { + e + } + + exception?.message shouldBe b + } + } + @Test fun getOrNullOk() = runTest { checkAll(Arb.int()) { a: Int ->