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

Deprecation of Semigroup and Monoid #2935

Merged
merged 37 commits into from
Mar 10, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
25701ca
Start deprecation of Semigroup and Monoid
serras Feb 17, 2023
c04602d
Deprecation for EmptyValue
serras Feb 17, 2023
915b740
Update API files
serras Feb 17, 2023
848b423
Deprecation for map
serras Feb 17, 2023
42d32c5
Update API files
serras Feb 17, 2023
bb4234c
Deprecation for NonEmptyList, Option, and Pair
serras Feb 17, 2023
1fd6dde
Deprecation for Raise builders
serras Feb 17, 2023
c45c6d4
Merge branch 'main' into deprecate-semigroup-monoid
serras Feb 17, 2023
f47a982
Merge branch 'main' into deprecate-semigroup-monoid
serras Feb 23, 2023
5148d55
Deprecation for Ior and zips
serras Feb 23, 2023
570634d
Update API files
serras Feb 23, 2023
e58c82f
Merge branch 'main' into deprecate-semigroup-monoid
serras Feb 23, 2023
0ecbcb4
Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Op…
serras Feb 27, 2023
c50c804
Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Op…
serras Feb 27, 2023
1d509a8
Merge branch 'main' into deprecate-semigroup-monoid
serras Mar 2, 2023
b8e0086
Remove emptyCombine + add missing Validated#zip
serras Mar 2, 2023
1020548
Fix more merge woes
serras Mar 2, 2023
7deae73
Fix incorrect 'combine' implementation
serras Mar 3, 2023
316809f
Remove unnecessary combine
serras Mar 3, 2023
9f367da
More Either woes
serras Mar 3, 2023
21fa9e5
Merge remote-tracking branch 'origin/main' into deprecate-semigroup-m…
nomisRev Mar 7, 2023
bccec6e
Update PR, introduce Semigroup::combine, and revert Ior changes in fa…
nomisRev Mar 7, 2023
627a8a5
Merge remote-tracking branch 'origin/main' into deprecate-semigroup-m…
nomisRev Mar 8, 2023
5ff3a7b
Revert unrelated change
nomisRev Mar 8, 2023
58c9296
A few improvements
serras Mar 8, 2023
d0e4c81
Deprecate Semiring
serras Mar 8, 2023
212e706
Rework Laws
serras Mar 8, 2023
bc0f97c
Update API files
serras Mar 8, 2023
1f31084
GitHub Actions
serras Mar 8, 2023
38f362e
Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/It…
nomisRev Mar 8, 2023
bbe260a
Merge branch 'main' into deprecate-semigroup-monoid
serras Mar 9, 2023
439c8e3
Try to fix Native compilation
serras Mar 9, 2023
7779714
Deprecate Const, Endo, Semigroup constructors, and revert Either#comb…
nomisRev Mar 10, 2023
28ba065
Merge branch 'deprecate-semigroup-monoid' of github.com:arrow-kt/arro…
nomisRev Mar 10, 2023
b13ebe9
Merge remote-tracking branch 'origin/main' into deprecate-semigroup-m…
nomisRev Mar 10, 2023
cdd5e50
Update API files
nomisRev Mar 10, 2023
ac8e6a2
Retrigger CI
nomisRev Mar 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions arrow-libs/core/arrow-core/api/arrow-core.api

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import arrow.core.Either.Companion.resolve
import arrow.core.Either.Left
import arrow.core.Either.Right
import arrow.core.Either.Right.Companion.unit
import arrow.core.computations.ResultEffect.bind
import arrow.core.continuations.Eager
import arrow.core.continuations.EagerEffect
import arrow.core.continuations.Effect
import arrow.core.continuations.Token
import arrow.core.raise.Raise
import arrow.core.raise.either
import arrow.typeclasses.Monoid
import arrow.typeclasses.MonoidDeprecation
import arrow.typeclasses.Semigroup
import arrow.typeclasses.SemigroupDeprecation
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
Expand Down Expand Up @@ -2279,17 +2278,31 @@ public operator fun <A : Comparable<A>, B : Comparable<B>> Either<A, B>.compareT

