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..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 @@ -385,3 +385,20 @@ 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 inline fun Iterable.traverse(transform: (V) -> Result): Result, E> { + return fold( + initial = emptyList(), + operation = { acc: List, element: V -> + transform(element).map { value -> + acc + value + } + } + ) +} 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) + } + + } }