diff --git a/arrow-libs/core/arrow-core/api/arrow-core.api b/arrow-libs/core/arrow-core/api/arrow-core.api index 838a55a597a..eccd19495fc 100644 --- a/arrow-libs/core/arrow-core/api/arrow-core.api +++ b/arrow-libs/core/arrow-core/api/arrow-core.api @@ -214,33 +214,22 @@ public final class arrow/core/Either$Companion { public final fun tryCatch (Lkotlin/jvm/functions/Function0;)Larrow/core/Either; public final fun tryCatch (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Larrow/core/Either; public final fun tryCatchAndFlatten (Lkotlin/jvm/functions/Function0;)Larrow/core/Either; - public final fun zipOrAccumulate (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function10;)Larrow/core/Either; - public final fun zipOrAccumulate (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function9;)Larrow/core/Either; - public final fun zipOrAccumulate (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function8;)Larrow/core/Either; - public final fun zipOrAccumulate (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function7;)Larrow/core/Either; - public final fun zipOrAccumulate (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function6;)Larrow/core/Either; - public final fun zipOrAccumulate (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function5;)Larrow/core/Either; - public final fun zipOrAccumulate (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function4;)Larrow/core/Either; - public final fun zipOrAccumulate (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function3;)Larrow/core/Either; - public final fun zipOrAccumulate (Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function2;)Larrow/core/Either; - public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function10;)Larrow/core/Either; - public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function9;)Larrow/core/Either; - public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function8;)Larrow/core/Either; - public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function7;)Larrow/core/Either; - public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function6;)Larrow/core/Either; - public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function5;)Larrow/core/Either; - public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function4;)Larrow/core/Either; - public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function3;)Larrow/core/Either; - public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function2;)Larrow/core/Either; - public final fun zipOrAccumulateNonEmptyList (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function10;)Larrow/core/Either; - public final fun zipOrAccumulateNonEmptyList (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function9;)Larrow/core/Either; - public final fun zipOrAccumulateNonEmptyList (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function8;)Larrow/core/Either; - public final fun zipOrAccumulateNonEmptyList (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function7;)Larrow/core/Either; - public final fun zipOrAccumulateNonEmptyList (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function6;)Larrow/core/Either; - public final fun zipOrAccumulateNonEmptyList (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function5;)Larrow/core/Either; - public final fun zipOrAccumulateNonEmptyList (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function4;)Larrow/core/Either; - public final fun zipOrAccumulateNonEmptyList (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function3;)Larrow/core/Either; - public final fun zipOrAccumulateNonEmptyList (Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function2;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function9;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function8;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function7;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function6;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function5;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function4;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function9;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function8;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function7;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function6;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function5;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function4;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;)Larrow/core/Either; + public final fun zipOrAccumulate (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Larrow/core/Either; } public final class arrow/core/Either$Left : arrow/core/Either { diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt index 198cfef509f..1a8bf673e4c 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt @@ -1,18 +1,17 @@ -@file:OptIn(ExperimentalContracts::class) +@file:OptIn(ExperimentalContracts::class, ExperimentalTypeInference::class) package arrow.core 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.RaiseAccumulate +import arrow.core.raise.catch import arrow.core.raise.either +import arrow.core.raise.zipOrAccumulate import arrow.typeclasses.Monoid import arrow.typeclasses.Semigroup import kotlin.contracts.ExperimentalContracts @@ -1378,14 +1377,8 @@ public sealed class Either { @JvmStatic @JvmName("tryCatch") - public inline fun catch(f: () -> R): Either { - contract { callsInPlace(f, InvocationKind.EXACTLY_ONCE) } - return try { - f().right() - } catch (t: Throwable) { - t.nonFatalOrThrow().left() - } - } + public inline fun catch(f: () -> R): Either = + catch({ f().right() }) { e -> e.left() } @Deprecated( RedundantAPI + "Compose catch with flatten instead", @@ -1481,474 +1474,196 @@ public sealed class Either { public fun lift(fa: (A) -> C, fb: (B) -> D): (Either) -> Either = { it.bimap(fa, fb) } - - public inline fun zipOrAccumulate( - combine: (E, E) -> E, - a: Either, - b: Either, - transform: (A, B) -> Z, - ): Either { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(combine, a, b, unit, unit, unit, unit, unit, unit, unit, unit) { aa, bb, _, _, _, _, _, _, _, _ -> - transform(aa, bb) - } - } - - public inline fun zipOrAccumulate( - combine: (E, E) -> E, - a: Either, - b: Either, - c: Either, - transform: (A, B, C) -> Z, - ): Either { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(combine, a, b, c, unit, unit, unit, unit, unit, unit, unit) { aa, bb, cc, _, _, _, _, _, _, _ -> - transform(aa, bb, cc) - } - } - - public inline fun zipOrAccumulate( - combine: (E, E) -> E, - a: Either, - b: Either, - c: Either, - d: Either, - transform: (A, B, C, D) -> Z, - ): Either { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(combine, a, b, c, d, unit, unit, unit, unit, unit, unit) { aa, bb, cc, dd, _, _, _, _, _, _ -> - transform(aa, bb, cc, dd) - } - } - - public inline fun zipOrAccumulate( - combine: (E, E) -> E, - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - transform: (A, B, C, D, EE) -> Z, - ): Either { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(combine, a, b, c, d, e, unit, unit, unit, unit, unit) { aa, bb, cc, dd, ee, _, _, _, _, _ -> - transform(aa, bb, cc, dd, ee) - } - } - - public inline fun zipOrAccumulate( - combine: (E, E) -> E, - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - f: Either, - transform: (A, B, C, D, EE, FF) -> Z, - ): Either { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(combine, a, b, c, d, e, f, unit, unit, unit, unit) { aa, bb, cc, dd, ee, ff, _, _, _, _ -> - transform(aa, bb, cc, dd, ee, ff) - } - } - - public inline fun zipOrAccumulate( - combine: (E, E) -> E, - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - transform: (A, B, C, D, EE, F, G) -> Z, - ): Either { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(combine, a, b, c, d, e, f, g, unit, unit, unit) { aa, bb, cc, dd, ee, ff, gg, _, _, _ -> - transform(aa, bb, cc, dd, ee, ff, gg) - } - } - - public inline fun zipOrAccumulate( - combine: (E, E) -> E, - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - h: Either, - transform: (A, B, C, D, EE, F, G, H) -> Z, - ): Either { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(combine, a, b, c, d, e, f, g, h, unit, unit) { aa, bb, cc, dd, ee, ff, gg, hh, _, _ -> - transform(aa, bb, cc, dd, ee, ff, gg, hh) - } - } - - public inline fun zipOrAccumulate( - combine: (E, E) -> E, - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - h: Either, - i: Either, - transform: (A, B, C, D, EE, F, G, H, I) -> Z, - ): Either { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(combine, a, b, c, d, e, f, g, h, i, unit) { aa, bb, cc, dd, ee, ff, gg, hh, ii, _ -> - transform(aa, bb, cc, dd, ee, ff, gg, hh, ii) - } - } - - @Suppress("DuplicatedCode") - public inline fun zipOrAccumulate( - combine: (E, E) -> E, - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - h: Either, - i: Either, - j: Either, - transform: (A, B, C, D, EE, F, G, H, I, J) -> Z, - ): Either { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return if (a is Right && b is Right && c is Right && d is Right && e is Right && f is Right && g is Right && h is Right && i is Right && j is Right) { - Right(transform(a.value, b.value, c.value, d.value, e.value, f.value, g.value, h.value, i.value, j.value)) - } else { - var accumulatedError: Any? = EmptyValue - accumulatedError = if (a is Left) a.value else accumulatedError - accumulatedError = if (b is Left) EmptyValue.combine(accumulatedError, b.value, combine) else accumulatedError - accumulatedError = if (c is Left) EmptyValue.combine(accumulatedError, c.value, combine) else accumulatedError - accumulatedError = if (d is Left) EmptyValue.combine(accumulatedError, d.value, combine) else accumulatedError - accumulatedError = if (e is Left) EmptyValue.combine(accumulatedError, e.value, combine) else accumulatedError - accumulatedError = if (f is Left) EmptyValue.combine(accumulatedError, f.value, combine) else accumulatedError - accumulatedError = if (g is Left) EmptyValue.combine(accumulatedError, g.value, combine) else accumulatedError - accumulatedError = if (h is Left) EmptyValue.combine(accumulatedError, h.value, combine) else accumulatedError - accumulatedError = if (i is Left) EmptyValue.combine(accumulatedError, i.value, combine) else accumulatedError - accumulatedError = if (j is Left) EmptyValue.combine(accumulatedError, j.value, combine) else accumulatedError - - @Suppress("UNCHECKED_CAST") - (Left(accumulatedError as E)) - } - } - - public inline fun zipOrAccumulate( - a: Either, - b: Either, - transform: (A, B) -> Z, - ): Either, Z> { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, unit, unit, unit, unit, unit, unit, unit, unit) { aa, bb, _, _, _, _, _, _, _, _ -> - transform(aa, bb) - } - } - - public inline fun zipOrAccumulate( - a: Either, - b: Either, - c: Either, - transform: (A, B, C) -> Z, - ): Either, Z> { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, unit, unit, unit, unit, unit, unit, unit) { aa, bb, cc, _, _, _, _, _, _, _ -> - transform(aa, bb, cc) - } + public inline fun zipOrAccumulate( + combine: (R, R) -> R, + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + block: (A, B) -> C + ): Either = either { + zipOrAccumulate(combine, action1, action2, block) } - public inline fun zipOrAccumulate( - a: Either, - b: Either, - c: Either, - d: Either, - transform: (A, B, C, D) -> Z, - ): Either, Z> { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, unit, unit, unit, unit, unit, unit) { aa, bb, cc, dd, _, _, _, _, _, _ -> - transform(aa, bb, cc, dd) - } + public inline fun zipOrAccumulate( + combine: (R, R) -> R, + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + block: (A, B, C) -> D + ): Either = either { + zipOrAccumulate(combine, action1, action2, action3, block) } - public inline fun zipOrAccumulate( - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - transform: (A, B, C, D, EE) -> Z, - ): Either, Z> { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, e, unit, unit, unit, unit, unit) { aa, bb, cc, dd, ee, _, _, _, _, _ -> - transform(aa, bb, cc, dd, ee) - } + public inline fun zipOrAccumulate( + combine: (R, R) -> R, + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + block: (A, B, C, D) -> E + ): Either = either { + zipOrAccumulate(combine, action1, action2, action3, action4, block) } - public inline fun zipOrAccumulate( - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - f: Either, - transform: (A, B, C, D, EE, FF) -> Z, - ): Either, Z> { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, e, f, unit, unit, unit, unit) { aa, bb, cc, dd, ee, ff, _, _, _, _ -> - transform(aa, bb, cc, dd, ee, ff) - } + public inline fun zipOrAccumulate( + combine: (R, R) -> R, + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + @BuilderInference action5: RaiseAccumulate.() -> E, + block: (A, B, C, D, E) -> F + ): Either = either { + zipOrAccumulate(combine, action1, action2, action3, action4, action5, block) } - public inline fun zipOrAccumulate( - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - transform: (A, B, C, D, EE, F, G) -> Z, - ): Either, Z> { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, e, f, g, unit, unit, unit) { aa, bb, cc, dd, ee, ff, gg, _, _, _ -> - transform(aa, bb, cc, dd, ee, ff, gg) - } - } - - public inline fun zipOrAccumulate( - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - h: Either, - transform: (A, B, C, D, EE, F, G, H) -> Z, - ): Either, Z> { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, e, f, g, h, unit, unit) { aa, bb, cc, dd, ee, ff, gg, hh, _, _ -> - transform(aa, bb, cc, dd, ee, ff, gg, hh) - } + public inline fun zipOrAccumulate( + combine: (R, R) -> R, + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + @BuilderInference action5: RaiseAccumulate.() -> E, + @BuilderInference action6: RaiseAccumulate.() -> F, + block: (A, B, C, D, E, F) -> G + ): Either = either { + zipOrAccumulate(combine, action1, action2, action3, action4, action5, action6, block) } - public inline fun zipOrAccumulate( - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - h: Either, - i: Either, - transform: (A, B, C, D, EE, F, G, H, I) -> Z, - ): Either, Z> { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, e, f, g, h, i, unit) { aa, bb, cc, dd, ee, ff, gg, hh, ii, _ -> - transform(aa, bb, cc, dd, ee, ff, gg, hh, ii) - } + public inline fun zipOrAccumulate( + combine: (R, R) -> R, + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + @BuilderInference action5: RaiseAccumulate.() -> E, + @BuilderInference action6: RaiseAccumulate.() -> F, + @BuilderInference action7: RaiseAccumulate.() -> G, + block: (A, B, C, D, E, F, G) -> H + ): Either = either { + zipOrAccumulate(combine, action1, action2, action3, action4, action5, action6, action7, block) } - @Suppress("DuplicatedCode") - public inline fun zipOrAccumulate( - a: Either, - b: Either, - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - h: Either, - i: Either, - j: Either, - transform: (A, B, C, D, EE, F, G, H, I, J) -> Z, - ): Either, Z> { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return if (a is Right && b is Right && c is Right && d is Right && e is Right && f is Right && g is Right && h is Right && i is Right && j is Right) { - Right(transform(a.value, b.value, c.value, d.value, e.value, f.value, g.value, h.value, i.value, j.value)) - } else { - val list = buildList(9) { - if (a is Left) add(a.value) - if (b is Left) add(b.value) - if (c is Left) add(c.value) - if (d is Left) add(d.value) - if (e is Left) add(e.value) - if (f is Left) add(f.value) - if (g is Left) add(g.value) - if (h is Left) add(h.value) - if (i is Left) add(i.value) - if (j is Left) add(j.value) - } - Left(NonEmptyList(list[0], list.drop(1))) - } + public inline fun zipOrAccumulate( + combine: (R, R) -> R, + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + @BuilderInference action5: RaiseAccumulate.() -> E, + @BuilderInference action6: RaiseAccumulate.() -> F, + @BuilderInference action7: RaiseAccumulate.() -> G, + @BuilderInference action8: RaiseAccumulate.() -> H, + block: (A, B, C, D, E, F, G, H) -> I + ): Either = either { + zipOrAccumulate(combine, action1, action2, action3, action4, action5, action6, action7, action8, block) } - @JvmName("zipOrAccumulateNonEmptyList") - public inline fun zipOrAccumulate( - a: EitherNel, - b: EitherNel, - transform: (A, B) -> Z, - ): EitherNel { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, unit, unit, unit, unit, unit, unit, unit, unit) { aa, bb, _, _, _, _, _, _, _, _ -> - transform(aa, bb) - } + public inline fun zipOrAccumulate( + combine: (R, R) -> R, + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + @BuilderInference action5: RaiseAccumulate.() -> E, + @BuilderInference action6: RaiseAccumulate.() -> F, + @BuilderInference action7: RaiseAccumulate.() -> G, + @BuilderInference action8: RaiseAccumulate.() -> H, + @BuilderInference action9: RaiseAccumulate.() -> I, + block: (A, B, C, D, E, F, G, H, I) -> J + ): Either = either { + zipOrAccumulate(combine, action1, action2, action3, action4, action5, action6, action7, action8, action9, block) } - @JvmName("zipOrAccumulateNonEmptyList") - public inline fun zipOrAccumulate( - a: EitherNel, - b: EitherNel, - c: EitherNel, - transform: (A, B, C) -> Z, - ): EitherNel { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, unit, unit, unit, unit, unit, unit, unit) { aa, bb, cc, _, _, _, _, _, _, _ -> - transform(aa, bb, cc) - } + public inline fun zipOrAccumulate( + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + block: (A, B) -> C, + ): Either, C> = either { + zipOrAccumulate(action1, action2, block) } - @JvmName("zipOrAccumulateNonEmptyList") - public inline fun zipOrAccumulate( - a: EitherNel, - b: EitherNel, - c: EitherNel, - d: EitherNel, - transform: (A, B, C, D) -> Z, - ): EitherNel { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, unit, unit, unit, unit, unit, unit) { aa, bb, cc, dd, _, _, _, _, _, _ -> - transform(aa, bb, cc, dd) - } + public inline fun zipOrAccumulate( + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + block: (A, B, C) -> D, + ): Either, D> = either { + zipOrAccumulate(action1, action2, action3, block) } - @JvmName("zipOrAccumulateNonEmptyList") - public inline fun zipOrAccumulate( - a: EitherNel, - b: EitherNel, - c: EitherNel, - d: EitherNel, - e: EitherNel, - transform: (A, B, C, D, EE) -> Z, - ): EitherNel { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, e, unit, unit, unit, unit, unit) { aa, bb, cc, dd, ee, _, _, _, _, _ -> - transform(aa, bb, cc, dd, ee) - } + public inline fun zipOrAccumulate( + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + block: (A, B, C, D) -> E, + ): Either, E> = either { + zipOrAccumulate(action1, action2, action3, action4, block) } - @JvmName("zipOrAccumulateNonEmptyList") - public inline fun zipOrAccumulate( - a: EitherNel, - b: EitherNel, - c: EitherNel, - d: EitherNel, - e: EitherNel, - f: EitherNel, - transform: (A, B, C, D, EE, FF) -> Z, - ): EitherNel { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, e, f, unit, unit, unit, unit) { aa, bb, cc, dd, ee, ff, _, _, _, _ -> - transform(aa, bb, cc, dd, ee, ff) - } + public inline fun zipOrAccumulate( + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + @BuilderInference action5: RaiseAccumulate.() -> E, + block: (A, B, C, D, E) -> F, + ): Either, F> = either { + zipOrAccumulate(action1, action2, action3, action4, action5, block) } - @JvmName("zipOrAccumulateNonEmptyList") - public inline fun zipOrAccumulate( - a: EitherNel, - b: EitherNel, - c: EitherNel, - d: EitherNel, - e: EitherNel, - f: EitherNel, - g: EitherNel, - transform: (A, B, C, D, EE, F, G) -> Z, - ): EitherNel { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, e, f, g, unit, unit, unit) { aa, bb, cc, dd, ee, ff, gg, _, _, _ -> - transform(aa, bb, cc, dd, ee, ff, gg) - } + public inline fun zipOrAccumulate( + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + @BuilderInference action5: RaiseAccumulate.() -> E, + @BuilderInference action6: RaiseAccumulate.() -> F, + block: (A, B, C, D, E, F) -> G, + ): Either, G> = either { + zipOrAccumulate(action1, action2, action3, action4, action5, action6, block) } - @JvmName("zipOrAccumulateNonEmptyList") - public inline fun zipOrAccumulate( - a: EitherNel, - b: EitherNel, - c: EitherNel, - d: EitherNel, - e: EitherNel, - f: EitherNel, - g: EitherNel, - h: EitherNel, - transform: (A, B, C, D, EE, F, G, H) -> Z, - ): EitherNel { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, e, f, g, h, unit, unit) { aa, bb, cc, dd, ee, ff, gg, hh, _, _ -> - transform(aa, bb, cc, dd, ee, ff, gg, hh) - } + public inline fun zipOrAccumulate( + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + @BuilderInference action5: RaiseAccumulate.() -> E, + @BuilderInference action6: RaiseAccumulate.() -> F, + @BuilderInference action7: RaiseAccumulate.() -> G, + block: (A, B, C, D, E, F, G) -> H, + ): Either, H> = either { + zipOrAccumulate(action1, action2, action3, action4, action5, action6, action7, block) } - @JvmName("zipOrAccumulateNonEmptyList") - public inline fun zipOrAccumulate( - a: EitherNel, - b: EitherNel, - c: EitherNel, - d: EitherNel, - e: EitherNel, - f: EitherNel, - g: EitherNel, - h: EitherNel, - i: EitherNel, - transform: (A, B, C, D, EE, F, G, H, I) -> Z, - ): EitherNel { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zipOrAccumulate(a, b, c, d, e, f, g, h, i, unit) { aa, bb, cc, dd, ee, ff, gg, hh, ii, _ -> - transform(aa, bb, cc, dd, ee, ff, gg, hh, ii) - } + public inline fun zipOrAccumulate( + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + @BuilderInference action5: RaiseAccumulate.() -> E, + @BuilderInference action6: RaiseAccumulate.() -> F, + @BuilderInference action7: RaiseAccumulate.() -> G, + @BuilderInference action8: RaiseAccumulate.() -> H, + block: (A, B, C, D, E, F, G, H) -> I, + ): Either, I> = either { + zipOrAccumulate(action1, action2, action3, action4, action5, action6, action7, action8, block) } - @Suppress("DuplicatedCode") - @JvmName("zipOrAccumulateNonEmptyList") - public inline fun zipOrAccumulate( - a: EitherNel, - b: EitherNel, - c: EitherNel, - d: EitherNel, - e: EitherNel, - f: EitherNel, - g: EitherNel, - h: EitherNel, - i: EitherNel, - j: EitherNel, - transform: (A, B, C, D, EE, F, G, H, I, J) -> Z, - ): EitherNel { - contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return if (a is Right && b is Right && c is Right && d is Right && e is Right && f is Right && g is Right && h is Right && i is Right && j is Right) { - Right(transform(a.value, b.value, c.value, d.value, e.value, f.value, g.value, h.value, i.value, j.value)) - } else { - val list = buildList { - if (a is Left) addAll(a.value) - if (b is Left) addAll(b.value) - if (c is Left) addAll(c.value) - if (d is Left) addAll(d.value) - if (e is Left) addAll(e.value) - if (f is Left) addAll(f.value) - if (g is Left) addAll(g.value) - if (h is Left) addAll(h.value) - if (i is Left) addAll(i.value) - if (j is Left) addAll(j.value) - } - Left(NonEmptyList(list[0], list.drop(1))) - } + public inline fun zipOrAccumulate( + @BuilderInference action1: RaiseAccumulate.() -> A, + @BuilderInference action2: RaiseAccumulate.() -> B, + @BuilderInference action3: RaiseAccumulate.() -> C, + @BuilderInference action4: RaiseAccumulate.() -> D, + @BuilderInference action5: RaiseAccumulate.() -> E, + @BuilderInference action6: RaiseAccumulate.() -> F, + @BuilderInference action7: RaiseAccumulate.() -> G, + @BuilderInference action8: RaiseAccumulate.() -> H, + @BuilderInference action9: RaiseAccumulate.() -> I, + block: (A, B, C, D, E, F, G, H, I) -> J + ): Either, J> = either { + zipOrAccumulate(action1, action2, action3, action4, action5, action6, action7, action8, action9, block) } } @@ -2294,10 +2009,13 @@ public operator fun , B : Comparable> Either.compareT @Deprecated( RedundantAPI + "Prefer zipOrAccumulate", - ReplaceWith("Either.zipOrAccumulate({ a, bb -> SGA.run { a.combine(bb) } }, this, b) { a, bb -> SGB.run { a.combine(bb) } }") + ReplaceWith("Either.zipOrAccumulate({ a, bb -> SGA.run { a.combine(bb) } }, { this@combine.bind() }, { b.bind() }) { a, bb -> SGB.run { a.combine(bb) } }") ) public fun Either.combine(SGA: Semigroup, SGB: Semigroup, b: Either): Either = - Either.zipOrAccumulate({ a, bb -> SGA.run { a.combine(bb) } }, this, b) { a, bb -> SGB.run { a.combine(bb) } } + Either.zipOrAccumulate( + { a, bb -> SGA.run { a.combine(bb) } }, + { this@combine.bind() }, + { b.bind() }) { a, bb -> SGB.run { a.combine(bb) } } @Deprecated( RedundantAPI + "Prefer explicit fold instead", @@ -2505,7 +2223,20 @@ public inline fun Either.zip( map: (B, C, D, E, F, G, H, I, J, K) -> L, ): Either { contract { callsInPlace(map, InvocationKind.AT_MOST_ONCE) } - return either { map(bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind(), i.bind(), j.bind(), k.bind()) } + return either { + map( + bind(), + c.bind(), + d.bind(), + e.bind(), + f.bind(), + g.bind(), + h.bind(), + i.bind(), + j.bind(), + k.bind() + ) + } } @Deprecated( @@ -2664,7 +2395,7 @@ public fun E.leftNel(): EitherNel = @OptIn(ExperimentalTypeInference::class) public inline fun Either.recover(@BuilderInference recover: Raise.(E) -> A): Either { contract { callsInPlace(recover, InvocationKind.AT_MOST_ONCE) } - return when(this) { + return when (this) { is Left -> either { recover(this, value) } is Right -> this@recover } diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt index 7accba25689..4b137d53412 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt @@ -6,6 +6,7 @@ import arrow.core.test.any import arrow.core.test.either import arrow.core.test.intSmall import arrow.core.test.laws.MonoidLaws +import arrow.core.test.nonEmptyList import arrow.core.test.suspendFunThatReturnsAnyLeft import arrow.core.test.suspendFunThatReturnsAnyRight import arrow.core.test.suspendFunThatReturnsEitherAnyOrAnyOrThrows @@ -32,7 +33,7 @@ import io.kotest.property.arbitrary.short import io.kotest.property.checkAll class EitherTest : StringSpec({ - + val ARB = Arb.either(Arb.string(), Arb.int()) testLaws( @@ -602,7 +603,19 @@ class EitherTest : StringSpec({ Arb.either(Arb.string(), Arb.string()), Arb.either(Arb.string(), Arb.boolean()) ) { a, b, c, d, e, f, g, h, i -> - val res = Either.zipOrAccumulate({ e1, e2 -> "$e1$e2" }, a, b, c, d, e, f, g, h, i, ::Tuple9) + val res = Either.zipOrAccumulate( + { e1, e2 -> "$e1$e2" }, + { a.bind() }, + { b.bind() }, + { c.bind() }, + { d.bind() }, + { e.bind() }, + { f.bind() }, + { g.bind() }, + { h.bind() }, + { i.bind() }, + ::Tuple9 + ) val all = listOf(a, b, c, d, e, f, g, h, i) val expected = if (all.any { it.isLeft() }) { @@ -620,47 +633,28 @@ class EitherTest : StringSpec({ "zipOrAccumulate without Semigroup results in all Right transformed, or all Left in a NonEmptyList" { checkAll( Arb.either(Arb.string(), Arb.short()), - Arb.either(Arb.string(), Arb.byte()), - Arb.either(Arb.string(), Arb.int()), - Arb.either(Arb.string(), Arb.long()), - Arb.either(Arb.string(), Arb.float()), - Arb.either(Arb.string(), Arb.double()), - Arb.either(Arb.string(), Arb.char()), - Arb.either(Arb.string(), Arb.string()), - Arb.either(Arb.string(), Arb.boolean()) - ) { a, b, c, d, e, f, g, h, i -> - val res = Either.zipOrAccumulate(a, b, c, d, e, f, g, h, i, ::Tuple9) - val all = listOf(a, b, c, d, e, f, g, h, i) - - val expected = if (all.any { it.isLeft() }) { - all.filterIsInstance>().map { it.value }.toNonEmptyListOrNull()!!.left() - } else { - all.filterIsInstance>().map { it.value }.let { - Tuple9(it[0], it[1], it[2], it[3], it[4], it[5], it[6], it[7], it[8]).right() - } - } - - res shouldBe expected - } - } - - "zipOrAccumulate EitherNel results in all Right transformed, or all Left in a NonEmptyList" { - fun Arb.Companion.nonEmptyList(arb: Arb): Arb> = - Arb.list(arb, 1..100).map { it.toNonEmptyListOrNull()!! } - - checkAll( - Arb.either(Arb.nonEmptyList(Arb.string()), Arb.short()), Arb.either(Arb.nonEmptyList(Arb.string()), Arb.byte()), - Arb.either(Arb.nonEmptyList(Arb.string()), Arb.int()), + Arb.either(Arb.string(), Arb.int()), Arb.either(Arb.nonEmptyList(Arb.string()), Arb.long()), - Arb.either(Arb.nonEmptyList(Arb.string()), Arb.float()), + Arb.either(Arb.string(), Arb.float()), Arb.either(Arb.nonEmptyList(Arb.string()), Arb.double()), - Arb.either(Arb.nonEmptyList(Arb.string()), Arb.char()), + Arb.either(Arb.string(), Arb.char()), Arb.either(Arb.nonEmptyList(Arb.string()), Arb.string()), - Arb.either(Arb.nonEmptyList(Arb.string()), Arb.boolean()) + Arb.either(Arb.string(), Arb.boolean()) ) { a, b, c, d, e, f, g, h, i -> - val res = Either.zipOrAccumulate(a, b, c, d, e, f, g, h, i, ::Tuple9) - val all = listOf(a, b, c, d, e, f, g, h, i) + val res = Either.zipOrAccumulate( + { a.bind() }, + { b.bindNel() }, + { c.bind() }, + { d.bindNel() }, + { e.bind() }, + { f.bindNel() }, + { g.bind() }, + { h.bindNel() }, + { i.bind() }, + ::Tuple9 + ) + val all = listOf(a.toEitherNel(), b, c.toEitherNel(), d, e.toEitherNel(), f, g.toEitherNel(), h, i.toEitherNel()) val expected = if (all.any { it.isLeft() }) { all.filterIsInstance>>()