@Deprecated(
RedundantAPI + "Prefer zipOrAccumulate",
ReplaceWith("Either.zipOrAccumulate(combineA, this, b, combineB)")
)
public fun <A, B> Either<A, B>.combine(combineA: (A, A) -> A, combineB: (B, B) -> B, b: Either<A, B>): Either<A, B> =
Either.zipOrAccumulate(combineA, this, b, combineB)
serras marked this conversation as resolved.
Show resolved Hide resolved

@Deprecated(
SemigroupDeprecation + "Prefer zipOrAccumulate",
ReplaceWith("Either.zipOrAccumulate({ a, bb -> SGA.run { a.combine(bb) } }, this, b) { a, bb -> SGB.run { a.combine(bb) } }")
)
public fun <A, B> Either<A, B>.combine(SGA: Semigroup<A>, SGB: Semigroup<B>, b: Either<A, B>): Either<A, B> =
Either.zipOrAccumulate({ a, bb -> SGA.run { a.combine(bb) } }, this, b) { a, bb -> SGB.run { a.combine(bb) } }
combine({ a, bb -> SGA.run { a.combine(bb) } }, { a, bb -> SGB.run { a.combine(bb) } }, b)

@Deprecated(
RedundantAPI + "Prefer explicit fold instead",
ReplaceWith("fold(Monoid.either(MA, MB))", "arrow.core.fold", "arrow.typeclasses.Monoid")
ReplaceWith("fold(initialB.right()) { x: Either<A, B>, y -> Either.zipOrAccumulate(combineA, x, y, combineB) }", "arrow.core.fold", "arrow.core.right")
)
public fun <A, B> Iterable<Either<A, B>>.combineAll(combineA: (A, A) -> A, initialB: B, combineB: (B, B) -> B): Either<A, B> =
serras marked this conversation as resolved.
Show resolved Hide resolved
fold(initialB.right()) { x: Either<A, B>, y -> Either.zipOrAccumulate(combineA, x, y, combineB) }

@Deprecated(
MonoidDeprecation,
ReplaceWith("combineAll({ x, y -> MA.run { x.combine(y) } }, MB.empty(), { x, y -> MB.run { x.combine(y) } })")
)
public fun <A, B> Iterable<Either<A, B>>.combineAll(MA: Monoid<A>, MB: Monoid<B>): Either<A, B> =
fold(Monoid.either(MA, MB))
combineAll({ x, y -> MA.run { x.combine(y) } }, MB.empty(), { x, y -> MB.run { x.combine(y) } })

