Skip to content
This repository has been archived by the owner on Feb 24, 2021. It is now read-only.

CU-cn24gw CU-cn24dh Remove extension and higherkind annotations for Endo and Eval #316

Merged
merged 27 commits into from Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4c0605a
Remove extension for EndoMonoid
danimontoya Jan 26, 2021
a6bc2c1
Remove extension and higherkind for Eval
danimontoya Jan 26, 2021
a4df05d
Deprecate @extension for Endo
danimontoya Jan 28, 2021
4234bad
Add combine for Endo and update ReplaceWith
danimontoya Jan 28, 2021
e2c54a9
Add mapN for Eval
danimontoya Jan 28, 2021
2550d47
Deprecate extension methods of EvalApplicative.kt
danimontoya Jan 29, 2021
dcbd5bf
Format and imports
danimontoya Jan 29, 2021
42146c7
Move mapN to companion object
danimontoya Jan 29, 2021
5e96e16
Deprecate extension methods for EvalBimonad.kt
danimontoya Jan 29, 2021
68e5714
Deprecate extension methods for EvalComonad.kt
danimontoya Jan 29, 2021
9cadbe8
Deprecate extension methods for EvalFunctor.kt
danimontoya Jan 29, 2021
cfb4630
Deprecate extension methods for EvalMonad.kt
danimontoya Jan 29, 2021
0fb0871
Deprecate eval typeclasses interfaces
danimontoya Jan 29, 2021
a966d3c
Refactor Endo.combine
danimontoya Jan 29, 2021
682001a
Remove fix() from new added flatMap function and JvmName-rename some …
danimontoya Jan 29, 2021
e3882b7
Divide and win. Reducing number of flatmapping works.. although build…
danimontoya Jan 29, 2021
0f6b764
Increase Eval.mapN
danimontoya Feb 1, 2021
b431a41
Enable zip64
danimontoya Feb 1, 2021
b6f3bc5
Add all mapN up until 10
danimontoya Feb 1, 2021
86f7e8f
Minor change
danimontoya Feb 1, 2021
282d270
Eval.mapN until 7 parameters works
danimontoya Feb 1, 2021
dae71b5
Merge branch 'master' into dm-remove-extension-endo-eval
danimontoya Feb 1, 2021
d42c57e
Remove inline-crossinline from mapN and flatMap functions
danimontoya Feb 2, 2021
7643c19
Fix deprecation messages and imports from comments
danimontoya Feb 2, 2021
01781b8
Merge branch 'master' into dm-remove-extension-endo-eval
danimontoya Feb 2, 2021
d949082
Rename Unit -> unit so its not confused with kotlin.Unit
danimontoya Feb 3, 2021
01d57f1
Merge branch 'master' into dm-remove-extension-endo-eval
danimontoya Feb 3, 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
14 changes: 14 additions & 0 deletions arrow-core-data/src/main/kotlin/arrow/core/Endo.kt
@@ -1,8 +1,22 @@
package arrow.core

import arrow.typeclasses.Monoid

/**
* The monoid of endomorphisms under composition.
*/
data class Endo<A>(val f: (A) -> A) {

companion object

fun combine(g: Endo<A>): Endo<A> =
Endo(f.compose(g.f))
}

fun <A> Monoid.Companion.endo(): Monoid<Endo<A>> = object : Monoid<Endo<A>> {
override fun empty(): Endo<A> =
Endo(::identity)

override fun Endo<A>.combine(g: Endo<A>): Endo<A> =
Endo(f.compose(g.f))
}
210 changes: 207 additions & 3 deletions arrow-core-data/src/main/kotlin/arrow/core/Eval.kt
@@ -1,11 +1,17 @@
package arrow.core

import arrow.typeclasses.Monoid
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

class ForEval private constructor() { companion object }
@Deprecated("Kind is deprecated, and will be removed in 0.13.0. Please use one of the provided concrete methods instead")
class ForEval private constructor() {
companion object
}
@Deprecated("Kind is deprecated, and will be removed in 0.13.0. Please use one of the provided concrete methods instead")
typealias EvalOf<A> = arrow.Kind<ForEval, A>

@Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE")
@Deprecated("Kind is deprecated, and will be removed in 0.13.0. Please use one of the provided concrete methods instead")
inline fun <A> EvalOf<A>.fix(): Eval<A> =
this as Eval<A>

Expand Down Expand Up @@ -67,6 +73,12 @@ 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
)
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 @@ -75,6 +87,19 @@ 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)"),
DeprecationLevel.WARNING
)
fun <A> just(a: A): Eval<A> =
danimontoya marked this conversation as resolved.
Show resolved Hide resolved
now(a)

Expand Down Expand Up @@ -242,6 +267,125 @@ sealed class Eval<out A> : EvalOf<A> {

return curr.value() as A
}

fun <A, B, C> mapN(
a: Eval<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) }

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) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:
with the kotlin naming conventions wouldn't we define Unit starting with a lowercase letter same there too

