Skip to content

Commit

Permalink
Iterable test (#2960)
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Vergauwen <[email protected]>
  • Loading branch information
abendt and nomisRev authored Mar 9, 2023
1 parent e94dc2e commit a1fffdb
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 8 deletions.
1 change: 1 addition & 0 deletions arrow-libs/core/arrow-core/api/arrow-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,7 @@ public final class arrow/core/IterableKt {
public static final fun rightPadZip (Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Ljava/util/List;
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 separateIor (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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -867,14 +867,11 @@ public inline fun <A, B, C> Iterable<C>.unzip(fc: (C) -> Pair<A, B>): Pair<List<
* ```
* <!--- KNIT example-iterable-13.kt -->
*/
public fun <A, B> Iterable<Ior<A, B>>.unalign(): Pair<List<A>, List<B>> =
fold(emptyList<A>() to emptyList()) { (l, r), x ->
x.fold(
{ l + it to r },
{ l to r + it },
{ a, b -> l + a to r + b }
)
}
@Deprecated(
"The current unalign function is renamed to separateIor, and a new unalign function is going to be added to Arrow 2.0.0.",
ReplaceWith("separateIor()", "arrow.core.separateIor")
)
public fun <A, B> Iterable<Ior<A, B>>.unalign(): Pair<List<A>, List<B>> = separateIor()

/**
* after applying the given function, splits the resulting union shaped structure into its components parts
Expand All @@ -894,9 +891,28 @@ public fun <A, B> Iterable<Ior<A, B>>.unalign(): Pair<List<A>, List<B>> =
* ```
* <!--- KNIT example-iterable-14.kt -->
*/
@Deprecated(
"The current unalign function is renamed to separateIor, and a new unalign function is going to be added to Arrow 2.0.0.",
ReplaceWith("map(fa).separateIor()", "arrow.core.separateIor")
)
public inline fun <A, B, C> Iterable<C>.unalign(fa: (C) -> Ior<A, B>): Pair<List<A>, List<B>> =
map(fa).unalign()

/**
* Separate the inner [Ior] values into a pair of Lists.
*
* @receiver Iterable of Ior
* @return a tuple containing a List with the left side value from the[Ior.Left] and [Ior.Both] values and another List with the right side value from the [Ior.Right] and [Ior.Both] values.
*/
public fun <A, B> Iterable<Ior<A, B>>.separateIor(): Pair<List<A>, List<B>> =
fold(emptyList<A>() to emptyList()) { (l, r), x ->
x.fold(
{ l + it to r },
{ l to r + it },
{ a, b -> l + a to r + b }
)
}

@Deprecated("use fold instead", ReplaceWith("fold(MA)", "arrow.core.fold"))
public fun <A> Iterable<A>.combineAll(MA: Monoid<A>): A =
fold(MA)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package arrow.core

import arrow.core.test.either
import arrow.core.test.functionAToB
import arrow.core.test.ior
import arrow.core.test.option
import arrow.typeclasses.Semigroup
import io.kotest.core.spec.style.StringSpec
Expand All @@ -14,6 +15,7 @@ import io.kotest.property.arbitrary.boolean
import io.kotest.property.arbitrary.int
import io.kotest.property.arbitrary.list
import io.kotest.property.arbitrary.orNull
import io.kotest.property.arbitrary.pair
import io.kotest.property.arbitrary.string
import io.kotest.property.checkAll
import kotlin.math.max
Expand Down Expand Up @@ -551,4 +553,79 @@ class IterableTest : StringSpec({
}
}

"unzip is the inverse of zip" {
checkAll(Arb.list(Arb.int())) { xs ->

val zipped = xs.zip(xs)
val ls = zipped.unzip()
val rs = xs to xs

ls shouldBe rs
}
}

"unzip(fn)" {
checkAll(Arb.list(Arb.pair(Arb.int(), Arb.string()))) { xs ->
xs.unzip { it } shouldBe xs.unzip()
}
}

"unalign is the inverse of align" {
checkAll(Arb.list(Arb.int()), Arb.list(Arb.string())) { a, b ->
a.align(b).unalign() shouldBe (a to b)
}
}

"align is the inverse of unalign" {
checkAll(Arb.list(Arb.ior(Arb.int(), Arb.string()))) { xs ->
val (a, b) = xs.unalign()
a.align(b) shouldBe xs
}
}

"unalign(fn)" {
checkAll(Arb.list(Arb.ior(Arb.int(), Arb.string()))) { xs ->
xs.unalign { it } shouldBe xs.unalign()
}
}

"salign" {
checkAll(Arb.list(Arb.int())) { xs ->
xs.salign(Semigroup.int(), xs) shouldBe xs.map { it + it }
}
}

"reduceOrNull is compatible with reduce from stdlib" {
checkAll(Arb.list(Arb.string())) { xs ->

val rs = xs.reduceOrNull({ it }) { a, b ->
a + b
}

if (xs.isEmpty()) {
rs.shouldBeNull()
} else {
rs shouldBe xs.reduce {
a,b -> a +b
}
}
}
}

"reduceRightNull is compatible with reduce from stdlib" {
checkAll(Arb.list(Arb.string())) { xs ->

val rs = xs.reduceRightNull({ it }) { a, b ->
a + b
}

if (xs.isEmpty()) {
rs.shouldBeNull()
} else {
rs shouldBe xs.reduceRight {
a,b -> a +b
}
}
}
}
})

0 comments on commit a1fffdb

Please sign in to comment.