Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deprecate combineAll in favour of fold #2687

Merged
merged 13 commits into from
Mar 15, 2022
4 changes: 4 additions & 0 deletions arrow-libs/core/arrow-core/api/arrow-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -2943,6 +2943,8 @@ public abstract interface class arrow/typeclasses/Monoid : arrow/typeclasses/Sem
public static fun either (Larrow/typeclasses/Monoid;Larrow/typeclasses/Monoid;)Larrow/typeclasses/Monoid;
public abstract fun empty ()Ljava/lang/Object;
public static fun endo ()Larrow/typeclasses/Monoid;
public abstract fun fold (Ljava/util/Collection;)Ljava/lang/Object;
public abstract fun fold (Ljava/util/List;)Ljava/lang/Object;
public static fun list ()Larrow/typeclasses/Monoid;
public static fun map (Larrow/typeclasses/Semigroup;)Larrow/typeclasses/Monoid;
public static fun option (Larrow/typeclasses/Semigroup;)Larrow/typeclasses/Monoid;
Expand Down Expand Up @@ -2973,6 +2975,8 @@ public final class arrow/typeclasses/Monoid$Companion {
public final class arrow/typeclasses/Monoid$DefaultImpls {
public static fun combineAll (Larrow/typeclasses/Monoid;Ljava/util/Collection;)Ljava/lang/Object;
public static fun combineAll (Larrow/typeclasses/Monoid;Ljava/util/List;)Ljava/lang/Object;
public static fun fold (Larrow/typeclasses/Monoid;Ljava/util/Collection;)Ljava/lang/Object;
public static fun fold (Larrow/typeclasses/Monoid;Ljava/util/List;)Ljava/lang/Object;
public static fun maybeCombine (Larrow/typeclasses/Monoid;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public static fun plus (Larrow/typeclasses/Monoid;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1496,10 +1496,9 @@ public fun <A, B> Either<A, B>.combine(SGA: Semigroup<A>, SGB: Semigroup<B>, b:
}
}

@Deprecated("use fold instead", ReplaceWith("fold(Monoid.either(MA, MB))", "arrow.core.fold", "arrow.typeclasses.Monoid"))
public fun <A, B> Iterable<Either<A, B>>.combineAll(MA: Monoid<A>, MB: Monoid<B>): Either<A, B> =
fold(Right(MB.empty()) as Either<A, B>) { acc, e ->
acc.combine(MA, MB, e)
}
fold(Monoid.either(MA, MB))

/**
* Given [B] is a sub type of [C], re-type this value from Either<A, B> to Either<A, B>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -657,19 +657,19 @@ public fun <A, B> Ior<A, B>.replicate(SA: Semigroup<A>, n: Int): Ior<A, List<B>>
is Ior.Right -> Ior.Right(List(n) { value })
is Ior.Left -> this
is Ior.Both -> bimap(
{ List(n - 1) { leftValue }.fold(leftValue, { acc, a -> SA.run { acc + a } }) },
{ List(n - 1) { leftValue }.fold(leftValue) { acc, a -> SA.run { acc + a } } },
{ List(n) { rightValue } }
)
}

public fun <A, B> Ior<A, B>.replicate(SA: Semigroup<A>, n: Int, MB: Monoid<B>): Ior<A, B> =
if (n <= 0) Ior.Right(MB.empty())
else when (this) {
is Ior.Right -> Ior.Right(MB.run { List(n) { value }.combineAll() })
is Ior.Right -> Ior.Right(MB.run { List(n) { value }.fold() })
is Ior.Left -> this
is Ior.Both -> bimap(
{ List(n - 1) { leftValue }.fold(leftValue, { acc, a -> SA.run { acc + a } }) },
{ MB.run { List(n) { rightValue }.combineAll() } }
{ MB.run { List(n) { rightValue }.fold() } }
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -704,11 +704,9 @@ public fun <A, B> Iterable<Ior<A, B>>.unalign(): Pair<List<A>, List<B>> =
public inline fun <A, B, C> Iterable<C>.unalign(fa: (C) -> Ior<A, B>): Pair<List<A>, List<B>> =
map(fa).unalign()

public fun <A> Iterable<A>.combineAll(MA: Monoid<A>): A = MA.run {
this@combineAll.fold(empty()) { acc, a ->
acc.combine(a)
}
}
@Deprecated("use fold instead", ReplaceWith("fold(MA)", "arrow.core.fold"))
public fun <A> Iterable<A>.combineAll(MA: Monoid<A>): A =
fold(MA)

/**
* Returns the first element as [Some(element)][Some], or [None] if the iterable is empty.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -904,14 +904,13 @@ public fun <A> A.some(): Option<A> = Some(this)

public fun <A> none(): Option<A> = None

@Deprecated("use fold instead", ReplaceWith("fold(Monoid.option(MA))", "arrow.core.fold", "arrow.typeclasses.Monoid"))
public fun <A> Iterable<Option<A>>.combineAll(MA: Monoid<A>): Option<A> =
fold(Option(MA.empty())) { acc, a ->
acc.combine(MA, a)
}
fold(Monoid.option(MA))

public fun <A> Option<A>.combineAll(MA: Monoid<A>): A = MA.run {
foldLeft(empty()) { acc, a -> acc.combine(a) }
}
@Deprecated("use getOrElse instead", ReplaceWith("getOrElse { MA.empty() }"))
public fun <A> Option<A>.combineAll(MA: Monoid<A>): A =
getOrElse { MA.empty() }

public inline fun <A> Option<A>.ensure(error: () -> Unit, predicate: (A) -> Boolean): Option<A> =
when (this) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,9 @@ private fun <X, Y> alignRec(ls: Sequence<X>, rs: Sequence<Y>): Sequence<Ior<X, Y
}
}

public fun <A> Sequence<A>.combineAll(MA: Monoid<A>): A = MA.run {
this@combineAll.fold(empty()) { acc, a ->
acc.combine(a)
}
}
@Deprecated("use fold instead", ReplaceWith("fold(MA)", "arrow.core.fold"))
public fun <A> Sequence<A>.combineAll(MA: Monoid<A>): A =
fold(MA)

public fun <A, B> Sequence<A>.crosswalk(f: (A) -> Sequence<B>): Sequence<Sequence<B>> =
fold(emptySequence()) { bs, a ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@ public fun <E, A> Validated<E, A>.fold(MA: Monoid<A>): A = MA.run {
foldLeft(empty()) { acc, a -> acc.combine(a) }
}

@Deprecated("use fold instead", ReplaceWith("fold(MA)", "arrow.core.fold"))
public fun <E, A> Validated<E, A>.combineAll(MA: Monoid<A>): A =
fold(MA)

Expand Down
54 changes: 49 additions & 5 deletions arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/map.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package arrow.core

import arrow.core.Either.Left
import arrow.core.Either.Right
import arrow.typeclasses.Monoid
import arrow.typeclasses.Semigroup
import kotlin.collections.flatMap as _flatMap

Expand Down Expand Up @@ -122,7 +123,18 @@ public inline fun <Key, B, C, D, E, F, G, H, I> Map<Key, B>.zip(
): Map<Key, I> {
val destination = LinkedHashMap<Key, I>(size)
for ((key, bb) in this) {
Nullable.zip(c[key], d[key], e[key], f[key], g[key], h[key]) { cc, dd, ee, ff, gg, hh -> map(key, bb, cc, dd, ee, ff, gg, hh) }
Nullable.zip(c[key], d[key], e[key], f[key], g[key], h[key]) { cc, dd, ee, ff, gg, hh ->
map(
key,
bb,
cc,
dd,
ee,
ff,
gg,
hh
)
}
?.let { l -> destination.put(key, l) }
}
return destination
Expand All @@ -140,7 +152,19 @@ public inline fun <Key, B, C, D, E, F, G, H, I, J> Map<Key, B>.zip(
): Map<Key, J> {
val destination = LinkedHashMap<Key, J>(size)
for ((key, bb) in this) {
Nullable.zip(c[key], d[key], e[key], f[key], g[key], h[key], i[key]) { cc, dd, ee, ff, gg, hh, ii -> map(key, bb, cc, dd, ee, ff, gg, hh, ii) }
Nullable.zip(c[key], d[key], e[key], f[key], g[key], h[key], i[key]) { cc, dd, ee, ff, gg, hh, ii ->
map(
key,
bb,
cc,
dd,
ee,
ff,
gg,
hh,
ii
)
}
?.let { l -> destination.put(key, l) }
}
return destination
Expand All @@ -159,7 +183,16 @@ public inline fun <Key, B, C, D, E, F, G, H, I, J, K> Map<Key, B>.zip(
): Map<Key, K> {
val destination = LinkedHashMap<Key, K>(size)
for ((key, bb) in this) {
Nullable.zip(c[key], d[key], e[key], f[key], g[key], h[key], i[key], j[key]) { cc, dd, ee, ff, gg, hh, ii, jj -> map(key, bb, cc, dd, ee, ff, gg, hh, ii, jj) }
Nullable.zip(
c[key],
d[key],
e[key],
f[key],
g[key],
h[key],
i[key],
j[key]
) { cc, dd, ee, ff, gg, hh, ii, jj -> map(key, bb, cc, dd, ee, ff, gg, hh, ii, jj) }
?.let { l -> destination.put(key, l) }
}
return destination
Expand All @@ -179,7 +212,17 @@ public inline fun <Key, B, C, D, E, F, G, H, I, J, K, L> Map<Key, B>.zip(
): Map<Key, L> {
val destination = LinkedHashMap<Key, L>(size)
for ((key, bb) in this) {
Nullable.zip(c[key], d[key], e[key], f[key], g[key], h[key], i[key], j[key], k[key]) { cc, dd, ee, ff, gg, hh, ii, jj, kk ->
Nullable.zip(
c[key],
d[key],
e[key],
f[key],
g[key],
h[key],
i[key],
j[key],
k[key]
) { cc, dd, ee, ff, gg, hh, ii, jj, kk ->
map(key, bb, cc, dd, ee, ff, gg, hh, ii, jj, kk)
}?.let { l -> destination.put(key, l) }
}
Expand Down Expand Up @@ -436,8 +479,9 @@ public fun <K, A> Map<K, A>.combine(SG: Semigroup<A>, b: Map<K, A>): Map<K, A> =
else b.foldLeft(this@combine) { my, (k, a) -> my + Pair(k, a.maybeCombine(my[k])) }
}

@Deprecated("use fold instead", ReplaceWith("fold(Monoid.map(SG))", "arrow.core.fold", "arrow.typeclasses.Monoid"))
public fun <K, A> Iterable<Map<K, A>>.combineAll(SG: Semigroup<A>): Map<K, A> =
fold(emptyMap()) { acc, map -> acc.combine(SG, map) }
fold(Monoid.map(SG))

public inline fun <K, A, B> Map<K, A>.foldLeft(b: B, f: (B, Map.Entry<K, A>) -> B): B {
var result = b
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import arrow.core.None
import arrow.core.Option
import arrow.core.Validated
import arrow.core.combine
import arrow.core.combineAll
import arrow.core.compose
import arrow.core.flatten
import arrow.core.fold
import arrow.core.identity
import kotlin.jvm.JvmName
import kotlin.jvm.JvmStatic
Expand All @@ -24,13 +24,26 @@ public interface Monoid<A> : Semigroup<A> {
/**
* Combine an [Collection] of [A] values.
*/
@Deprecated("use fold instead", ReplaceWith("fold()"))
public fun Collection<A>.combineAll(): A =
if (isEmpty()) empty() else reduce { a, b -> a.combine(b) }
fold()

/**
* Combine an array of [A] values.
*/
public fun combineAll(elems: List<A>): A = elems.combineAll()
@Deprecated("use fold instead", ReplaceWith("fold(elems)"))
public fun combineAll(elems: List<A>): A = fold(elems)

/**
* Fold an [Collection] of [A] values.
*/
public fun Collection<A>.fold(): A =
if (isEmpty()) empty() else reduce { a, b -> a.combine(b) }

/**
* Fold an array of [A] values.
*/
public fun fold(elems: List<A>): A = elems.fold()

public companion object {
@JvmStatic
Expand Down Expand Up @@ -186,14 +199,14 @@ public interface Monoid<A> : Semigroup<A> {
override fun Either<L, R>.combine(b: Either<L, R>): Either<L, R> =
combine(MOL, MOR, b)

override fun Collection<Either<L, R>>.combineAll(): Either<L, R> =
combineAll(MOL, MOR)
override fun Collection<Either<L, R>>.fold(): Either<L, R> =
fold(either(MOL, MOR))

override fun fold(elems: List<Either<L, R>>): Either<L, R> =
elems.fold(either(MOL, MOR))

override fun Either<L, R>.maybeCombine(b: Either<L, R>?): Either<L, R> =
b?.let { combine(MOL, MOR, it) } ?: this

override fun combineAll(elems: List<Either<L, R>>): Either<L, R> =
elems.combineAll(MOL, MOR)
}

private class PairMonoid<A, B>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@ public interface Fold<S, A> {
/**
* Alias for fold.
*/
@Deprecated("use fold instead", ReplaceWith("fold(M, source)"))
public fun combineAll(M: Monoid<A>, source: S): A =
foldMap(M, source, ::identity)
fold(M, source)

/**
* Get all targets of the [Fold]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import arrow.typeclasses.Monoid
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.orNull
import io.kotest.property.checkAll

class EveryTest : UnitSpec() {
init {
Expand Down