val Unit: Eval<Unit> = Now(kotlin.Unit)
val True: Eval<Boolean> = Now(true)
val False: Eval<Boolean> = Now(false)
val Zero: Eval<Int> = Now(0)
val One: Eval<Int> = Now(1)


fun <A, B, C, D, E> mapN(
a: Eval<A>,
b: Eval<B>,
c: Eval<C>,
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) }

fun <A, B, C, D, E, F> mapN(
a: Eval<A>,
b: Eval<B>,
c: Eval<C>,
d: Eval<D>,
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) }

fun <A, B, C, D, E, F, G> mapN(
a: Eval<A>,
b: Eval<B>,
c: Eval<C>,
d: Eval<D>,
e: Eval<E>,
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) }

fun <A, B, C, D, E, F, G, H> mapN(
a: Eval<A>,
b: Eval<B>,
c: Eval<C>,
d: Eval<D>,
e: Eval<E>,
f: Eval<F>,
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) }

fun <A, B, C, D, E, F, G, H, I> mapN(
a: Eval<A>,
b: Eval<B>,
c: Eval<C>,
d: Eval<D>,
e: Eval<E>,
f: Eval<F>,
g: Eval<G>,
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) }

fun <A, B, C, D, E, F, G, H, I, J> mapN(
a: Eval<A>,
b: Eval<B>,
c: Eval<C>,
d: Eval<D>,
e: Eval<E>,
f: Eval<F>,
g: Eval<G>,
h: Eval<H>,
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) }

fun <A, B, C, D, E, F, G, H, I, J, K> mapN(
a: Eval<A>,
b: Eval<B>,
c: Eval<C>,
d: Eval<D>,
e: Eval<E>,
f: Eval<F>,
g: Eval<G>,
h: Eval<H>,
i: Eval<I>,
j: Eval<J>,
map: (A, B, C, D, E, F, G, H, I, J) -> K
): Eval<K> =
a.flatMap { aa ->
b.flatMap { bb ->
c.flatMap { cc ->
d.flatMap { dd ->
e.flatMap { ee ->
f.flatMap { ff ->
g.flatMap { gg ->
h.flatMap { hh ->
i.flatMap { ii ->
j.map { jj ->
map(aa, bb, cc, dd, ee, ff, gg, hh, ii, jj)
}
}
}
}
}
}
}
}
}
}
}

abstract fun value(): A
Expand All @@ -251,14 +395,21 @@ 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")
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) }

