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-fb6x32 Clean up Arrow Syntax based on API Review #2330

Merged
merged 22 commits into from Mar 22, 2021
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
135f7df
Apply API review comments
nomisRev Mar 17, 2021
fb4073f
Update ap / apEval
nomisRev Mar 18, 2021
7ecfb9f
Remove/deprecate mproduct
nomisRev Mar 19, 2021
cba0da3
Deprecate tailRecM
nomisRev Mar 19, 2021
cc23fbb
Update AndThen extensions deprecation
nomisRev Mar 19, 2021
2b2ad2b
Merge remote-tracking branch 'origin/master' into cu-fv6x32-clean-up-…
nomisRev Mar 19, 2021
b558bb5
Fix build
nomisRev Mar 19, 2021
5eee674
Apply suggestions from code review
nomisRev Mar 22, 2021
1428167
Update arrow-libs/core/arrow-core/src/main/kotlin/arrow/core/extensio…
nomisRev Mar 22, 2021
3263c84
Update arrow-libs/core/arrow-core/src/main/kotlin/arrow/core/extensio…
nomisRev Mar 22, 2021
991ea88
Update arrow-libs/core/arrow-core/src/main/kotlin/arrow/core/extensio…
nomisRev Mar 22, 2021
83debc3
Update arrow-libs/core/arrow-core/src/main/kotlin/arrow/core/extensio…
nomisRev Mar 22, 2021
7e9f754
Apply review suggestions, and fix build
nomisRev Mar 22, 2021
7d56e6a
Merge branch 'cu-fv6x32-clean-up-arrow-core-review' of github.com:arr…
nomisRev Mar 22, 2021
558711f
Update arrow-libs/core/arrow-core-data/src/main/kotlin/arrow/core/Con…
nomisRev Mar 22, 2021
5c4ace1
Update arrow-libs/core/arrow-core/src/main/kotlin/arrow/core/extensio…
nomisRev Mar 22, 2021
51f6be4
Update arrow-libs/core/arrow-core/src/main/kotlin/arrow/core/extensio…
nomisRev Mar 22, 2021
7819432
Update arrow-libs/core/arrow-core/src/main/kotlin/arrow/core/extensio…
nomisRev Mar 22, 2021
3fcc65d
Update arrow-libs/core/arrow-core-data/src/main/kotlin/arrow/core/Ior.kt
nomisRev Mar 22, 2021
7788d0d
Fix build
nomisRev Mar 22, 2021
15d80f4
Merge branch 'cu-fv6x32-clean-up-arrow-core-review' of github.com:arr…
nomisRev Mar 22, 2021
ba763f6
Merge branch 'master' into cu-fv6x32-clean-up-arrow-core-review
nomisRev Mar 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -2,6 +2,9 @@ package arrow.core

import arrow.KindDeprecation

const val AndThenDeprecation =
"`AndThen` is deprecated in favor of the function `andThen` used to provide stack safe function composition."

