Skip to content

Commit

Permalink
Implement 'align' using 'buildList' (#2886)
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Vergauwen <nomisRev@users.noreply.github.com>
  • Loading branch information
serras and nomisRev committed Jan 10, 2023
1 parent 55e8c48 commit 4d1adbf
Showing 1 changed file with 14 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,19 @@ public fun <A, B> Iterable<A>.rightPadZip(other: Iterable<B>): List<Pair<A, B?>>
* <!--- KNIT example-iterable-07.kt -->
*/
public inline fun <A, B, C> Iterable<A>.align(b: Iterable<B>, fa: (Ior<A, B>) -> C): List<C> =
this.align(b).map(fa)
buildList(maxOf(this.collectionSizeOrDefault(10), b.collectionSizeOrDefault(10))) {
val first = this@align.iterator()
val second = b.iterator()
while (first.hasNext() || second.hasNext()) {
val element: Ior<A, B> = when {
first.hasNext() && second.hasNext() -> Ior.Both(first.next(), second.next())
first.hasNext() -> first.next().leftIor()
second.hasNext() -> second.next().rightIor()
else -> throw IllegalStateException("this should never happen")
}
add(fa(element))
}
}

/**
* Combines two structures by taking the union of their shapes and using Ior to hold the elements.
Expand All @@ -651,18 +663,7 @@ public inline fun <A, B, C> Iterable<A>.align(b: Iterable<B>, fa: (Ior<A, B>) ->
* <!--- KNIT example-iterable-08.kt -->
*/
public fun <A, B> Iterable<A>.align(b: Iterable<B>): List<Ior<A, B>> =
alignRec(this, b)

@Suppress("NAME_SHADOWING")
private fun <X, Y> alignRec(ls: Iterable<X>, rs: Iterable<Y>): List<Ior<X, Y>> {
val ls = if (ls is List) ls else ls.toList()
val rs = if (rs is List) rs else rs.toList()
return when {
ls.isEmpty() -> rs.map { it.rightIor() }
rs.isEmpty() -> ls.map { it.leftIor() }
else -> listOf(Ior.Both(ls.first(), rs.first())) + alignRec(ls.drop(1), rs.drop(1))
}
}
this.align(b, ::identity)

/**
* aligns two structures and combine them with the given [Semigroup.combine]
Expand Down

0 comments on commit 4d1adbf

Please sign in to comment.