@JvmName("flatMapKind")
@Deprecated("Kind is deprecated, and will be removed in 0.13.0. Please use the flatMap method defined for Eval instead")
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE", "UNCHECKED_CAST")
inline fun <B> flatMap(crossinline f: (A) -> EvalOf<B>): Eval<B> =
when (this) {
is FlatMap<A> -> object : FlatMap<B>() {
override fun <S> start(): Eval<S> = (this@Eval).start()

@IgnoreJRERequirement
override fun <S> run(s: S): Eval<B> =
object : FlatMap<B>() {
Expand All @@ -276,9 +427,42 @@ sealed class Eval<out A> : EvalOf<A> {
}
}

@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE", "UNCHECKED_CAST")
fun <B> flatMap(f: (A) -> Eval<B>): Eval<B> =
when (this) {
is FlatMap<A> -> object : FlatMap<B>() {
override fun <S> start(): Eval<S> = (this@Eval).start()

@IgnoreJRERequirement
override fun <S> run(s: S): Eval<B> =
object : FlatMap<B>() {
override fun <S1> start(): Eval<S1> = (this@Eval).run(s) as Eval<S1>
override fun <S1> run(s1: S1): Eval<B> = f(s1 as A)
}
}
is Defer<A> -> object : FlatMap<B>() {
override fun <S> start(): Eval<S> = this@Eval.thunk() as Eval<S>
override fun <S> run(s: S): Eval<B> = f(s as A)
}
else -> object : FlatMap<B>() {
override fun <S> start(): Eval<S> = this@Eval as Eval<S>
override fun <S> run(s: S): Eval<B> = f(s as A)
}
}

@JvmName("coflatMapKind")
@Deprecated("Kind is deprecated, and will be removed in 0.13.0. Please use the coflatMap method defined for Eval instead")
inline fun <B> coflatMap(crossinline f: (EvalOf<A>) -> B): Eval<B> =
Later { f(this) }

inline fun <B> coflatMap(crossinline f: (Eval<A>) -> B): Eval<B> =
Later { f(this) }

@Deprecated(
"extract is deprecated in favor of value",
ReplaceWith("value()"),
DeprecationLevel.WARNING
)
fun extract(): A = value()
danimontoya marked this conversation as resolved.
Show resolved Hide resolved

/**
Expand Down Expand Up @@ -373,7 +557,27 @@ fun <A, B> Iterator<A>.iterateRight(lb: Eval<B>, f: (A, Eval<B>) -> Eval<B>): Ev
}

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

fun <A, B> Eval<A>.zip(fb: Eval<B>): Eval<Pair<A, B>> =
flatMap { a: A -> fb.map { b -> Pair(a, b) } }
flatMap { a: A -> fb.map { b: B -> Pair(a, b) } }

fun <A> Eval<A>.replicate(n: Int): Eval<List<A>> =
if (n <= 0) Eval.just(emptyList())
else Eval.mapN(this, replicate(n - 1)) { a: A, xs: List<A> -> listOf(a) + xs }

fun <A> Eval<A>.replicate(n: Int, MA: Monoid<A>): Eval<A> = MA.run {
if (n <= 0) Eval.just(MA.empty())
else Eval.mapN(this@replicate, 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, Z> Eval<A>.map2Eval(fb: Eval<Eval<B>>, f: (Tuple2<A, B>) -> Z): Eval<Eval<Z>> =
apEval(fb.map { it.map { b: B -> { a: A -> f(Tuple2(a, b)) } } })

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 } }
Expand Up @@ -18,11 +18,11 @@ interface Applicative<F> : Apply<F> {

fun <A> Kind<F, A>.replicate(n: Int): Kind<F, List<A>> =
if (n <= 0) just(emptyList())
else mapN(this, replicate(n - 1)) { (a, xs) -> listOf(a) + xs }
else mapN(this, replicate(n - 1)) { (a: A, xs: List<A>) -> listOf(a) + xs }

fun <A> Kind<F, A>.replicate(n: Int, MA: Monoid<A>): Kind<F, A> =
if (n <= 0) just(MA.empty())
else mapN(this@replicate, replicate(n - 1, MA)) { (a, xs) -> MA.run { a + xs } }
else mapN(this@replicate, replicate(n - 1, MA)) { (a: A, xs: A) -> MA.run { a + xs } }
}

@Deprecated("Applicative typeclass is deprecated")
Expand Down
Expand Up @@ -3,10 +3,13 @@ package arrow.core.extensions
import arrow.core.Endo
import arrow.core.compose
import arrow.core.identity
import arrow.extension
import arrow.typeclasses.Monoid

@extension
@Deprecated(
"Typeclass instance have been moved to the companion object of the typeclass.",
ReplaceWith("Monoid.endo<A>()", "arrow.core.endo", "arrow.typeclasses.Monoid"),
DeprecationLevel.WARNING
)
interface EndoMonoid<A> : Monoid<Endo<A>> {
override fun empty(): Endo<A> = Endo(::identity)
override fun Endo<A>.combine(g: Endo<A>): Endo<A> = Endo(f.compose(g.f))
Expand Down
Expand Up @@ -3,13 +3,6 @@ package arrow.core.extensions.endo.monoid
import arrow.core.Endo
import arrow.core.Endo.Companion
import arrow.core.extensions.EndoMonoid
import kotlin.Any
import kotlin.Deprecated
import kotlin.PublishedApi
import kotlin.Suppress
import kotlin.collections.Collection
import kotlin.collections.List
import kotlin.jvm.JvmName

/**
* cached extension
Expand All @@ -27,14 +20,15 @@ internal val monoid_singleton: EndoMonoid<Any?> = object : EndoMonoid<Any?> {}
@Deprecated(
"@extension kinded projected functions are deprecated",
ReplaceWith(
"combineAll()",
"arrow.core.combineAll"
"if (isEmpty()) Endo(::identity) else reduce { a, b -> a.combine(b) }",
"arrow.core.combine"
),
DeprecationLevel.WARNING
)
fun <A> Collection<Endo<A>>.combineAll(): Endo<A> = arrow.core.Endo.monoid<A>().run {
this@combineAll.combineAll() as arrow.core.Endo<A>
}
fun <A> Collection<Endo<A>>.combineAll(): Endo<A> =
arrow.core.Endo.monoid<A>().run {
this@combineAll.combineAll() as arrow.core.Endo<A>
}

@JvmName("combineAll")
@Suppress(
Expand All @@ -46,18 +40,23 @@ fun <A> Collection<Endo<A>>.combineAll(): Endo<A> = arrow.core.Endo.monoid<A>().
@Deprecated(
"@extension kinded projected functions are deprecated",
ReplaceWith(
"combineAll(arg0)",
"arrow.core.Endo.combineAll"
"if (arg0.isEmpty()) Endo(::identity) else arg0.reduce { a, b -> a.combine(b) }",
"arrow.core.combine"
),
DeprecationLevel.WARNING
)
fun <A> combineAll(arg0: List<Endo<A>>): Endo<A> = arrow.core.Endo
.monoid<A>()
.combineAll(arg0) as arrow.core.Endo<A>
fun <A> combineAll(arg0: List<Endo<A>>): Endo<A> =
arrow.core.Endo
.monoid<A>()
.combineAll(arg0) as arrow.core.Endo<A>

@Suppress(
"UNCHECKED_CAST",
"NOTHING_TO_INLINE"
)
@Deprecated(
"Extension projections are deprecated. Use endo on Monoid.",
ReplaceWith("Monoid.endo()", "arrow.typeclasses.Monoid", "arrow.core.endo")
)
inline fun <A> Companion.monoid(): EndoMonoid<A> = monoid_singleton as
arrow.core.extensions.EndoMonoid<A>
arrow.core.extensions.EndoMonoid<A>