@Deprecated(
message = KindDeprecation,
level = DeprecationLevel.WARNING
Expand Down Expand Up @@ -71,10 +74,7 @@ operator fun <A, B> AndThenOf<A, B>.invoke(a: A): B = fix().invoke(a)
* ```
*
*/
@Deprecated(
"AndThen is becoming an internal data type that automatically tries to make andThen stack safe",
level = DeprecationLevel.WARNING
)
@Deprecated(AndThenDeprecation)
sealed class AndThen<A, B> : (A) -> B, AndThenOf<A, B> {

private data class Single<A, B>(val f: (A) -> B, val index: Int) : AndThen<A, B>()
Expand Down Expand Up @@ -229,6 +229,7 @@ sealed class AndThen<A, B> : (A) -> B, AndThenOf<A, B> {
else -> Single(f, 0)
}

@Deprecated(TailRecMDeprecation)
fun <I, A, B> tailRecM(a: A, f: (A) -> AndThenOf<I, Either<A, B>>): AndThen<I, B> =
AndThen { t: I -> step(a, t, f) }

Expand Down
Expand Up @@ -70,7 +70,7 @@ data class Const<A, out T>(private val value: A) : ConstOf<A, T> {
b: Const<A, B>,
map: (T, B) -> C
): Const<A, C> =
b.retag<C>().combine(SG, b.retag())
retag<C>().combine(SG, b.retag())

inline fun <B, C, D> zip(
SG: Semigroup<A>,
Expand Down Expand Up @@ -228,14 +228,11 @@ fun <A, T> Const<A, T>.combine(SG: Semigroup<A>, that: Const<A, T>): Const<A, T>

@Deprecated(
"Kind is deprecated, and will be removed in 0.13.0. Please use the ap method defined for Const instead",
ReplaceWith(
"this.zip(MA, arg1)",
"arrow.core.Const"
),
ReplaceWith("fix().zip(SG, ff.fix()) { a, f -> f(a) }"),
nomisRev marked this conversation as resolved.
Show resolved Hide resolved
DeprecationLevel.WARNING
)
fun <A, T, U> ConstOf<A, T>.ap(SG: Semigroup<A>, ff: ConstOf<A, (T) -> U>): Const<A, U> =
fix().retag<U>().combine(SG, ff.fix().retag())
fix().zip<(T) -> U, U>(SG, ff.fix()) { a, f -> f(a) }

@Deprecated("Kind is deprecated, and will be removed in 0.13.0. Please use one of the provided concrete methods instead")
fun <T, A, G> ConstOf<A, Kind<G, T>>.sequence(GA: Applicative<G>): Kind<G, Const<A, T>> =
Expand Down
106 changes: 15 additions & 91 deletions arrow-libs/core/arrow-core-data/src/main/kotlin/arrow/core/Either.kt
Expand Up @@ -968,61 +968,6 @@ sealed class Either<out A, out B> : EitherOf<A, B> {
*/
fun orNull(): B? = fold({ null }, { it })

/**
* Applies [f] to an [B] inside [Either] and returns the [Either] structure with a tuple of the [B] value and the
* computed [C] value as result of applying [f]
*
* ```kotlin:ank:playground
* import arrow.core.*
*
* fun main(args: Array<String>) {
* val result =
* //sampleStart
* "Hello".right().fproduct<String>({ "$it World" })
* //sampleEnd
* println(result)
* }
* ```
*/
fun <C> fproduct(f: (B) -> C): Either<A, Pair<B, C>> =
map { b -> b to f(b) }

/**
* Pairs [C] with [B] returning a Either<A, Pair<C, B>>
*
* ```kotlin:ank:playground
* import arrow.core.*
*
* fun main(args: Array<String>) {
* val result =
* //sampleStart
* "Hello".left().tupleLeft<String>("World")
* //sampleEnd
* println(result)
* }
* ```
*/
fun <C> tupleLeft(c: C): Either<A, Pair<C, B>> =
map { b -> c to b }

/**
* Pairs [C] with [B] returning a Either<A, Pair<B, C>>
*
* ```kotlin:ank:playground
* import arrow.core.*
*
* fun main(args: Array<String>) {
* val result =
* //sampleStart
* "Hello".left().tupleRight<String>("World")
* //sampleEnd
* println(result)
* }
* ```
*/
fun <C> tupleRight(c: C): Either<A, Pair<B, C>> =
map { b -> b to c }

fun replicate(n: Int): Either<A, List<B>> =
if (n <= 0) emptyList<B>().right()
else when (this) {
Expand Down Expand Up @@ -1139,6 +1084,7 @@ sealed class Either<out A, out B> : EitherOf<A, B> {

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

@Deprecated(TailRecMDeprecation)
tailrec fun <L, A, B> tailRecM(a: A, f: (A) -> Kind<EitherPartialOf<L>, Either<A, B>>): Either<L, B> {
val ev: Either<L, Either<A, B>> = f(a).fix()
return when (ev) {
Expand Down Expand Up @@ -1274,28 +1220,8 @@ sealed class Either<out A, out B> : EitherOf<A, B> {
{ it.bimap(fa, fb) }
}

/**
* Replaces [B] inside [Either] with [C] resulting in a Either<A, C>
*
* Kind<F, A> -> Kind<F, B>
*
* ```kotlin:ank:playground
* import arrow.core.*
*
* fun main(args: Array<String>) {
* val result =
* //sampleStart
* "Hello World".left().mapConst<String>("...")
* //sampleEnd
* println(result)
* }
* ```
*/
fun <C> mapConst(c: C): Either<A, C> =
map { c }

fun void(): Either<A, Unit> =
raulraja marked this conversation as resolved.
Show resolved Hide resolved
mapConst(Unit)
map { Unit }
}

@Deprecated("Deprecated, use the constructor instead", ReplaceWith("Either.Left(left)", "arrow.core.Either"))
Expand Down Expand Up @@ -1468,9 +1394,21 @@ inline fun <A, B> EitherOf<A, B?>.leftIfNull(default: () -> A): Either<A, B> =
fun <A, B> EitherOf<A, B>.contains(elem: B): Boolean =
fix().exists { it == elem }

@Deprecated(
"ap is deprecated alongside the Apply typeclass, since it's a low-level operator specific for generically deriving Apply combinators.",
ReplaceWith("zip(ff) { a, f -> f(a) }", "arrow.core.zip")
)
fun <A, B, C> EitherOf<A, B>.ap(ff: EitherOf<A, (B) -> C>): Either<A, C> =
flatMap { a -> ff.fix().map { f -> f(a) } }
fix().zip(ff.fix()) { a, f -> f(a) }

@Deprecated(
"apEval is deprecated alongside the Apply typeclass, since it's a low-level operator specific for generically deriving Apply combinators.",
ReplaceWith(
"fold({ l -> Eval.now(l.left()) }, { r -> ff.map { it.map { f -> f(r) } } })",
"arrow.core.Eval",
"arrow.core.left"
)
)
fun <A, B, C> Either<A, B>.apEval(ff: Eval<Either<A, (B) -> C>>): Eval<Either<A, C>> =
fold({ l -> Eval.now(l.left()) }, { r -> ff.map { it.map { f -> f(r) } } })

Expand Down Expand Up @@ -1689,9 +1627,6 @@ inline fun <A, B, C, D, E, F, G, H, I, J, K, L> Either<A, B>.zip(
}
}

fun <A, B, C, Z> Either<A, B>.zipEval(fb: Eval<Either<A, C>>, f: (B, C) -> Z): Eval<Either<A, Z>> =
fb.map { zip(it, f) }

fun <A, B> Either<A, B>.replicate(n: Int, MB: Monoid<B>): Either<A, B> =
if (n <= 0) MB.empty().right()
else MB.run {
Expand All @@ -1701,17 +1636,6 @@ fun <A, B> Either<A, B>.replicate(n: Int, MB: Monoid<B>): Either<A, B> =
}
}

inline fun <A, B, C> Either<A, B>.mproduct(f: (B) -> Either<A, C>): Either<A, Pair<B, C>> =
flatMap { a ->
f(a).map { b -> a to b }
}

inline fun <A, B> Either<A, Boolean>.ifM(ifTrue: () -> Either<A, B>, ifFalse: () -> Either<A, B>): Either<A, B> =
flatMap { if (it) ifTrue() else ifFalse() }

fun <A, B, C> Either<A, Either<B, C>>.selectM(f: Either<A, (B) -> C>): Either<A, C> =
flatMap { it.fold({ a -> f.map { ff -> ff(a) } }, { b -> b.right() }) }

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()
Expand Down
40 changes: 9 additions & 31 deletions arrow-libs/core/arrow-core-data/src/main/kotlin/arrow/core/Eval.kt
Expand Up @@ -85,13 +85,7 @@ fun <A> EvalOf<A>.value(): A = this.fix().value()
sealed class Eval<out A> : EvalOf<A> {

companion object {

@JvmName("tailRecMKind")
@Deprecated(
"Kind is deprecated, and will be removed in 0.13.0. Please use the tailRecM method defined for Eval instead",
ReplaceWith("tailRecM(f)"),
DeprecationLevel.WARNING
)
@Deprecated(TailRecMDeprecation)
fun <A, B> tailRecM(a: A, f: (A) -> EvalOf<Either<A, B>>): Eval<B> =
f(a).fix().flatMap { eval: Either<A, B> ->
when (eval) {
Expand All @@ -100,14 +94,6 @@ sealed class Eval<out A> : EvalOf<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)
}
}

@Deprecated(
"just is deprecated in favor of now",
ReplaceWith("now(a)"),
Expand Down Expand Up @@ -309,12 +295,15 @@ sealed class Eval<out A> : EvalOf<A> {
inline fun <B> map(crossinline f: (A) -> B): Eval<B> =
flatMap { a -> Now(f(a)) }

@Deprecated("Kind is deprecated, and will be removed in 0.13.0. Please use the ap method defined for Eval instead")
@Deprecated(
"ap is deprecated alongside the Apply typeclass, since it's a low-level operator specific for generically deriving Apply combinators.",
ReplaceWith(
"ff.fix().flatMap { f -> map(f) }",
"arrow.core.fix"
)
)
fun <B> ap(ff: EvalOf<(A) -> B>): Eval<B> =
ff.fix().flatMap { f -> map(f) }.fix()

fun <B> ap(ff: Eval<(A) -> B>): Eval<B> =
ff.flatMap { f -> map(f) }
ff.fix().flatMap { f -> map(f) }

@JvmName("flatMapKind")
@Deprecated("Kind is deprecated, and will be removed in 0.13.0. Please use the flatMap method defined for Eval instead")
Expand Down Expand Up @@ -601,9 +590,6 @@ fun <A, B, C, D, E, F, G, H, I, J, K> Eval<A>.zip(
}
}

fun <A, B, Z> Eval<A>.zipEval(fb: Eval<Eval<B>>, f: (A, B) -> Z): Eval<Eval<Z>> =
fb.map { zip(it, f) }

fun <A> Eval<A>.replicate(n: Int): Eval<List<A>> =
if (n <= 0) Eval.just(emptyList())
else this.zip(replicate(n - 1)) { a: A, xs: List<A> -> listOf(a) + xs }
Expand All @@ -612,11 +598,3 @@ fun <A> Eval<A>.replicate(n: Int, MA: Monoid<A>): Eval<A> = MA.run {
if (n <= 0) Eval.just(MA.empty())
else this@replicate.zip(replicate(n - 1, MA)) { a: A, xs: A -> MA.run { a + xs } }
}

fun <A, B> Eval<A>.apEval(ff: Eval<Eval<(A) -> B>>): Eval<Eval<B>> = ff.map { this.ap(it) }

fun <A, B> Eval<A>.apTap(fb: Eval<B>): Eval<A> =
flatTap { fb }

fun <A, B> Eval<A>.flatTap(f: (A) -> Eval<B>): Eval<A> =
flatMap { a -> f(a).map { a } }