From e60f956622ec16948c907e1616145cebd4216a2f Mon Sep 17 00:00:00 2001 From: hoangchung <52132635+hoangchungk53qx1@users.noreply.github.com> Date: Wed, 31 Jul 2024 01:48:44 +0700 Subject: [PATCH 1/3] Update link monad_comprehensions Arrow (Kotlin) README.md Update the error link Arrow kotlin --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9cf85a8..04b8e7a 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ The `binding` function primarily draws inspiration from [Bow's `binding` function][bow-bindings], however below is a list of other resources on the topic of monad comprehensions. -- [Monad comprehensions - Arrow (Kotlin)](https://arrow-kt.io/docs/0.10/patterns/monad_comprehensions/) +- [Monad comprehensions - Arrow (Kotlin)](https://old.arrow-kt.io/docs/patterns/monad_comprehensions/) - [Monad comprehensions - Bow (Swift)](https://bow-swift.io/docs/patterns/monad-comprehensions) - [For comprehensions - Scala](https://docs.scala-lang.org/tour/for-comprehensions.html) From e0ef5f78dce7bd7e55162e144b2ecb18be542251 Mon Sep 17 00:00:00 2001 From: hoangchungk53qx1 Date: Mon, 7 Apr 2025 03:00:56 +0700 Subject: [PATCH 2/3] Add traverse function to Iterable and corresponding tests --- .../com/github/michaelbull/result/Iterable.kt | 19 +++++++++++ .../github/michaelbull/result/IterableTest.kt | 32 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Iterable.kt b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Iterable.kt index c1c86a0..bae3130 100644 --- a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Iterable.kt +++ b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Iterable.kt @@ -385,3 +385,22 @@ public inline fun > Iterable.mapRe return Ok(values) } + +/** + * Applies the given [transform] function to each element in this [Iterable], collecting the results into a [Result, E>]. + * If all transformations succeed, returns an [Ok] containing a list of [U] values in the same order as the original [Iterable]. + * If any transformation fails, immediately returns the first [Err] + * encountered and stops processing further elements. + */ +public fun Iterable.traverse(transform: (V) -> Result): Result, E> { + val results = mutableListOf() + for (item in this) { + val result = transform(item) + val element = when { + result.isOk -> result.value + else -> return Err(result.error) + } + results.add(element) + } + return Ok(results) +} diff --git a/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/IterableTest.kt b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/IterableTest.kt index 3442ee0..988684b 100644 --- a/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/IterableTest.kt +++ b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/IterableTest.kt @@ -199,4 +199,36 @@ class IterableTest { ) } } + + class Traverse { + @Test + fun returnTraverseValueIfOk() { + val input = listOf(1, 2, 3) + val transform: (Int) -> Result = { Ok(it.toString()) } + val result = input.traverse(transform) + + assertEquals(Ok(listOf("1", "2", "3")), result) + } + + @Test + fun returnsFirstErrorIfErr() { + val input = listOf(1, 2, 3) + val transform: (Int) -> Result = { + if (it == 1) Err("Error at 1") else Ok(it.toString()) + } + val result = input.traverse(transform) + + assertEquals(Err("Error at 1"), result) + } + + @Test + fun traverseWithEmptyListReturnsEmptyOkList() { + val input = emptyList() + val transform: (Int) -> Result = { Ok(it.toString()) } + val result = input.traverse(transform) + + assertEquals(Ok(emptyList()), result) + } + + } } From 4fc24880059b10e5f6bd70acb9a4e082f46ad7cd Mon Sep 17 00:00:00 2001 From: hoangchungk53qx1 Date: Mon, 7 Apr 2025 22:59:51 +0700 Subject: [PATCH 3/3] Refactor traverse function in Iterable to use fold for improved --- .../com/github/michaelbull/result/Iterable.kt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Iterable.kt b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Iterable.kt index bae3130..3fc9d74 100644 --- a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Iterable.kt +++ b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Iterable.kt @@ -392,15 +392,13 @@ public inline fun > Iterable.mapRe * If any transformation fails, immediately returns the first [Err] * encountered and stops processing further elements. */ -public fun Iterable.traverse(transform: (V) -> Result): Result, E> { - val results = mutableListOf() - for (item in this) { - val result = transform(item) - val element = when { - result.isOk -> result.value - else -> return Err(result.error) +public inline fun Iterable.traverse(transform: (V) -> Result): Result, E> { + return fold( + initial = emptyList(), + operation = { acc: List, element: V -> + transform(element).map { value -> + acc + value + } } - results.add(element) - } - return Ok(results) + ) }