From a5522cc1ff87b7531fbf12467c0c0dded16d59a7 Mon Sep 17 00:00:00 2001 From: i-walker <46971368+i-walker@users.noreply.github.com> Date: Tue, 15 Mar 2022 18:05:33 +0100 Subject: [PATCH 01/17] init --- .../src/commonMain/kotlin/arrow/core/Iterable.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index 1ec37dfbc8b..50fa3a2d2c4 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -282,7 +282,11 @@ public inline fun Iterable.zip( internal fun Iterable.collectionSizeOrDefault(default: Int): Int = if (this is Collection<*>) this.size else default -public inline fun Iterable.traverseEither(f: (A) -> Either): Either> { +@Deprecated("use traverse instead", ReplaceWith("traverse(f)", "arrow.core.traverse")) +public inline fun Iterable.traverseEither(f: (A) -> Either): Either> = + traverse(f) + +public inline fun Iterable.traverse(f: (A) -> Either): Either> { val destination = ArrayList(collectionSizeOrDefault(10)) for (item in this) { when (val res = f(item)) { @@ -293,9 +297,13 @@ public inline fun Iterable.traverseEither(f: (A) -> Either): return destination.right() } +@Deprecated("use sequence instead", ReplaceWith("sequence()", "arrow.core.sequence")) public fun Iterable>.sequenceEither(): Either> = traverseEither(::identity) +public fun Iterable>.sequence(): Either> = + traverse(::identity) + public inline fun Iterable.traverseResult(f: (A) -> Result): Result> { val destination = ArrayList(collectionSizeOrDefault(10)) for (item in this) { @@ -336,7 +344,7 @@ public fun Iterable>.sequenceValidated(semigroup: Semigro public fun Iterable>.sequenceValidated(): ValidatedNel> = traverseValidated(Semigroup.nonEmptyList(), ::identity) -public inline fun Iterable.traverseOption(f: (A) -> Option): Option> { +public inline fun Iterable.traverse(f: (A) -> Option): Option> { val destination = ArrayList(collectionSizeOrDefault(10)) for (item in this) { when (val res = f(item)) { From 3872d7af3dfb2cf9d3925835ec70b735e1e622ce Mon Sep 17 00:00:00 2001 From: i-walker <46971368+i-walker@users.noreply.github.com> Date: Tue, 15 Mar 2022 18:11:44 +0100 Subject: [PATCH 02/17] prog --- .../commonMain/kotlin/arrow/core/Iterable.kt | 25 +++++++++++++++---- .../kotlin/arrow/core/IterableTest.kt | 4 +-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index 50fa3a2d2c4..215710f568f 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -7,6 +7,7 @@ import arrow.core.Either.Right import arrow.typeclasses.Monoid import arrow.typeclasses.Semigroup import kotlin.Result.Companion.success +import kotlin.experimental.ExperimentalTypeInference public inline fun Iterable.zip( c: Iterable, @@ -286,6 +287,8 @@ internal fun Iterable.collectionSizeOrDefault(default: Int): Int = public inline fun Iterable.traverseEither(f: (A) -> Either): Either> = traverse(f) +@OptIn(ExperimentalTypeInference::class) +@OverloadResolutionByLambdaReturnType public inline fun Iterable.traverse(f: (A) -> Either): Either> { val destination = ArrayList(collectionSizeOrDefault(10)) for (item in this) { @@ -299,23 +302,29 @@ public inline fun Iterable.traverse(f: (A) -> Either): Either @Deprecated("use sequence instead", ReplaceWith("sequence()", "arrow.core.sequence")) public fun Iterable>.sequenceEither(): Either> = - traverseEither(::identity) + traverse(::identity) public fun Iterable>.sequence(): Either> = traverse(::identity) -public inline fun Iterable.traverseResult(f: (A) -> Result): Result> { +@OptIn(ExperimentalTypeInference::class) +@OverloadResolutionByLambdaReturnType +public inline fun Iterable.traverse(f: (A) -> Result): Result> { val destination = ArrayList(collectionSizeOrDefault(10)) for (item in this) { f(item).fold(destination::add) { throwable -> - return@traverseResult Result.failure(throwable) + return@traverse Result.failure(throwable) } } return success(destination) } +@Deprecated("use traverse instead", ReplaceWith("traverse(f)", "arrow.core.traverse")) +public inline fun Iterable.traverseResult(f: (A) -> Result): Result> = + traverse(f) + public fun Iterable>.sequenceResult(): Result> = - traverseResult(::identity) + traverse(::identity) public inline fun Iterable.traverseValidated( semigroup: Semigroup, @@ -344,6 +353,12 @@ public fun Iterable>.sequenceValidated(semigroup: Semigro public fun Iterable>.sequenceValidated(): ValidatedNel> = traverseValidated(Semigroup.nonEmptyList(), ::identity) +@Deprecated("use traverse instead", ReplaceWith("traverse(f)", "arrow.core.traverse")) +public inline fun Iterable.traverseOption(f: (A) -> Option): Option> = + traverse(f) + +@OptIn(ExperimentalTypeInference::class) +@OverloadResolutionByLambdaReturnType public inline fun Iterable.traverse(f: (A) -> Option): Option> { val destination = ArrayList(collectionSizeOrDefault(10)) for (item in this) { @@ -356,7 +371,7 @@ public inline fun Iterable.traverse(f: (A) -> Option): Option Iterable>.sequenceOption(): Option> = - this.traverseOption { it } + traverse(::identity) public inline fun Iterable.traverseNullable(f: (A) -> B?): List? { val acc = mutableListOf() diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt index c9972d08441..7c1ba8c9cab 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt @@ -20,7 +20,7 @@ class IterableTest : UnitSpec() { "traverseEither stack-safe" { // also verifies result order and execution order (l to r) val acc = mutableListOf() - val res = (0..20_000).traverseEither { a -> + val res = (0..20_000).traverse { a -> acc.add(a) Either.Right(a) } @@ -31,7 +31,7 @@ class IterableTest : UnitSpec() { "traverseEither short-circuit" { checkAll(Arb.list(Arb.int())) { ints -> val acc = mutableListOf() - val evens = ints.traverseEither { + val evens = ints.traverse { if (it % 2 == 0) { acc.add(it) Either.Right(it) From 84e9076a564432e3ed9e8806762ab07bc9ff9159 Mon Sep 17 00:00:00 2001 From: i-walker <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 09:30:53 +0100 Subject: [PATCH 03/17] progress --- .../commonMain/kotlin/arrow/core/Iterable.kt | 76 ++++++++++++++----- .../kotlin/arrow/core/IterableTest.kt | 68 ++++++++--------- .../commonTest/kotlin/arrow/core/MapKTest.kt | 5 +- .../kotlin/arrow/core/NonEmptyListTest.kt | 2 +- .../kotlin/arrow/fx/coroutines/ParTraverse.kt | 1 + .../arrow/fx/coroutines/ParTraverseResult.kt | 4 +- .../fx/coroutines/ParTraverseValidated.kt | 4 +- .../kotlin/arrow/fx/coroutines/Resource.kt | 4 +- .../fx/coroutines/ParTraverseResultTest.kt | 5 +- .../fx/coroutines/ParTraverseValidatedTest.kt | 5 +- 10 files changed, 105 insertions(+), 69 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index 215710f568f..14a21c1ef75 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -323,35 +323,63 @@ public inline fun Iterable.traverse(f: (A) -> Result): Result Iterable.traverseResult(f: (A) -> Result): Result> = traverse(f) +@Deprecated("use sequence instead", ReplaceWith("sequence()", "arrow.core.sequence")) public fun Iterable>.sequenceResult(): Result> = + sequence() + +public fun Iterable>.sequence(): Result> = traverse(::identity) +@Deprecated("use traverse instead", ReplaceWith("traverse(semigroup, f)", "arrow.core.traverse")) public inline fun Iterable.traverseValidated( semigroup: Semigroup, f: (A) -> Validated -): Validated> = semigroup.run { - fold(Valid(ArrayList(collectionSizeOrDefault(10))) as Validated>) { acc, a -> - when (val res = f(a)) { - is Validated.Valid -> when (acc) { - is Valid -> acc.also { it.value.add(res.value) } - is Invalid -> acc - } - is Validated.Invalid -> when (acc) { - is Valid -> res - is Invalid -> Invalid(acc.value.combine(res.value)) +): Validated> = + traverse(semigroup, f) + +@OptIn(ExperimentalTypeInference::class) +@OverloadResolutionByLambdaReturnType +public inline fun Iterable.traverse( + semigroup: Semigroup, + f: (A) -> Validated +): Validated> = + semigroup.run { + fold(Valid(ArrayList(collectionSizeOrDefault(10))) as Validated>) { acc, a -> + when (val res = f(a)) { + is Validated.Valid -> when (acc) { + is Valid -> acc.also { it.value.add(res.value) } + is Invalid -> acc + } + is Validated.Invalid -> when (acc) { + is Valid -> res + is Invalid -> Invalid(acc.value.combine(res.value)) + } } } } -} +@Deprecated("use traverse instead", ReplaceWith("traverse(f)", "arrow.core.traverse")) public inline fun Iterable.traverseValidated(f: (A) -> ValidatedNel): ValidatedNel> = - traverseValidated(Semigroup.nonEmptyList(), f) + traverse(f) + +@OptIn(ExperimentalTypeInference::class) +@OverloadResolutionByLambdaReturnType +public inline fun Iterable.traverse(f: (A) -> ValidatedNel): ValidatedNel> = + traverse(Semigroup.nonEmptyList(), f) +@Deprecated("use sequence instead", ReplaceWith("sequence(semigroup)", "arrow.core.sequence")) public fun Iterable>.sequenceValidated(semigroup: Semigroup): Validated> = - traverseValidated(semigroup, ::identity) + sequence(semigroup) +public fun Iterable>.sequence(semigroup: Semigroup): Validated> = + traverse(semigroup, ::identity) + +@Deprecated("use sequence instead", ReplaceWith("sequence()", "arrow.core.sequence")) public fun Iterable>.sequenceValidated(): ValidatedNel> = - traverseValidated(Semigroup.nonEmptyList(), ::identity) + sequence() + +public fun Iterable>.sequence(): ValidatedNel> = + traverse(Semigroup.nonEmptyList(), ::identity) @Deprecated("use traverse instead", ReplaceWith("traverse(f)", "arrow.core.traverse")) public inline fun Iterable.traverseOption(f: (A) -> Option): Option> = @@ -370,10 +398,20 @@ public inline fun Iterable.traverse(f: (A) -> Option): Option Iterable>.sequenceOption(): Option> = - traverse(::identity) + sequence() + +public fun Iterable>.sequence(): Option> = + traverse(::identity) + +@Deprecated("use traverse instead", ReplaceWith("traverse(f)", "arrow.core.traverse")) +public inline fun Iterable.traverseNullable(f: (A) -> B?): List? = + traverse(f) -public inline fun Iterable.traverseNullable(f: (A) -> B?): List? { +@OptIn(ExperimentalTypeInference::class) +@OverloadResolutionByLambdaReturnType +public inline fun Iterable.traverse(f: (A) -> B?): List? { val acc = mutableListOf() forEach { a -> val res = f(a) @@ -386,8 +424,12 @@ public inline fun Iterable.traverseNullable(f: (A) -> B?): List? { return acc.toList() } +@Deprecated("use sequence instead", ReplaceWith("sequence()", "arrow.core.sequence")) public fun Iterable.sequenceNullable(): List? = - this.traverseNullable { it } + sequence() + +public fun Iterable.sequence(): List? = + traverse(::identity) public fun Iterable.void(): List = map { } diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt index 7c1ba8c9cab..0fd9a689133 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt @@ -7,17 +7,15 @@ import io.kotest.matchers.collections.shouldContainExactly import io.kotest.matchers.nulls.shouldBeNull import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.property.Arb -import io.kotest.property.checkAll import io.kotest.matchers.shouldBe import io.kotest.property.arbitrary.boolean import io.kotest.property.arbitrary.int -import io.kotest.property.arbitrary.list import kotlin.math.max import kotlin.math.min class IterableTest : UnitSpec() { init { - "traverseEither stack-safe" { + "traverse Either stack-safe" { // also verifies result order and execution order (l to r) val acc = mutableListOf() val res = (0..20_000).traverse { a -> @@ -28,7 +26,7 @@ class IterableTest : UnitSpec() { res shouldBe Either.Right((0..20_000).toList()) } - "traverseEither short-circuit" { + "traverse Either short-circuit" { checkAll(Arb.list(Arb.int())) { ints -> val acc = mutableListOf() val evens = ints.traverse { @@ -45,16 +43,16 @@ class IterableTest : UnitSpec() { } } - "sequenceEither should be consistent with traverseEither" { + "sequenceEither should be consistent with traverse Either" { checkAll(Arb.list(Arb.int())) { ints -> - ints.map { it.right() }.sequenceEither() shouldBe ints.traverseEither { it.right() } + ints.map { it.right() }.sequence() shouldBe ints.traverse { it.right() } } } - "traverseResult stack-safe" { + "traverse Result stack-safe" { // also verifies result order and execution order (l to r) val acc = mutableListOf() - val res = (0..20_000).traverseResult { a -> + val res = (0..20_000).traverse { a -> acc.add(a) Result.success(a) } @@ -62,10 +60,10 @@ class IterableTest : UnitSpec() { res shouldBe Result.success((0..20_000).toList()) } - "traverseResult short-circuit" { + "traverse Result short-circuit" { checkAll(Arb.list(Arb.int())) { ints -> val acc = mutableListOf() - val evens = ints.traverseResult { + val evens = ints.traverse { if (it % 2 == 0) { acc.add(it) Result.success(it) @@ -79,16 +77,16 @@ class IterableTest : UnitSpec() { } } - "sequenceResult should be consistent with traverseResult" { + "sequence Result should be consistent with traverse Result" { checkAll(Arb.list(Arb.int())) { ints -> - ints.map { Result.success(it) }.sequenceResult() shouldBe ints.traverseResult { Result.success(it) } + ints.map { Result.success(it) }.sequence() shouldBe ints.traverse { Result.success(it) } } } - "traverseOption is stack-safe" { + "traverse Option is stack-safe" { // also verifies result order and execution order (l to r) val acc = mutableListOf() - val res = (0..20_000).traverseOption { a -> + val res = (0..20_000).traverse { a: Int -> acc.add(a) Some(a) } @@ -96,10 +94,10 @@ class IterableTest : UnitSpec() { res shouldBe Some((0..20_000).toList()) } - "traverseOption short-circuits" { + "traverse Option short-circuits" { checkAll(Arb.list(Arb.int())) { ints -> val acc = mutableListOf() - val evens = ints.traverseOption { + val evens = ints.traverse { it: Int -> (it % 2 == 0).maybe { acc.add(it) it @@ -110,23 +108,23 @@ class IterableTest : UnitSpec() { } } - "sequenceOption yields some when all entries in the list are some" { + "sequence Option yields some when all entries in the list are some" { checkAll(Arb.list(Arb.int())) { ints -> - val evens = ints.map { (it % 2 == 0).maybe { it } }.sequenceOption() + val evens = ints.map { (it % 2 == 0).maybe { it } }.sequence() evens.fold({ Unit }) { it shouldBe ints } } } - "sequenceOption should be consistent with traverseOption" { + "sequence Option should be consistent with traverse Option" { checkAll(Arb.list(Arb.int())) { ints -> - ints.map { Some(it) }.sequenceOption() shouldBe ints.traverseOption { Some(it) } + ints.map { Some(it) }.sequence() shouldBe ints.traverse { it: Int -> Some(it) } } } - "traverseNullable is stack-safe" { + "traverse Nullable is stack-safe" { // also verifies result order and execution order (l to r) val acc = mutableListOf() - val res = (0..20_000).traverseNullable { a -> + val res = (0..20_000).traverse { a: Int -> acc.add(a) a } @@ -134,10 +132,10 @@ class IterableTest : UnitSpec() { res.shouldNotBeNull() shouldBe (0..20_000).toList() } - "traverseNullable short-circuits" { + "traverse Nullable short-circuits" { checkAll(Arb.list(Arb.int())) { ints -> val acc = mutableListOf() - val evens = ints.traverseNullable { + val evens = ints.traverse { it: Int -> if (it % 2 == 0) { acc.add(it) it @@ -157,9 +155,9 @@ class IterableTest : UnitSpec() { } } - "sequenceNullable yields some when all entries in the list are not null" { + "sequence Nullable yields some when all entries in the list are not null" { checkAll(Arb.list(Arb.int())) { ints -> - val evens = ints.map { if (it % 2 == 0) it else null }.sequenceNullable() + val evens = ints.map { if (it % 2 == 0) it else null }.sequence() val expected = ints.takeWhile { it % 2 == 0 } if (ints.any { it % 2 != 0 }) { @@ -170,16 +168,16 @@ class IterableTest : UnitSpec() { } } - "sequenceNullable should be consistent with traversNullable" { + "sequence Nullable should be consistent with travers Nullable" { checkAll(Arb.list(Arb.int())) { ints -> - ints.map { it as Int? }.sequenceNullable() shouldBe ints.traverseNullable { it as Int? } + ints.map { it as Int? }.sequence() shouldBe ints.traverse { it: Int -> it as Int? } } } - "traverseValidated stack-safe" { + "traverse Validated stack-safe" { // also verifies result order and execution order (l to r) val acc = mutableListOf() - val res = (0..20_000).traverseValidated(Semigroup.string()) { + val res = (0..20_000).traverse(Semigroup.string()) { acc.add(it) Validated.Valid(it) } @@ -187,11 +185,11 @@ class IterableTest : UnitSpec() { res shouldBe Validated.Valid((0..20_000).toList()) } - "traverseValidated acumulates" { + "traverse Validated acumulates" { checkAll(Arb.list(Arb.int())) { ints -> val res: ValidatedNel> = ints.map { i -> if (i % 2 == 0) Valid(i) else Invalid(nonEmptyListOf(i)) } - .sequenceValidated() + .sequence() val expected: ValidatedNel> = NonEmptyList.fromList(ints.filterNot { it % 2 == 0 }) .fold({ Valid(ints.filter { it % 2 == 0 }) }, { Invalid(it) }) @@ -200,10 +198,10 @@ class IterableTest : UnitSpec() { } } - "sequenceValidated should be consistent with traverseValidated" { + "sequence Validated should be consistent with traverseValidated" { checkAll(Arb.list(Arb.int())) { ints -> - ints.map { it.valid() }.sequenceValidated(Semigroup.string()) shouldBe - ints.traverseValidated(Semigroup.string()) { it.valid() } + ints.map { it.valid() }.sequence(Semigroup.string()) shouldBe + ints.traverse(Semigroup.string()) { it.valid() } } } diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/MapKTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/MapKTest.kt index 282a592494b..cafe79f4218 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/MapKTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/MapKTest.kt @@ -7,13 +7,10 @@ import arrow.core.test.laws.MonoidLaws import arrow.typeclasses.Monoid import arrow.typeclasses.Semigroup import io.kotest.property.Arb -import io.kotest.property.checkAll import io.kotest.matchers.shouldBe import io.kotest.property.arbitrary.boolean import io.kotest.property.arbitrary.int -import io.kotest.property.arbitrary.list import io.kotest.property.arbitrary.long -import io.kotest.property.arbitrary.map import io.kotest.property.arbitrary.string class MapKTest : UnitSpec() { @@ -80,7 +77,7 @@ class MapKTest : UnitSpec() { "sequenceOption yields some when all entries in the list are some" { checkAll(Arb.list(Arb.int())) { ints -> - val evens = ints.map { (it % 2 == 0).maybe { it } }.sequenceOption() + val evens = ints.map { (it % 2 == 0).maybe { it } }.sequence() evens.fold({ Unit }) { it shouldBe ints } } } diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt index a14d8893a07..7bb02f888c5 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt @@ -93,7 +93,7 @@ class NonEmptyListTest : UnitSpec() { "traverseValidated stack-safe" { // also verifies result order and execution order (l to r) val acc = mutableListOf() - val res = (0..20_000).traverseValidated(Semigroup.string()) { + val res = (0..20_000).traverse(Semigroup.string()) { acc.add(it) Validated.Valid(it) } diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverse.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverse.kt index e8158371531..9ef68fdb12d 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverse.kt +++ b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverse.kt @@ -123,6 +123,7 @@ public suspend fun Iterable A>.parSequence(ctx: * Traverses this [Iterable] and runs [f] in [n] parallel operations on [Dispatchers.Default]. * Cancelling this operation cancels all running tasks. */ + public suspend fun Iterable.parTraverseN(n: Int, f: suspend CoroutineScope.(A) -> B): List = parTraverseN(Dispatchers.Default, n, f) diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseResult.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseResult.kt index 3d76c23e3d1..6c0b129865a 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseResult.kt +++ b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseResult.kt @@ -3,7 +3,7 @@ package arrow.fx.coroutines -import arrow.core.sequenceResult +import arrow.core.sequence import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async @@ -132,5 +132,5 @@ public suspend fun Iterable.parTraverseResult( f: suspend CoroutineScope.(A) -> Result ): Result> = coroutineScope { - map { async(ctx) { f.invoke(this, it) } }.awaitAll().sequenceResult() + map { async(ctx) { f.invoke(this, it) } }.awaitAll().sequence() } diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseValidated.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseValidated.kt index 86c0eee5843..da530594ed9 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseValidated.kt +++ b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseValidated.kt @@ -4,7 +4,7 @@ package arrow.fx.coroutines import arrow.core.Validated -import arrow.core.sequenceValidated +import arrow.core.sequence import arrow.typeclasses.Semigroup import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -206,5 +206,5 @@ public suspend fun Iterable.parTraverseValidated( ): Validated> = coroutineScope { map { async(ctx) { f.invoke(this, it) } }.awaitAll() - .sequenceValidated(semigroup) + .sequence(semigroup) } diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/Resource.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/Resource.kt index f8d41a404d5..777d254bdeb 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/Resource.kt +++ b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/Resource.kt @@ -6,7 +6,7 @@ import arrow.core.NonEmptyList import arrow.core.ValidatedNel import arrow.core.identity import arrow.core.invalidNel -import arrow.core.traverseValidated +import arrow.core.traverse import arrow.core.valid import arrow.fx.coroutines.continuations.ResourceScope import kotlin.coroutines.CoroutineContext @@ -757,7 +757,7 @@ private inline fun catchNel(f: () -> A): ValidatedNel = private suspend fun List Unit>.cancelAll( exitCase: ExitCase, first: Throwable? = null -): Throwable? = traverseValidated { f -> +): Throwable? = traverse { f -> catchNel { f(exitCase) } }.fold({ if (first != null) Platform.composeErrors(NonEmptyList(first, it)) diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseResultTest.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseResultTest.kt index 3b94c934c84..32c4a0aade7 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseResultTest.kt +++ b/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseResultTest.kt @@ -1,14 +1,13 @@ package arrow.fx.coroutines import arrow.core.Either -import arrow.core.sequenceResult +import arrow.core.sequence import arrow.core.test.generators.result import io.kotest.matchers.result.shouldBeFailureOfType import io.kotest.matchers.shouldBe import io.kotest.matchers.types.shouldBeTypeOf import io.kotest.property.Arb import io.kotest.property.arbitrary.int -import io.kotest.property.arbitrary.list import io.kotest.property.arbitrary.orNull import io.kotest.property.arbitrary.string import kotlinx.coroutines.CompletableDeferred @@ -58,7 +57,7 @@ class ParTraverseResultTest : ArrowFxSpec( "parTraverseResult identity is identity" { checkAll(Arb.list(Arb.result(Arb.int()))) { l -> val res = l.parTraverseResult { it } - res shouldBe l.sequenceResult() + res shouldBe l.sequence() } } diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedTest.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedTest.kt index 0ad3690667e..26be83f0a61 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedTest.kt +++ b/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedTest.kt @@ -4,14 +4,13 @@ import arrow.core.Either import arrow.core.NonEmptyList import arrow.core.Validated import arrow.core.invalidNel -import arrow.core.sequenceValidated +import arrow.core.sequence import arrow.core.validNel import arrow.typeclasses.Semigroup import io.kotest.matchers.should import io.kotest.matchers.shouldBe import io.kotest.property.Arb import io.kotest.property.arbitrary.int -import io.kotest.property.arbitrary.list import io.kotest.property.arbitrary.string import kotlinx.coroutines.CompletableDeferred @@ -61,7 +60,7 @@ class ParTraverseValidatedTest : ArrowFxSpec( "parTraverseValidated identity is identity" { checkAll(Arb.list(Arb.validatedNel(Arb.int(), Arb.int()))) { l -> val res: Validated, List> = l.parTraverseValidated(Semigroup.nonEmptyList()) { it } - res shouldBe l.sequenceValidated(Semigroup.nonEmptyList()) + res shouldBe l.sequence(Semigroup.nonEmptyList()) } } From 7d31c3e7b5c51c313119f60457c83507570348a7 Mon Sep 17 00:00:00 2001 From: i-walker Date: Wed, 16 Mar 2022 08:47:02 +0000 Subject: [PATCH 04/17] Update API files --- arrow-libs/core/arrow-core/api/arrow-core.api | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arrow-libs/core/arrow-core/api/arrow-core.api b/arrow-libs/core/arrow-core/api/arrow-core.api index 3ac149f6121..ed562f34597 100644 --- a/arrow-libs/core/arrow-core/api/arrow-core.api +++ b/arrow-libs/core/arrow-core/api/arrow-core.api @@ -584,6 +584,12 @@ public final class arrow/core/IterableKt { public static final fun salign (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;Ljava/lang/Iterable;)Ljava/lang/Iterable; public static final fun separateEither (Ljava/lang/Iterable;)Lkotlin/Pair; public static final fun separateValidated (Ljava/lang/Iterable;)Lkotlin/Pair; + public static final fun sequence (Ljava/lang/Iterable;)Larrow/core/Either; + public static final fun sequence (Ljava/lang/Iterable;)Larrow/core/Option; + public static final fun sequence (Ljava/lang/Iterable;)Larrow/core/Validated; + public static final fun sequence (Ljava/lang/Iterable;)Ljava/lang/Object; + public static final fun sequence (Ljava/lang/Iterable;)Ljava/util/List; + public static final fun sequence (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;)Larrow/core/Validated; public static final fun sequenceEither (Ljava/lang/Iterable;)Larrow/core/Either; public static final fun sequenceNullable (Ljava/lang/Iterable;)Ljava/util/List; public static final fun sequenceOption (Ljava/lang/Iterable;)Larrow/core/Option; @@ -594,6 +600,12 @@ public final class arrow/core/IterableKt { public static final fun singleOrNone (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; public static final fun split (Ljava/lang/Iterable;)Lkotlin/Pair; public static final fun tail (Ljava/lang/Iterable;)Ljava/util/List; + public static final fun traverse (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; + public static final fun traverse (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; + public static final fun traverse (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; + public static final fun traverse (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; + public static final fun traverse (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun traverse (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/util/List; public static final fun traverseEither (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; public static final fun traverseNullable (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/util/List; public static final fun traverseOption (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; From 3fb8bc15cd02ff45825f97985c34685c971f78c4 Mon Sep 17 00:00:00 2001 From: i-walker <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 10:07:36 +0100 Subject: [PATCH 05/17] check From 2df416c197dea4c3420b0a51dee6efc258e4114b Mon Sep 17 00:00:00 2001 From: Imran Malic Settuba <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 12:29:18 +0100 Subject: [PATCH 06/17] Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt Co-authored-by: Simon Vergauwen --- .../arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index 14a21c1ef75..413c66f8138 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -424,7 +424,7 @@ public inline fun Iterable.traverse(f: (A) -> B?): List? { return acc.toList() } -@Deprecated("use sequence instead", ReplaceWith("sequence()", "arrow.core.sequence")) +@Deprecated("sequenceNullable is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) public fun Iterable.sequenceNullable(): List? = sequence() From 9b6bd9be24bb0701a064a719e72dcc7790503057 Mon Sep 17 00:00:00 2001 From: Imran Malic Settuba <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 12:29:40 +0100 Subject: [PATCH 07/17] Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt Co-authored-by: Simon Vergauwen --- .../arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index 413c66f8138..b1e59e047da 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -283,7 +283,7 @@ public inline fun Iterable.zip( internal fun Iterable.collectionSizeOrDefault(default: Int): Int = if (this is Collection<*>) this.size else default -@Deprecated("use traverse instead", ReplaceWith("traverse(f)", "arrow.core.traverse")) +@Deprecated("traverseEither is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse")) public inline fun Iterable.traverseEither(f: (A) -> Either): Either> = traverse(f) From 38d22d16c7865e05f4fd403f22b73a7deafefe67 Mon Sep 17 00:00:00 2001 From: Imran Malic Settuba <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 12:29:46 +0100 Subject: [PATCH 08/17] Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt Co-authored-by: Simon Vergauwen --- .../arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index b1e59e047da..c0b2f1b55fa 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -300,7 +300,7 @@ public inline fun Iterable.traverse(f: (A) -> Either): Either return destination.right() } -@Deprecated("use sequence instead", ReplaceWith("sequence()", "arrow.core.sequence")) +@Deprecated("sequenceEither is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) public fun Iterable>.sequenceEither(): Either> = traverse(::identity) From bbcbadadf48ad484e3b1af57773816921f6e6eb9 Mon Sep 17 00:00:00 2001 From: Imran Malic Settuba <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 12:29:52 +0100 Subject: [PATCH 09/17] Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt Co-authored-by: Simon Vergauwen --- .../arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index c0b2f1b55fa..fe90e04696b 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -319,7 +319,7 @@ public inline fun Iterable.traverse(f: (A) -> Result): Result Iterable.traverseResult(f: (A) -> Result): Result> = traverse(f) From e97a6bab0f1396fe52342be3e2556bcf298ab013 Mon Sep 17 00:00:00 2001 From: Imran Malic Settuba <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 12:29:58 +0100 Subject: [PATCH 10/17] Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt Co-authored-by: Simon Vergauwen --- .../arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index fe90e04696b..da7e284fb63 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -330,7 +330,7 @@ public fun Iterable>.sequenceResult(): Result> = public fun Iterable>.sequence(): Result> = traverse(::identity) -@Deprecated("use traverse instead", ReplaceWith("traverse(semigroup, f)", "arrow.core.traverse")) +@Deprecated("traverseValidated is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(semigroup, f)", "arrow.core.traverse")) public inline fun Iterable.traverseValidated( semigroup: Semigroup, f: (A) -> Validated From d649b228528154557a8b8b3c4560eabba987a68c Mon Sep 17 00:00:00 2001 From: Imran Malic Settuba <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 12:30:03 +0100 Subject: [PATCH 11/17] Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt Co-authored-by: Simon Vergauwen --- .../arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index da7e284fb63..8bcd5376ca1 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -323,7 +323,7 @@ public inline fun Iterable.traverse(f: (A) -> Result): Result Iterable.traverseResult(f: (A) -> Result): Result> = traverse(f) -@Deprecated("use sequence instead", ReplaceWith("sequence()", "arrow.core.sequence")) +@Deprecated("sequenceResult is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) public fun Iterable>.sequenceResult(): Result> = sequence() From 1c2e97110819dbe631f65891ac5ffdcf9197638a Mon Sep 17 00:00:00 2001 From: Imran Malic Settuba <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 12:30:13 +0100 Subject: [PATCH 12/17] Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt Co-authored-by: Simon Vergauwen --- .../arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index 8bcd5376ca1..1110480b6b0 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -381,7 +381,7 @@ public fun Iterable>.sequenceValidated(): ValidatedNel public fun Iterable>.sequence(): ValidatedNel> = traverse(Semigroup.nonEmptyList(), ::identity) -@Deprecated("use traverse instead", ReplaceWith("traverse(f)", "arrow.core.traverse")) +@Deprecated("traverseOption is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse")) public inline fun Iterable.traverseOption(f: (A) -> Option): Option> = traverse(f) From bbcfb2a43bc63b65c27cc97f943b64fde0e35b05 Mon Sep 17 00:00:00 2001 From: Imran Malic Settuba <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 12:30:19 +0100 Subject: [PATCH 13/17] Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt Co-authored-by: Simon Vergauwen --- .../arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index 1110480b6b0..3c7242995f8 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -398,7 +398,7 @@ public inline fun Iterable.traverse(f: (A) -> Option): Option Iterable>.sequenceOption(): Option> = sequence() From 76fc5dcf37af74ebe07c9883795b01f2d3b538ac Mon Sep 17 00:00:00 2001 From: Imran Malic Settuba <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 12:30:27 +0100 Subject: [PATCH 14/17] Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt Co-authored-by: Simon Vergauwen --- .../arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index 3c7242995f8..60f7e2a5e4c 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -405,7 +405,7 @@ public fun Iterable>.sequenceOption(): Option> = public fun Iterable>.sequence(): Option> = traverse(::identity) -@Deprecated("use traverse instead", ReplaceWith("traverse(f)", "arrow.core.traverse")) +@Deprecated("traverseNullable is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse")) public inline fun Iterable.traverseNullable(f: (A) -> B?): List? = traverse(f) From 5d471173162fb50dddb8c5e25eb39fca9e5cf2ed Mon Sep 17 00:00:00 2001 From: i-walker <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 14:03:36 +0100 Subject: [PATCH 15/17] show that traverse Nullable and Either sequence interoperate --- .../commonTest/kotlin/arrow/core/IterableTest.kt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt index 0fd9a689133..62c3e2d00ff 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt @@ -1,15 +1,19 @@ package arrow.core import arrow.core.test.UnitSpec +import arrow.core.test.generators.either import arrow.core.test.generators.option import arrow.typeclasses.Semigroup import io.kotest.matchers.collections.shouldContainExactly import io.kotest.matchers.nulls.shouldBeNull import io.kotest.matchers.nulls.shouldNotBeNull +import io.kotest.matchers.should import io.kotest.property.Arb import io.kotest.matchers.shouldBe import io.kotest.property.arbitrary.boolean import io.kotest.property.arbitrary.int +import io.kotest.property.arbitrary.orNull +import io.kotest.property.arbitrary.string import kotlin.math.max import kotlin.math.min @@ -198,13 +202,22 @@ class IterableTest : UnitSpec() { } } - "sequence Validated should be consistent with traverseValidated" { + "sequence Validated should be consistent with traverse Validated" { checkAll(Arb.list(Arb.int())) { ints -> ints.map { it.valid() }.sequence(Semigroup.string()) shouldBe ints.traverse(Semigroup.string()) { it.valid() } } } + "traverse Nullable and sequence Either interoperate" { + checkAll( + Arb.either(Arb.string(), Arb.int()).orNull(), + Arb.list(Arb.int()) + ) { either, ints -> + ints.traverse { i -> either?.map { it + i } }?.sequence() shouldBe either?.map { i -> ints.traverse { it + i } } + } + } + "zip3" { checkAll(Arb.list(Arb.int()), Arb.list(Arb.int()), Arb.list(Arb.int())) { a, b, c -> val result = a.zip(b, c, ::Triple) From b68af9017493019594993da003ce7dbe30ca7431 Mon Sep 17 00:00:00 2001 From: Imran Malic Settuba <46971368+i-walker@users.noreply.github.com> Date: Wed, 16 Mar 2022 14:04:34 +0100 Subject: [PATCH 16/17] Apply suggestions from code review Co-authored-by: Simon Vergauwen --- .../arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index 60f7e2a5e4c..e4704746a07 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -358,7 +358,7 @@ public inline fun Iterable.traverse( } } -@Deprecated("use traverse instead", ReplaceWith("traverse(f)", "arrow.core.traverse")) +@Deprecated("traverseValidated is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse")) public inline fun Iterable.traverseValidated(f: (A) -> ValidatedNel): ValidatedNel> = traverse(f) @@ -367,14 +367,14 @@ public inline fun Iterable.traverseValidated(f: (A) -> ValidatedNel public inline fun Iterable.traverse(f: (A) -> ValidatedNel): ValidatedNel> = traverse(Semigroup.nonEmptyList(), f) -@Deprecated("use sequence instead", ReplaceWith("sequence(semigroup)", "arrow.core.sequence")) +@Deprecated("sequenceValidated is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence(semigroup)", "arrow.core.sequence")) public fun Iterable>.sequenceValidated(semigroup: Semigroup): Validated> = sequence(semigroup) public fun Iterable>.sequence(semigroup: Semigroup): Validated> = traverse(semigroup, ::identity) -@Deprecated("use sequence instead", ReplaceWith("sequence()", "arrow.core.sequence")) +@Deprecated("sequenceValidated is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) public fun Iterable>.sequenceValidated(): ValidatedNel> = sequence() From df90bd603c07ed13c06b35b2c32640b7825d192d Mon Sep 17 00:00:00 2001 From: i-walker <46971368+i-walker@users.noreply.github.com> Date: Thu, 17 Mar 2022 00:41:37 +0100 Subject: [PATCH 17/17] show that traverse Nullable and Either sequence interoperate --- .../kotlin/arrow/core/IterableTest.kt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt index 62c3e2d00ff..224fc743727 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt @@ -2,8 +2,10 @@ package arrow.core import arrow.core.test.UnitSpec import arrow.core.test.generators.either +import arrow.core.test.generators.functionAToB import arrow.core.test.generators.option import arrow.typeclasses.Semigroup +import io.kotest.matchers.collections.shouldBeEmpty import io.kotest.matchers.collections.shouldContainExactly import io.kotest.matchers.nulls.shouldBeNull import io.kotest.matchers.nulls.shouldNotBeNull @@ -209,12 +211,19 @@ class IterableTest : UnitSpec() { } } - "traverse Nullable and sequence Either interoperate" { + "sequence Either traverse Nullable interoperate - and proof map + sequence equality with traverse" { checkAll( - Arb.either(Arb.string(), Arb.int()).orNull(), - Arb.list(Arb.int()) - ) { either, ints -> - ints.traverse { i -> either?.map { it + i } }?.sequence() shouldBe either?.map { i -> ints.traverse { it + i } } + Arb.list(Arb.int()), + Arb.functionAToB?>(Arb.either(Arb.string(), Arb.int()).orNull()) + ) { ints, f -> + + val res: Either>? = + ints.traverse(f)?.sequence() + + val expected: Either>? = + ints.map(f).sequence()?.sequence() + + res shouldBe expected } }