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

Cu f31fp2 unify constructors #2278

Merged
merged 16 commits into from Mar 3, 2021
@@ -1,8 +1,8 @@
package generic

import arrow.core.Left
import arrow.core.Right
import arrow.core.computations.either
import arrow.core.Either.Right
import arrow.core.Either.Left
import io.kotlintest.fail
import io.kotlintest.shouldBe
import io.kotlintest.shouldThrow
Expand Down
Expand Up @@ -4,7 +4,7 @@ import arrow.continuations.Reset
import arrow.continuations.generic.MultiShotDelimContScope
import arrow.continuations.generic.RestrictedScope
import arrow.core.Either
import arrow.core.Left
import arrow.core.Either.Left
import arrow.core.Tuple2
import arrow.core.Tuple3
import arrow.core.test.UnitSpec
Expand Down
Expand Up @@ -193,8 +193,8 @@ sealed class AndThen<A, B> : (A) -> B {
private tailrec fun <I, A, B> step(a: A, t: I, fn: (A) -> AndThen<I, Either<A, B>>): B {
val af = fn(a)(t)
return when (af) {
is Either.Right -> af.b
is Either.Left -> step(af.a, t, fn)
is Either.Right -> af.value
is Either.Left -> step(af.value, t, fn)
}
}

Expand Down
Expand Up @@ -990,7 +990,7 @@ sealed class Either<out A, out B> {
if (n <= 0) emptyList<B>().right()
else when (this) {
is Left -> this
is Right -> List(n) { this.b }.right()
is Right -> List(n) { this.value }.right()
}

inline fun <C> traverse(fa: (B) -> Iterable<C>): List<Either<A, C>> =
Expand All @@ -1001,7 +1001,7 @@ sealed class Either<out A, out B> {

inline fun <AA, C> traverseValidated(fa: (B) -> Validated<AA, C>): Validated<AA, Either<A, C>> =
when (this) {
is Right -> fa(this.b).map { Right(it) }
is Right -> fa(this.value).map { Right(it) }
is Left -> this.valid()
}

Expand All @@ -1019,7 +1019,7 @@ sealed class Either<out A, out B> {

inline fun findOrNull(predicate: (B) -> Boolean): B? =
when (this) {
is Right -> if (predicate(this.b)) this.b else null
is Right -> if (predicate(this.value)) this.value else null
is Left -> null
}

Expand All @@ -1033,39 +1033,25 @@ sealed class Either<out A, out B> {
/**
* The left side of the disjoint union, as opposed to the [Right] side.
*/
data class Left<out A> constructor(
@Deprecated("Use value instead", ReplaceWith("value"))
val a: A
) : Either<A, Nothing>() {
val value: A = a
data class Left<out A> constructor(val value: A) : Either<A, Nothing>() {
override val isLeft = true
override val isRight = false

override fun toString(): String = "Either.Left($a)"
override fun toString(): String = "Either.Left($value)"

companion object {
@Deprecated("Deprecated, use the constructor instead", ReplaceWith("Either.Left(a)", "arrow.core.Either"))
operator fun <A> invoke(a: A): Either<A, Nothing> = Left(a)
}
companion object
}

/**
* The right side of the disjoint union, as opposed to the [Left] side.
*/
data class Right<out B> constructor(
@Deprecated("Use value instead", ReplaceWith("value"))
val b: B
) : Either<Nothing, B>() {
val value: B = b
data class Right<out B> constructor(val value: B) : Either<Nothing, B>() {
override val isLeft = false
override val isRight = true

override fun toString(): String = "Either.Right($b)"
override fun toString(): String = "Either.Right($value)"

companion object {
@Deprecated("Deprecated, use the constructor instead", ReplaceWith("Either.Right(b)", "arrow.core.Either"))
operator fun <B> invoke(b: B): Either<Nothing, B> = Right(b)
}
companion object
}

override fun toString(): String = fold(
Expand All @@ -1081,34 +1067,22 @@ sealed class Either<out A, out B> {

companion object {

@Deprecated(
"This constructor is duplicated with Either.Left. Use Either.Left instead.",
ReplaceWith("Either.Left(left)", "arrow.core.Either")
)
fun <L> left(left: L): Either<L, Nothing> = Left(left)

@Deprecated(
"This constructor is duplicated with Either.Right. Use Either.Right instead.",
ReplaceWith("Either.Right(right)", "arrow.core.Either")
)
fun <R> right(right: R): Either<Nothing, R> = Right(right)

@PublishedApi
internal val leftUnit: Either<Unit, Nothing> =
left(Unit)
Left(Unit)

@PublishedApi
internal val unit: Either<Nothing, Unit> = right(Unit)
internal val unit: Either<Nothing, Unit> = Right(Unit)

fun <A> fromNullable(a: A?): Either<Unit, A> = a?.right() ?: Unit.left()

tailrec fun <L, A, B> tailRecM(a: A, f: (A) -> Either<L, Either<A, B>>): Either<L, B> {
return when (val ev = f(a)) {
is Left -> Left(ev.a)
is Left -> Left(ev.value)
is Right -> {
when (val b = ev.b) {
is Left -> tailRecM(b.a, f)
is Right -> Right(b.b)
when (val b = ev.value) {
is Left -> tailRecM(b.value, f)
is Right -> Right(b.value)
}
}
}
Expand Down Expand Up @@ -1137,7 +1111,7 @@ sealed class Either<out A, out B> {
* @return [Either.Right] if evaluation succeed, [Either.Left] otherwise
*/
inline fun <L, R> conditionally(test: Boolean, ifFalse: () -> L, ifTrue: () -> R): Either<L, R> =
if (test) right(ifTrue()) else left(ifFalse())
if (test) Right(ifTrue()) else Left(ifFalse())

@Deprecated("Use the inline version. Hidden for binary compat", level = DeprecationLevel.HIDDEN)
suspend inline fun <R> catch(f: suspend () -> R): Either<Throwable, R> =
Expand Down Expand Up @@ -1375,10 +1349,6 @@ sealed class Either<out A, out B> {
mapConst(Unit)
}

fun <L> Left(left: L): Either<L, Nothing> = Left(left)

fun <R> Right(right: R): Either<Nothing, R> = Right(right)

fun <A, B> Semigroup.Companion.either(SA: Semigroup<A>, SB: Semigroup<B>): Semigroup<Either<A, B>> =
EitherSemigroup(SA, SB)

Expand Down Expand Up @@ -1587,19 +1557,19 @@ inline fun <A> Any?.rightIfNull(default: () -> A): Either<A, Nothing?> = when (t
*/
inline fun <A, B, C> Either<A, B>.handleErrorWith(f: (A) -> Either<C, B>): Either<C, B> =
when (this) {
is Left -> f(this.a)
is Left -> f(this.value)
is Right -> this
}

inline fun <A, B> Either<A, B>.handleError(f: (A) -> B): Either<A, B> =
when (this) {
is Left -> f(a).right()
is Left -> f(value).right()
is Right -> this
}

inline fun <A, B, C> Either<A, B>.redeem(fe: (A) -> C, fa: (B) -> C): Either<A, C> =
when (this) {
is Left -> fe(a).right()
is Left -> fe(value).right()
is Right -> map(fa)
}

Expand All @@ -1612,12 +1582,12 @@ operator fun <A : Comparable<A>, B : Comparable<B>> Either<A, B>.compareTo(other
fun <A, B> Either<A, B>.combine(SGA: Semigroup<A>, SGB: Semigroup<B>, b: Either<A, B>): Either<A, B> =
when (this) {
is Left -> when (b) {
is Left -> Left(SGA.run { a.combine(b.a) })
is Left -> Left(SGA.run { value.combine(b.value) })
is Right -> this
}
is Right -> when (b) {
is Left -> b
is Right -> Either.right(SGB.run { this@combine.b.combine(b.b) })
is Right -> Either.Right(SGB.run { this@combine.value.combine(b.value) })
}
}

Expand Down Expand Up @@ -1666,7 +1636,7 @@ fun <A, B> Either<A, B>.replicate(n: Int, MB: Monoid<B>): Either<A, B> =
else MB.run {
when (this@replicate) {
is Left -> this@replicate
is Right -> List(n) { this@replicate.b }.combineAll().right()
is Right -> List(n) { this@replicate.value }.combineAll().right()
}
}

Expand All @@ -1683,14 +1653,14 @@ fun <A, B, C> Either<A, Either<B, C>>.selectM(f: Either<A, (B) -> C>): Either<A,

inline fun <A, B> Either<A, B>.ensure(error: () -> A, predicate: (B) -> Boolean): Either<A, B> =
when (this) {
is Right -> if (predicate(this.b)) this else error().left()
is Right -> if (predicate(this.value)) this else error().left()
is Left -> this
}

inline fun <A, B, C, D> Either<A, B>.redeemWith(fa: (A) -> Either<C, D>, fb: (B) -> Either<C, D>): Either<C, D> =
when (this) {
is Left -> fa(this.a)
is Right -> fb(this.b)
is Left -> fa(this.value)
is Right -> fb(this.value)
}

fun <A, B> Either<A, Iterable<B>>.sequence(): List<Either<A, B>> =
Expand Down
51 changes: 12 additions & 39 deletions arrow-libs/core/arrow-core-data/src/main/kotlin/arrow/core/Eval.kt
Expand Up @@ -62,8 +62,8 @@ sealed class Eval<out A> {
fun <A, B> tailRecM(a: A, f: (A) -> Eval<Either<A, B>>): Eval<B> =
f(a).flatMap { eval: Either<A, B> ->
when (eval) {
is Either.Left -> tailRecM(eval.a, f)
is Either.Right -> just(eval.b)
is Either.Left -> tailRecM(eval.value, f)
is Either.Right -> just(eval.value)
}
}

Expand Down Expand Up @@ -144,35 +144,8 @@ sealed class Eval<out A> {
fun raise(t: Throwable): Eval<Nothing> =
defer { throw t }

@Deprecated(
"This constructor is deprecated in favor of the Now constructor",
ReplaceWith("Eval.now(kotlin.Unit)", "arrow.core.Eval")
)
val Unit: Eval<Unit> = Now(kotlin.Unit)

@Deprecated(
"This constructor is deprecated in favor of the Now constructor",
ReplaceWith("Eval.now(true)", "arrow.core.Eval")
)
val True: Eval<Boolean> = Now(true)

@Deprecated(
"This constructor is deprecated in favor of the Now constructor",
ReplaceWith("Eval.now(false)", "arrow.core.Eval")
)
val False: Eval<Boolean> = Now(false)

@Deprecated(
"This constructor is deprecated in favor of the Now constructor",
ReplaceWith("Eval.now(0)", "arrow.core.Eval")
)
val Zero: Eval<Int> = Now(0)

@Deprecated(
"This constructor is deprecated in favor of the Now constructor",
ReplaceWith("Eval.now(1)", "arrow.core.Eval")
)
val One: Eval<Int> = Now(1)
@PublishedApi
internal val unit: Eval<Unit> = Now(Unit)

/**
* Collapse the call stack for eager evaluations.
Expand Down Expand Up @@ -265,15 +238,15 @@ sealed class Eval<out A> {
b: Eval<B>,
map: (A, B) -> C
): Eval<C> =
mapN(a, b, Unit, Unit, Unit, Unit, Unit, Unit, Unit) { aa, bb, _, _, _, _, _, _, _ -> map(aa, bb) }
mapN(a, b, unit, unit, unit, unit, unit, unit, unit) { aa, bb, _, _, _, _, _, _, _ -> map(aa, bb) }

fun <A, B, C, D> mapN(
a: Eval<A>,
b: Eval<B>,
c: Eval<C>,
map: (A, B, C) -> D
): Eval<D> =
mapN(a, b, c, Unit, Unit, Unit, Unit, Unit, Unit, Unit) { aa, bb, cc, _, _, _, _, _, _, _ -> map(aa, bb, cc) }
mapN(a, b, c, unit, unit, unit, unit, unit, unit, unit) { aa, bb, cc, _, _, _, _, _, _, _ -> map(aa, bb, cc) }

fun <A, B, C, D, E> mapN(
a: Eval<A>,
Expand All @@ -282,7 +255,7 @@ sealed class Eval<out A> {
d: Eval<D>,
map: (A, B, C, D) -> E
): Eval<E> =
mapN(a, b, c, d, Unit, Unit, Unit, Unit, Unit, Unit) { aa, bb, cc, dd, _, _, _, _, _, _ -> map(aa, bb, cc, dd) }
mapN(a, b, c, d, unit, unit, unit, unit, unit, unit) { aa, bb, cc, dd, _, _, _, _, _, _ -> map(aa, bb, cc, dd) }

fun <A, B, C, D, E, F> mapN(
a: Eval<A>,
Expand All @@ -292,7 +265,7 @@ sealed class Eval<out A> {
e: Eval<E>,
map: (A, B, C, D, E) -> F
): Eval<F> =
mapN(a, b, c, d, e, Unit, Unit, Unit, Unit, Unit) { aa, bb, cc, dd, ee, _, _, _, _, _ -> map(aa, bb, cc, dd, ee) }
mapN(a, b, c, d, e, unit, unit, unit, unit, unit) { aa, bb, cc, dd, ee, _, _, _, _, _ -> map(aa, bb, cc, dd, ee) }

fun <A, B, C, D, E, F, G> mapN(
a: Eval<A>,
Expand All @@ -303,7 +276,7 @@ sealed class Eval<out A> {
f: Eval<F>,
map: (A, B, C, D, E, F) -> G
): Eval<G> =
mapN(a, b, c, d, e, f, Unit, Unit, Unit, Unit) { aa, bb, cc, dd, ee, ff, _, _, _, _ -> map(aa, bb, cc, dd, ee, ff) }
mapN(a, b, c, d, e, f, unit, unit, unit, unit) { aa, bb, cc, dd, ee, ff, _, _, _, _ -> map(aa, bb, cc, dd, ee, ff) }

fun <A, B, C, D, E, F, G, H> mapN(
a: Eval<A>,
Expand All @@ -315,7 +288,7 @@ sealed class Eval<out A> {
g: Eval<G>,
map: (A, B, C, D, E, F, G) -> H
): Eval<H> =
mapN(a, b, c, d, e, f, g, Unit, Unit, Unit) { aa, bb, cc, dd, ee, ff, gg, _, _, _ -> map(aa, bb, cc, dd, ee, ff, gg) }
mapN(a, b, c, d, e, f, g, unit, unit, unit) { aa, bb, cc, dd, ee, ff, gg, _, _, _ -> map(aa, bb, cc, dd, ee, ff, gg) }

fun <A, B, C, D, E, F, G, H, I> mapN(
a: Eval<A>,
Expand All @@ -328,7 +301,7 @@ sealed class Eval<out A> {
h: Eval<H>,
map: (A, B, C, D, E, F, G, H) -> I
): Eval<I> =
mapN(a, b, c, d, e, f, g, h, Unit, Unit) { aa, bb, cc, dd, ee, ff, gg, hh, _, _ -> map(aa, bb, cc, dd, ee, ff, gg, hh) }
mapN(a, b, c, d, e, f, g, h, unit, unit) { aa, bb, cc, dd, ee, ff, gg, hh, _, _ -> map(aa, bb, cc, dd, ee, ff, gg, hh) }

fun <A, B, C, D, E, F, G, H, I, J> mapN(
a: Eval<A>,
Expand All @@ -342,7 +315,7 @@ sealed class Eval<out A> {
i: Eval<I>,
map: (A, B, C, D, E, F, G, H, I) -> J
): Eval<J> =
mapN(a, b, c, d, e, f, g, h, i, Unit) { aa, bb, cc, dd, ee, ff, gg, hh, ii, _ -> map(aa, bb, cc, dd, ee, ff, gg, hh, ii) }
mapN(a, b, c, d, e, f, g, h, i, unit) { aa, bb, cc, dd, ee, ff, gg, hh, ii, _ -> map(aa, bb, cc, dd, ee, ff, gg, hh, ii) }

fun <A, B, C, D, E, F, G, H, I, J, K> mapN(
a: Eval<A>,
Expand Down