/**
* Given [B] is a sub type of [C], re-type this value from Either<A, B> to Either<A, C>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import arrow.core.Either.Right
import arrow.core.raise.Raise
import arrow.core.raise.either
import arrow.typeclasses.Monoid
import arrow.typeclasses.MonoidDeprecation
import arrow.typeclasses.Semigroup
import arrow.typeclasses.SemigroupDeprecation
import kotlin.Result.Companion.success
import kotlin.experimental.ExperimentalTypeInference

Expand Down Expand Up @@ -342,46 +344,59 @@ public inline fun <E, A, B> Iterable<A>.traverseValidated(
@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
public inline fun <E, A, B> Iterable<A>.traverse(
semigroup: Semigroup<E>,
combine: (E, E) -> E,
f: (A) -> Validated<E, B>
): Validated<E, List<B>> =
semigroup.run {
fold(Valid(ArrayList<B>(collectionSizeOrDefault(10))) as Validated<E, MutableList<B>>) { 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))
}
fold(Valid(ArrayList<B>(collectionSizeOrDefault(10))) as Validated<E, MutableList<B>>) { 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(combine(acc.value, res.value))
}
}
}

@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
@Deprecated(SemigroupDeprecation, ReplaceWith("semigroup.run { traverse({ x, y -> x.combine(y) }, f) }"))
public inline fun <E, A, B> Iterable<A>.traverse(
semigroup: Semigroup<E>,
f: (A) -> Validated<E, B>
): Validated<E, List<B>> = semigroup.run {
nomisRev marked this conversation as resolved.
Show resolved Hide resolved
traverse({ x, y -> x.combine(y) }, f)
}

@Deprecated("traverseValidated is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse"))
public inline fun <E, A, B> Iterable<A>.traverseValidated(f: (A) -> ValidatedNel<E, B>): ValidatedNel<E, List<B>> =
traverse(f)

@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
public inline fun <E, A, B> Iterable<A>.traverse(f: (A) -> ValidatedNel<E, B>): ValidatedNel<E, List<B>> =
traverse(Semigroup.nonEmptyList(), f)
traverse({ x, y -> x + y }, f)

@Deprecated("sequenceValidated is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence(semigroup)", "arrow.core.sequence"))
public fun <E, A> Iterable<Validated<E, A>>.sequenceValidated(semigroup: Semigroup<E>): Validated<E, List<A>> =
sequence(semigroup)

public fun <E, A> Iterable<Validated<E, A>>.sequence(semigroup: Semigroup<E>): Validated<E, List<A>> =
traverse(semigroup, ::identity)
public fun <E, A> Iterable<Validated<E, A>>.sequence(combine: (E, E) -> E): Validated<E, List<A>> =
traverse(combine, ::identity)

@Deprecated(SemigroupDeprecation, ReplaceWith("semigroup.run { sequence { x, y -> x.combine(y) } }"))
public fun <E, A> Iterable<Validated<E, A>>.sequence(semigroup: Semigroup<E>): Validated<E, List<A>> = semigroup.run {
sequence { x, y -> x.combine(y) }
}

@Deprecated("sequenceValidated is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence"))
public fun <E, A> Iterable<ValidatedNel<E, A>>.sequenceValidated(): ValidatedNel<E, List<A>> =
sequence()

public fun <E, A> Iterable<ValidatedNel<E, A>>.sequence(): ValidatedNel<E, List<A>> =
traverse(Semigroup.nonEmptyList(), ::identity)
sequence { x, y -> x + y }

@Deprecated("traverseOption is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse"))
public inline fun <A, B> Iterable<A>.traverseOption(f: (A) -> Option<B>): Option<List<B>> =
Expand Down Expand Up @@ -758,17 +773,27 @@ public fun <A, B> Iterable<A>.align(b: Iterable<B>): List<Ior<A, B>> =
this.align(b, ::identity)

/**
* aligns two structures and combine them with the given [Semigroup.combine]
* aligns two structures and combine them with [combine]
*/
public fun <A> Iterable<A>.salign(
SG: Semigroup<A>,
combine: (A, A) -> A,
other: Iterable<A>
): Iterable<A> = SG.run {
): Iterable<A> =
align(other) {
it.fold(::identity, ::identity) { a, b ->
a.combine(b)
combine(a, b)
}
}

/**
* aligns two structures and combine them with the given [Semigroup.combine]
*/
@Deprecated(SemigroupDeprecation, ReplaceWith("SG.run { salign({ a, b -> a.combine(b) }, other) }"))
nomisRev marked this conversation as resolved.
Show resolved Hide resolved
public fun <A> Iterable<A>.salign(
nomisRev marked this conversation as resolved.
Show resolved Hide resolved
SG: Semigroup<A>,
other: Iterable<A>
): Iterable<A> = SG.run {
salign({ a, b -> a.combine(b) }, other)
}

