diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Sequence.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Sequence.kt
index 8e00e19fc78..7f67780684d 100644
--- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Sequence.kt
+++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Sequence.kt
@@ -593,11 +593,13 @@ public fun Sequence.salign(
* @receiver Iterable of Validated
* @return a tuple containing Sequence with [Either.Left] and another Sequence with its [Either.Right] values.
*/
-public fun Sequence>.separateEither(): Pair, Sequence> {
- val asep = flatMap { gab -> gab.fold({ sequenceOf(it) }, { emptySequence() }) }
- val bsep = flatMap { gab -> gab.fold({ emptySequence() }, { sequenceOf(it) }) }
- return asep to bsep
-}
+public fun Sequence>.separateEither(): Pair, Sequence> =
+ fold(sequenceOf() to sequenceOf()) { (lefts, rights), either ->
+ when (either) {
+ is Left -> lefts + either.value to rights
+ is Right -> lefts to rights + either.value
+ }
+ }
/**
* Separate the inner [Validated] values into the [Validated.Invalid] and [Validated.Valid].
@@ -605,11 +607,13 @@ public fun Sequence>.separateEither(): Pair, Seq
* @receiver Iterable of Validated
* @return a tuple containing Sequence with [Validated.Invalid] and another Sequence with its [Validated.Valid] values.
*/
-public fun Sequence>.separateValidated(): Pair, Sequence> {
- val asep = flatMap { gab -> gab.fold({ sequenceOf(it) }, { emptySequence() }) }
- val bsep = flatMap { gab -> gab.fold({ emptySequence() }, { sequenceOf(it) }) }
- return asep to bsep
-}
+public fun Sequence>.separateValidated(): Pair, Sequence> =
+ fold(sequenceOf() to sequenceOf()) { (invalids, valids), validated ->
+ when (validated) {
+ is Valid -> invalids to valids + validated.value
+ is Invalid -> invalids + validated.value to valids
+ }
+ }
public fun Sequence>.sequence(): Either> =
traverse(::identity)
diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/SequenceKTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/SequenceKTest.kt
index 1ad6bffe6f2..8e77cffad6f 100644
--- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/SequenceKTest.kt
+++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/SequenceKTest.kt
@@ -307,5 +307,31 @@ class SequenceKTest : UnitSpec() {
ints.asSequence().filterOption().toList() shouldBe ints.filterOption()
}
}
+
+ "separateEither" {
+ checkAll(Arb.sequence(Arb.int())) { ints ->
+ val sequence = ints.map {
+ if (it % 2 == 0) it.left()
+ else it.right()
+ }
+
+ val (lefts, rights) = sequence.separateEither()
+
+ lefts.toList() to rights.toList() shouldBe ints.partition { it % 2 == 0 }
+ }
+ }
+
+ "separateValidated" {
+ checkAll(Arb.sequence(Arb.int())) { ints ->
+ val sequence = ints.map {
+ if (it % 2 == 0) it.invalid()
+ else it.valid()
+ }
+
+ val (invalids, valids) = sequence.separateValidated()
+
+ invalids.toList() to valids.toList() shouldBe ints.partition { it % 2 == 0 }
+ }
+ }
}
}