/**
Expand Down Expand Up @@ -1148,16 +1173,20 @@ public fun <B, A : B> Iterable<A>.widen(): Iterable<B> =
public fun <B, A : B> List<A>.widen(): List<B> =
this

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

public fun <A, B> Iterable<A>.foldMap(
initial: B,
combine: (B, B) -> B,
f: (A) -> B
): B = this.fold(initial) { acc: B, x: A -> combine(acc, f(x)) }

@Deprecated(MonoidDeprecation, ReplaceWith("MB.run { foldMap(empty(), { acc, a -> acc.combine(a) }, f) }"))
public fun <A, B> Iterable<A>.foldMap(MB: Monoid<B>, f: (A) -> B): B = MB.run {
this@foldMap.fold(empty()) { acc, a ->
acc.combine(f(a))
}
this@foldMap.foldMap(empty(), { acc, a -> acc.combine(a) }, f)
}

public fun <A, B> Iterable<A>.crosswalk(f: (A) -> Iterable<B>): List<List<B>> =
Expand Down Expand Up @@ -1199,9 +1228,14 @@ public fun <A> Iterable<A>.replicate(n: Int): List<List<A>> =
if (n <= 0) emptyList()
else toList().let { l -> List(n) { l } }

public fun <A> Iterable<A>.replicate(n: Int, MA: Monoid<A>): List<A> =
if (n <= 0) listOf(MA.empty())
else this@replicate.zip(replicate(n - 1, MA)) { a, xs -> MA.run { a + xs } }
public fun <A> Iterable<A>.replicate(n: Int, empty: A, combine: (A, A) -> A): List<A> =
if (n <= 0) listOf(empty)
else zip(replicate(n - 1, empty, combine), combine)

@Deprecated(MonoidDeprecation, ReplaceWith("MA.run { replicate(n, MA.empty()) { a, xs -> a.combine(xs) } }"))
public fun <A> Iterable<A>.replicate(n: Int, MA: Monoid<A>): List<A> = MA.run {
replicate(n, MA.empty()) { a, xs -> a.combine(xs) }
}

public operator fun <A : Comparable<A>> Iterable<A>.compareTo(other: Iterable<A>): Int =
align(other) { ior -> ior.fold({ 1 }, { -1 }, { a1, a2 -> a1.compareTo(a2) }) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package arrow.core
import arrow.core.Either.Left
import arrow.core.Either.Right
import arrow.typeclasses.Semigroup
import arrow.typeclasses.SemigroupDeprecation
import kotlin.experimental.ExperimentalTypeInference
import kotlin.jvm.JvmStatic

Expand Down Expand Up @@ -215,10 +216,12 @@ public class NonEmptyList<out A>(
public fun <B> align(b: NonEmptyList<B>): NonEmptyList<Ior<A, B>> =
NonEmptyList(Ior.Both(head, b.head), tail.align(b.tail))

public fun salign(combine: (A, A) -> @UnsafeVariance A, b: NonEmptyList<@UnsafeVariance A>): NonEmptyList<A> =
NonEmptyList(combine(head, b.head), tail.salign(combine, b.tail).toList())

@Deprecated(SemigroupDeprecation, ReplaceWith("SA.run { salign({ x, y -> x.combine(y) }, b) }"))
public fun salign(SA: Semigroup<@UnsafeVariance A>, b: NonEmptyList<@UnsafeVariance A>): NonEmptyList<A> =
SA.run {
NonEmptyList(head.combine(b.head), tail.salign(SA, b.tail).toList())
}
SA.run { salign({ x, y -> x.combine(y) }, b) }

public fun <B> padZip(other: NonEmptyList<B>): NonEmptyList<Pair<A?, B?>> =
NonEmptyList(head to other.head, tail.padZip(other.tail))
Expand Down Expand Up @@ -450,7 +453,7 @@ public inline fun <E, A, B> NonEmptyList<A>.traverseValidated(
@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
public inline fun <E, A, B> NonEmptyList<A>.traverse(
semigroup: Semigroup<E>,
combine: (E, E) -> E,
f: (A) -> Validated<E, B>
): Validated<E, NonEmptyList<B>> =
nomisRev marked this conversation as resolved.
Show resolved Hide resolved
fold<A, Validated<E, MutableList<B>>>(mutableListOf<B>().valid()) { acc, a ->
Expand All @@ -461,17 +464,30 @@ public inline fun <E, A, B> NonEmptyList<A>.traverse(
}
is Invalid -> when (acc) {
is Valid -> res
is Invalid -> semigroup.run { Invalid(acc.value.combine(res.value)) }
is Invalid -> Invalid(combine(acc.value, res.value))
}
}
}.map { requireNotNull(it.toNonEmptyListOrNull()) }

@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
@Deprecated(SemigroupDeprecation, ReplaceWith("semigroup.run { traverse({ x, y -> x.combine(y) }, f) }"))
public inline fun <E, A, B> NonEmptyList<A>.traverse(
semigroup: Semigroup<E>,
f: (A) -> Validated<E, B>
): Validated<E, NonEmptyList<B>> =
semigroup.run { traverse({ x, y -> x.combine(y) }, f) }

@Deprecated("sequenceValidated is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence"))
public fun <E, A> NonEmptyList<Validated<E, A>>.sequenceValidated(semigroup: Semigroup<E>): Validated<E, NonEmptyList<A>> =
sequence(semigroup)

public fun <E, A> NonEmptyList<Validated<E, A>>.sequence(combine: (E, E) -> E): Validated<E, NonEmptyList<A>> =
traverse(combine, ::identity)

@Deprecated(SemigroupDeprecation, ReplaceWith("semigroup.run { sequence { x, y -> x.combine(y) } }"))
public fun <E, A> NonEmptyList<Validated<E, A>>.sequence(semigroup: Semigroup<E>): Validated<E, NonEmptyList<A>> =
traverse(semigroup, ::identity)
semigroup.run { sequence { x, y -> x.combine(y) } }

@Deprecated(
"traverseOption is being renamed to traverse to simplify the Arrow API",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import arrow.core.Either.Right
import arrow.core.raise.OptionRaise
import arrow.core.raise.option
import arrow.typeclasses.Monoid
import arrow.typeclasses.MonoidDeprecation
import arrow.typeclasses.Semigroup
import arrow.typeclasses.SemigroupDeprecation
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
Expand Down Expand Up @@ -1042,10 +1044,10 @@ public sealed class Option<out A> {

@Deprecated(
NicheAPI + "Prefer when or fold instead",
ReplaceWith("MB.run { this.fold({ empty() }) { a -> empty().combine(f(a)) } }")
ReplaceWith("MB.run { this.fold({ empty() }) { empty().combine(f(it)) } }")
)
public inline fun <B> foldMap(MB: Monoid<B>, f: (A) -> B): B = MB.run {
foldLeft(empty()) { b, a -> b.combine(f(a)) }
fold({ empty() }) { empty().combine(f(it)) }
}

@Deprecated(
Expand Down Expand Up @@ -1293,9 +1295,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"))
@Deprecated("use fold instead", ReplaceWith("fold(None as Option<A>) { x, y -> x.combine(combine, y) }"))
serras marked this conversation as resolved.
Show resolved Hide resolved
public fun <A> Iterable<Option<A>>.combineAll(combine: (A, A) -> A): Option<A> =
fold(None as Option<A>) { x, y -> x.combine(combine, y) }

@Deprecated(SemigroupDeprecation, ReplaceWith("MA.run { combineAll { x, y -> x + y } }"))
public fun <A> Iterable<Option<A>>.combineAll(MA: Monoid<A>): Option<A> =
fold(Monoid.option(MA))
MA.run { combineAll { x, y -> x + y } }

@Deprecated("use getOrElse instead", ReplaceWith("getOrElse { MA.empty() }"))
public fun <A> Option<A>.combineAll(MA: Monoid<A>): A =
Expand Down Expand Up @@ -1396,11 +1402,15 @@ public inline fun <A, B> Option<A>.redeemWith(fe: (Unit) -> Option<B>, fb: (A) -

@Deprecated(
NicheAPI + "Prefer using the Option DSL or map",
ReplaceWith("MA.run { this.map { List(n) { it }.fold(empty()) { acc, v -> acc + v } } }")
ReplaceWith("this.map { List(n) { it }.fold(empty(), combine) }")
)
public fun <A> Option<A>.replicate(n: Int, initial: A, combine: (A, A) -> A): Option<A> =
if (n <= 0) Some(initial)
else map { a -> List(n) { a }.fold(initial, combine) }

@Deprecated(MonoidDeprecation, ReplaceWith("MA.run { replicate(n, empty()) { acc, v -> acc + v } }"))
public fun <A> Option<A>.replicate(n: Int, MA: Monoid<A>): Option<A> = MA.run {
nomisRev marked this conversation as resolved.
Show resolved Hide resolved
if (n <= 0) Some(empty())
else map { a -> List(n) { a }.fold(empty()) { acc, v -> acc + v } }
replicate(n, empty()) { acc, v -> acc + v }
}

@Deprecated(
Expand Down Expand Up @@ -1596,16 +1606,19 @@ public fun <B, A : B> Option<A>.widen(): Option<B> =

public fun <K, V> Option<Pair<K, V>>.toMap(): Map<K, V> = this.toList().toMap()

public fun <A> Option<A>.combine(SGA: Semigroup<A>, b: Option<A>): Option<A> =
public fun <A> Option<A>.combine(combineA: (A, A) -> A, b: Option<A>): Option<A> =
when (this) {
is Some -> when (b) {
is Some -> Some(SGA.run { value.combine(b.value) })
is Some -> Some(combineA(value, b.value))
None -> this
}

None -> b
}

@Deprecated(SemigroupDeprecation, ReplaceWith("SGA.run { combine({ x, y -> x + y }, b) }"))
public fun <A> Option<A>.combine(SGA: Semigroup<A>, b: Option<A>): Option<A> =
SGA.run { combine({ x, y -> x + y }, b) }
serras marked this conversation as resolved.
Show resolved Hide resolved

public operator fun <A : Comparable<A>> Option<A>.compareTo(other: Option<A>): Int = fold(
{ other.fold({ 0 }, { -1 }) },
{ a1 ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package arrow.core

import arrow.typeclasses.Semigroup
import arrow.typeclasses.SemigroupDeprecation
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName

Expand All @@ -13,8 +14,12 @@ public operator fun <A : Comparable<A>, B : Comparable<B>> Pair<A, B>.compareTo(
else first
}

public fun <A, B> Pair<A, B>.combine(SA: Semigroup<A>, SB: Semigroup<B>, b: Pair<A, B>): Pair<A, B> {
public fun <A, B> Pair<A, B>.combine(combineA: (A, A) -> A, combineB: (B, B) -> B, b: Pair<A, B>): Pair<A, B> {
val (xa, xb) = this
val (ya, yb) = b
return Pair(SA.run { xa.combine(ya) }, SB.run { xb.combine(yb) })
return Pair(combineA(xa, ya), combineB(xb, yb))
nomisRev marked this conversation as resolved.
Show resolved Hide resolved
}

@Deprecated(SemigroupDeprecation, ReplaceWith("combine({ x, y -> SA.run { x + y } }, { x, y -> SB.run { x + y } }, b)"))
public fun <A, B> Pair<A, B>.combine(SA: Semigroup<A>, SB: Semigroup<B>, b: Pair<A, B>): Pair<A, B> =
combine({ x, y -> SA.run { x + y } }, { x, y -> SB.run { x + y } }, b)
Loading