From 659c0807a9dc267775957e04fda6dfbe86754e3c Mon Sep 17 00:00:00 2001 From: Jose Gutierrez Date: Tue, 28 Mar 2023 17:03:00 +0200 Subject: [PATCH] Deprecate `foldMap` with `Monoid` in `Fold` --- .../optics/arrow-optics/api/arrow-optics.api | 9 +- .../commonMain/kotlin/arrow/optics/Every.kt | 94 +++++++++++++++++++ .../commonMain/kotlin/arrow/optics/Fold.kt | 44 +++++++-- .../commonMain/kotlin/arrow/optics/Getter.kt | 5 + .../src/commonMain/kotlin/arrow/optics/Iso.kt | 5 + .../commonMain/kotlin/arrow/optics/Lens.kt | 5 + .../kotlin/arrow/optics/Optional.kt | 6 ++ .../kotlin/arrow/optics/OptionalGetter.kt | 5 + .../commonMain/kotlin/arrow/optics/Prism.kt | 5 + .../arrow/optics/typeclasses/FilterIndex.kt | 12 +++ 10 files changed, 181 insertions(+), 9 deletions(-) diff --git a/arrow-libs/optics/arrow-optics/api/arrow-optics.api b/arrow-libs/optics/arrow-optics/api/arrow-optics.api index 9a570cb45a7..e9bbd5727aa 100644 --- a/arrow-libs/optics/arrow-optics/api/arrow-optics.api +++ b/arrow-libs/optics/arrow-optics/api/arrow-optics.api @@ -88,7 +88,6 @@ public final class arrow/optics/Fold$DefaultImpls { public static fun firstOrNull (Larrow/optics/Fold;Ljava/lang/Object;)Ljava/lang/Object; public static fun fold (Larrow/optics/Fold;Larrow/typeclasses/Monoid;Ljava/lang/Object;)Ljava/lang/Object; public static fun fold (Larrow/optics/Fold;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;)Ljava/lang/Object; - public static fun foldMap (Larrow/optics/Fold;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun getAll (Larrow/optics/Fold;Ljava/lang/Object;)Ljava/util/List; public static fun isEmpty (Larrow/optics/Fold;Ljava/lang/Object;)Z public static fun isNotEmpty (Larrow/optics/Fold;Ljava/lang/Object;)Z @@ -105,6 +104,7 @@ public abstract interface class arrow/optics/Getter : arrow/optics/Fold { public abstract fun compose (Larrow/optics/Getter;)Larrow/optics/Getter; public abstract fun first ()Larrow/optics/Getter; public abstract fun foldMap (Larrow/typeclasses/Monoid;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public abstract fun foldMap (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public abstract fun get (Ljava/lang/Object;)Ljava/lang/Object; public abstract fun left ()Larrow/optics/Getter; public abstract fun plus (Larrow/optics/Getter;)Larrow/optics/Getter; @@ -173,6 +173,7 @@ public abstract interface class arrow/optics/PEvery : arrow/optics/Fold, arrow/o public abstract fun compose (Larrow/optics/PEvery;)Larrow/optics/PEvery; public static fun either ()Larrow/optics/PEvery; public abstract fun foldMap (Larrow/typeclasses/Monoid;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public abstract fun foldMap (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public abstract fun getEvery (Larrow/optics/PIso;)Larrow/optics/PEvery; public abstract fun getEvery (Larrow/optics/PLens;)Larrow/optics/PEvery; public abstract fun getEvery (Larrow/optics/POptional;)Larrow/optics/PEvery; @@ -234,7 +235,6 @@ public final class arrow/optics/PEvery$DefaultImpls { public static fun firstOrNull (Larrow/optics/PEvery;Ljava/lang/Object;)Ljava/lang/Object; public static fun fold (Larrow/optics/PEvery;Larrow/typeclasses/Monoid;Ljava/lang/Object;)Ljava/lang/Object; public static fun fold (Larrow/optics/PEvery;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;)Ljava/lang/Object; - public static fun foldMap (Larrow/optics/PEvery;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun getAll (Larrow/optics/PEvery;Ljava/lang/Object;)Ljava/util/List; public static fun getEvery (Larrow/optics/PEvery;Larrow/optics/PEvery;)Larrow/optics/PTraversal; public static fun getEvery (Larrow/optics/PEvery;Larrow/optics/PIso;)Larrow/optics/PEvery; @@ -264,6 +264,7 @@ public abstract interface class arrow/optics/PIso : arrow/optics/Fold, arrow/opt public static fun eitherToValidated ()Larrow/optics/PIso; public abstract fun first ()Larrow/optics/PIso; public abstract fun foldMap (Larrow/typeclasses/Monoid;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public abstract fun foldMap (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public abstract fun get (Ljava/lang/Object;)Ljava/lang/Object; public abstract fun getOrModify (Ljava/lang/Object;)Larrow/core/Either; public abstract fun left ()Larrow/optics/PIso; @@ -385,6 +386,7 @@ public abstract interface class arrow/optics/PLens : arrow/optics/Getter, arrow/ public abstract fun compose (Larrow/optics/PLens;)Larrow/optics/PLens; public abstract fun first ()Larrow/optics/PLens; public abstract fun foldMap (Larrow/typeclasses/Monoid;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public abstract fun foldMap (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public abstract fun get (Ljava/lang/Object;)Ljava/lang/Object; public abstract fun getOrModify (Ljava/lang/Object;)Larrow/core/Either; public static fun nonEmptyListHead ()Larrow/optics/PLens; @@ -490,6 +492,7 @@ public abstract interface class arrow/optics/POptional : arrow/optics/PEvery, ar public abstract fun compose (Larrow/optics/POptional;)Larrow/optics/POptional; public abstract fun first ()Larrow/optics/POptional; public abstract fun foldMap (Larrow/typeclasses/Monoid;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public abstract fun foldMap (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public abstract fun getOrModify (Ljava/lang/Object;)Larrow/core/Either; public static fun listHead ()Larrow/optics/POptional; public static fun listTail ()Larrow/optics/POptional; @@ -570,6 +573,7 @@ public abstract interface class arrow/optics/POptionalGetter : arrow/optics/Fold public static fun filter (Lkotlin/jvm/functions/Function1;)Larrow/optics/POptionalGetter; public abstract fun first ()Larrow/optics/POptionalGetter; public abstract fun foldMap (Larrow/typeclasses/Monoid;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public abstract fun foldMap (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public abstract fun getOrModify (Ljava/lang/Object;)Larrow/core/Either; public abstract fun getOrNull (Ljava/lang/Object;)Ljava/lang/Object; public abstract fun plus (Larrow/optics/POptionalGetter;)Larrow/optics/POptionalGetter; @@ -618,6 +622,7 @@ public abstract interface class arrow/optics/PPrism : arrow/optics/PEvery, arrow public static fun eitherRight ()Larrow/optics/PPrism; public abstract fun first ()Larrow/optics/PPrism; public abstract fun foldMap (Larrow/typeclasses/Monoid;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public abstract fun foldMap (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public abstract fun getOrModify (Ljava/lang/Object;)Larrow/core/Either; public abstract fun left ()Larrow/optics/PPrism; public abstract fun liftNullable (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1; diff --git a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Every.kt b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Every.kt index dc8fdad411f..c100b75b89d 100644 --- a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Every.kt +++ b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Every.kt @@ -28,6 +28,8 @@ public interface PEvery : PTraversal, Fold, PSette */ override fun foldMap(M: Monoid, source: S, map: (focus: A) -> R): R + override fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: A) -> R): R + override fun modify(source: S, map: (focus: A) -> B): T /** @@ -40,6 +42,9 @@ public interface PEvery : PTraversal, Fold, PSette override fun modify(source: S, map: (focus: C) -> D): T = this@PEvery.modify(source) { b -> other.modify(b, map) } + + override fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: C) -> R): R = + this@PEvery.foldMap(empty, combine, source) { c -> other.foldMap(empty, combine, c, map) } } public operator fun plus(other: PEvery): PEvery = @@ -50,6 +55,8 @@ public interface PEvery : PTraversal, Fold, PSette object : Every { override fun foldMap(M: Monoid, source: S, map: (A) -> R): R = F.foldMap(M, source, map) override fun modify(source: S, map: (focus: A) -> A): S = T.modify(source, map) + override fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: A) -> R): R = + F.foldMap(empty, combine, source, map) } /** @@ -63,6 +70,9 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: List, map: (focus: A) -> R): R = source.foldMap(M, map) + + override fun foldMap(empty: R, combine: (R, R) -> R, source: List, map: (focus: A) -> R): R = + source.fold(empty) { acc, a -> combine(acc, map(a)) } } /** @@ -78,6 +88,10 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Either, map: (focus: R) -> A): A = source.fold({ M.empty() }, map) + + override fun foldMap(empty: A, combine: (A, A) -> A, source: Either, map: (focus: R) -> A): A = + source.fold({ empty }, map) + } @JvmStatic @@ -89,6 +103,9 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Map, map: (focus: V) -> R): R = M.run { source.fold(empty()) { acc, (_, v) -> acc.combine(map(v)) } } + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Map, map: (focus: V) -> R): R = + source.fold(empty) { acc, (_, v) -> combine(acc, map(v)) } } /** @@ -105,6 +122,10 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: NonEmptyList, map: (focus: A) -> R): R = source.foldMap(M, map) + + override fun foldMap(empty: R, combine: (R, R) -> R, source: NonEmptyList, map: (focus: A) -> R): R = + source.fold(empty) { acc, a -> combine(acc, map(a)) } + } /** @@ -121,6 +142,9 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Option, map: (focus: A) -> R): R = source.fold({ M.empty() }, map) + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Option, map: (focus: A) -> R): R = + source.fold({ empty }, map) } @JvmStatic @@ -131,6 +155,9 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Sequence, map: (focus: A) -> R): R = source.foldMap(M, map) + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Sequence, map: (focus: A) -> R): R = + source.fold(empty){ acc, a -> combine(acc, map(a)) } } /** @@ -148,6 +175,9 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: String, map: (focus: Char) -> R): R = M.run { source.fold(empty()) { acc, char -> acc.combine(map(char)) } } + + override fun foldMap(empty: R, combine: (R, R) -> R, source: String, map: (focus: Char) -> R): R = + source.fold(empty) { acc, char -> combine(acc, map(char)) } } /** @@ -162,6 +192,10 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Pair, map: (focus: A) -> R): R = listOf(source.first, source.second) .foldMap(M, map) + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Pair, map: (focus: A) -> R): R = + listOf(source.first, source.second).fold(empty) { acc, a -> combine(acc, map(a)) } + } /** @@ -176,6 +210,9 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Triple, map: (focus: A) -> R): R = listOf(source.first, source.second, source.third) .foldMap(M, map) + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Triple, map: (focus: A) -> R): R = + listOf(source.first, source.second, source.third).fold(empty) { acc, a -> combine(acc, map(a)) } } /** @@ -190,6 +227,9 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Tuple4, map: (focus: A) -> R): R = listOf(source.first, source.second, source.third, source.fourth) .foldMap(M, map) + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Tuple4, map: (focus: A) -> R): R = + listOf(source.first, source.second, source.third, source.fourth).fold(empty) { acc, a -> combine(acc, map(a))} } /** @@ -204,6 +244,15 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Tuple5, map: (focus: A) -> R): R = listOf(source.first, source.second, source.third, source.fourth, source.fifth) .foldMap(M, map) + + override fun foldMap( + empty: R, + combine: (R, R) -> R, + source: Tuple5, + map: (focus: A) -> R + ): R = + listOf(source.first, source.second, source.third, source.fourth, source.fifth) + .fold(empty) { acc, a -> combine(acc, map(a)) } } /** @@ -225,6 +274,15 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Tuple6, map: (focus: A) -> R): R = listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth) .foldMap(M, map) + + override fun foldMap( + empty: R, + combine: (R, R) -> R, + source: Tuple6, + map: (focus: A) -> R + ): R = + listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth) + .fold(empty) { acc, a -> combine(acc, map(a)) } } /** @@ -247,6 +305,15 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Tuple7, map: (focus: A) -> R): R = listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh) .foldMap(M, map) + + override fun foldMap( + empty: R, + combine: (R, R) -> R, + source: Tuple7, + map: (focus: A) -> R + ): R = + listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh) + .fold(empty) { acc, a -> combine(acc, map(a)) } } /** @@ -273,6 +340,15 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Tuple8, map: (focus: A) -> R): R = listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh, source.eighth) .foldMap(M, map) + + override fun foldMap( + empty: R, + combine: (R, R) -> R, + source: Tuple8, + map: (focus: A) -> R + ): R = + listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh, source.eighth) + .fold(empty) { acc, a -> combine(acc, map(a)) } } /** @@ -300,6 +376,15 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Tuple9, map: (focus: A) -> R): R = listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh, source.eighth, source.ninth) .foldMap(M, map) + + override fun foldMap( + empty: R, + combine: (R, R) -> R, + source: Tuple9, + map: (focus: A) -> R + ): R = + listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh, source.eighth, source.ninth) + .fold(empty) { acc, a -> combine(acc, map(a)) } } /** @@ -328,6 +413,15 @@ public interface PEvery : PTraversal, Fold, PSette override fun foldMap(M: Monoid, source: Tuple10, map: (focus: A) -> R): R = listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh, source.eighth, source.ninth, source.tenth) .foldMap(M, map) + + override fun foldMap( + empty: R, + combine: (R, R) -> R, + source: Tuple10, + map: (focus: A) -> R + ): R = + listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh, source.eighth, source.ninth, source.tenth) + .fold(empty) { acc, a -> combine(acc, map(a)) } } } diff --git a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Fold.kt b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Fold.kt index 879be12d950..a05bad6519c 100644 --- a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Fold.kt +++ b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Fold.kt @@ -29,16 +29,12 @@ public interface Fold { /** * Map each target to a type [R] and combine the results as a fold. */ - public fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: A) -> R): R = - foldMap(object : Monoid { - override fun empty(): R = empty - override fun R.combine(b: R): R = combine(this, b) - }, source, map) + public fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: A) -> R): R /** * Map each target to a type R and use a Monoid to fold the results */ - @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(M.empty(), M::combine, source, map)", "arrow.optics.foldMap", "arrow.typeclasses.combine")) + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) public fun foldMap(M: Monoid, source: S, map: (focus: A) -> R): R /** @@ -92,7 +88,7 @@ public interface Fold { /** * Fold using the given [Monoid] instance. */ - @Deprecated(MonoidDeprecation, ReplaceWith("fold(M.empty(), M::combine, source)", "arrow.optics.fold", "arrow.typeclasses.combine")) + @Deprecated(MonoidDeprecation, ReplaceWith("fold(empty, {r1, r2 -> r1 + r2}, source)", "arrow.optics.fold")) public fun fold(M: Monoid, source: S): A = foldMap(M, source, ::identity) @@ -132,8 +128,13 @@ public interface Fold { */ public infix fun choice(other: Fold): Fold, A> = object : Fold, A> { + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: Either, map: (focus: A) -> R): R = source.fold({ ac -> this@Fold.foldMap(M, ac, map) }, { c -> other.foldMap(M, c, map) }) + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Either, map: (focus: A) -> R): R = + source.fold({ ac -> this@Fold.foldMap(empty, combine, ac, map) }, { c -> other.foldMap(empty, combine, c, map) }) + } /** @@ -141,10 +142,17 @@ public interface Fold { */ public fun left(): Fold, Either> = object : Fold, Either> { + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: Either, map: (Either) -> R): R = source.fold( { a1: S -> this@Fold.foldMap(M, a1) { b -> map(Either.Left(b)) } }, { c -> map(Either.Right(c)) }) + + override fun foldMap(empty: R, combine:(R, R) -> R, source: Either, map: (focus: Either) -> R): R = + source.fold( + { a1: S -> this@Fold.foldMap(empty, combine, a1) { b -> map(Either.Left(b)) } }, + { c -> map(Either.Right(c)) } + ) } /** @@ -152,8 +160,12 @@ public interface Fold { */ public fun right(): Fold, Either> = object : Fold, Either> { + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: Either, map: (Either) -> R): R = source.fold({ c -> map(Either.Left(c)) }, { a1 -> this@Fold.foldMap(M, a1) { b -> map(Either.Right(b)) } }) + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Either, map: (focus: Either) -> R): R = + source.fold({ c -> map(Either.Left(c)) }, { a1 -> this@Fold.foldMap(empty, combine, a1) { b -> map(Either.Right(b)) } }) } /** @@ -161,8 +173,13 @@ public interface Fold { */ public infix fun compose(other: Fold): Fold = object : Fold { + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: S, map: (focus: C) -> R): R = this@Fold.foldMap(M, source) { c -> other.foldMap(M, c, map) } + + override fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: C) -> R): R = + this@Fold.foldMap(empty, combine, source) { c -> other.foldMap(empty, combine, c, map) } + } public operator fun plus(other: Fold): Fold = @@ -177,16 +194,25 @@ public interface Fold { * [Fold] that takes either [S] or [S] and strips the choice of [S]. */ public fun codiagonal(): Fold, S> = object : Fold, S> { + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: Either, map: (S) -> R): R = source.fold(map, map) + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Either, map: (focus: S) -> R): R = + source.fold(map, map) } /** * Creates a [Fold] based on a predicate of the source [S] */ public fun select(p: (S) -> Boolean): Fold = object : Fold { + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: S, map: (S) -> R): R = if (p(source)) map(source) else M.empty() + + override fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: S) -> R): R = + if (p(source)) map(source) else empty + } /** @@ -198,8 +224,12 @@ public interface Fold { @JvmStatic public fun iterable(): Fold, A> = object : Fold, A> { + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: Iterable, map: (focus: A) -> R): R = source.foldMap(M, map) + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Iterable, map: (focus: A) -> R): R = + source.fold(empty) { acc, a -> combine(acc, map(a)) } } /** diff --git a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Getter.kt b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Getter.kt index 7fa4469e60d..5e641453033 100644 --- a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Getter.kt +++ b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Getter.kt @@ -4,6 +4,7 @@ import arrow.core.Either import arrow.core.compose import arrow.core.identity import arrow.typeclasses.Monoid +import arrow.typeclasses.MonoidDeprecation /** * A [Getter] is an optic that allows to see into a structure and getting a focus. @@ -21,9 +22,13 @@ public fun interface Getter : Fold { */ public fun get(source: S): A + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: S, map: (focus: A) -> R): R = map(get(source)) + override fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: A) -> R): R = + map(get(source)) + /** * Create a product of the [Getter] and a type [C] */ diff --git a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Iso.kt b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Iso.kt index 5f941198744..92150a95ef2 100644 --- a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Iso.kt +++ b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Iso.kt @@ -12,6 +12,7 @@ import arrow.core.Validated.Valid import arrow.core.compose import arrow.core.identity import arrow.typeclasses.Monoid +import arrow.typeclasses.MonoidDeprecation import kotlin.jvm.JvmStatic /** @@ -65,9 +66,13 @@ public interface PIso : PPrism, PLens, Gette override fun modify(source: S, map: (focus: A) -> B): T = reverseGet(map(get(source))) + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: S, map: (focus: A) -> R): R = map(get(source)) + override fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: A) -> R): R = + map(get(source)) + /** * Reverse a [PIso]: the source becomes the target and the target becomes the source */ diff --git a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Lens.kt b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Lens.kt index 6912a35d6bd..b57c701f759 100644 --- a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Lens.kt +++ b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Lens.kt @@ -4,6 +4,7 @@ import arrow.core.Either import arrow.core.NonEmptyList import arrow.core.identity import arrow.typeclasses.Monoid +import arrow.typeclasses.MonoidDeprecation import kotlin.jvm.JvmStatic /** @@ -38,9 +39,13 @@ public interface PLens : Getter, POptional, PSette override fun getOrModify(source: S): Either = Either.Right(get(source)) + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: S, map: (focus: A) -> R): R = map(get(source)) + override fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: A) -> R): R = + map(get(source)) + /** * Join two [PLens] with the same focus in [A] */ diff --git a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Optional.kt b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Optional.kt index 5ccbb8d4b54..50fc654048c 100644 --- a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Optional.kt +++ b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Optional.kt @@ -10,6 +10,7 @@ import arrow.core.identity import arrow.core.prependTo import arrow.core.toOption import arrow.typeclasses.Monoid +import arrow.typeclasses.MonoidDeprecation import kotlin.jvm.JvmStatic /** @@ -72,9 +73,14 @@ public interface POptional : PSetter, POptionalGetter + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: S, map: (focus: A) -> R): R = getOrModify(source).map(map).getOrElse { M.empty() } + override fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: A) -> R): R = + getOrModify(source).map(map).getOrElse { empty } + + /** * Modify the focus of a [POptional] with a function [map] */ diff --git a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/OptionalGetter.kt b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/OptionalGetter.kt index efa0b790678..b05adb11b93 100644 --- a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/OptionalGetter.kt +++ b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/OptionalGetter.kt @@ -7,6 +7,7 @@ import arrow.core.Some import arrow.core.flatMap import arrow.core.getOrElse import arrow.typeclasses.Monoid +import arrow.typeclasses.MonoidDeprecation import kotlin.jvm.JvmStatic /** @@ -37,9 +38,13 @@ public interface POptionalGetter: Fold { public fun getOrNull(source: S): A? = getOrModify(source).getOrNull() + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: S, map: (focus: A) -> R): R = getOrModify(source).map(map).getOrElse { M.empty() } + override fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: A) -> R): R = + getOrModify(source).map(map).getOrElse { empty } + /** * Join two [POptionalGetter] with the same focus */ diff --git a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Prism.kt b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Prism.kt index 96e420e9415..b4be2ccdf2a 100644 --- a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Prism.kt +++ b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/Prism.kt @@ -10,6 +10,7 @@ import arrow.core.identity import arrow.core.left import arrow.core.right import arrow.typeclasses.Monoid +import arrow.typeclasses.MonoidDeprecation import kotlin.jvm.JvmName import kotlin.jvm.JvmStatic @@ -41,9 +42,13 @@ public interface PPrism : POptional, PSetter public fun reverseGet(focus: B): T + @Deprecated(MonoidDeprecation, ReplaceWith("foldMap(empty, {r1, r2 -> r1 + r2}, source, map)", "arrow.optics.foldMap")) override fun foldMap(M: Monoid, source: S, map: (focus: A) -> R): R = getOrNull(source)?.let(map) ?: M.empty() + override fun foldMap(empty: R, combine: (R, R) -> R, source: S, map: (focus: A) -> R): R = + getOrNull(source)?.let(map) ?: empty + /** * Modify the focus of a [PPrism] with a function */ diff --git a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/typeclasses/FilterIndex.kt b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/typeclasses/FilterIndex.kt index 16c0d920bc6..042ee01fbc8 100644 --- a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/typeclasses/FilterIndex.kt +++ b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/typeclasses/FilterIndex.kt @@ -43,6 +43,9 @@ public fun interface FilterIndex { override fun modify(source: List, map: (focus: A) -> A): List = source.mapIndexed { index, a -> if (p(index)) map(a) else a } + + override fun foldMap(empty: R, combine: (R, R) -> R, source: List, map: (focus: A) -> R): R = + source.foldIndexed(empty) { index, acc, a -> if (p(index)) combine(acc, map(a)) else acc } } } @@ -58,6 +61,9 @@ public fun interface FilterIndex { override fun modify(source: Map, map: (focus: V) -> V): Map = source.mapValues { (k, v) -> if (p(k)) map(v) else v } + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Map, map: (focus: V) -> R): R = + source.entries.fold(empty) { acc, (k, v) -> if (p(k)) combine(acc, map(v)) else acc } } } @@ -77,6 +83,9 @@ public fun interface FilterIndex { override fun modify(source: NonEmptyList, map: (focus: A) -> A): NonEmptyList = source.mapIndexed { index, a -> if (p(index)) map(a) else a }.toNonEmptyListOrNull() ?: throw IndexOutOfBoundsException("Empty list doesn't contain element at index 0.") + + override fun foldMap(empty: R, combine: (R, R) -> R, source: NonEmptyList, map: (focus: A) -> R): R = + source.foldIndexed(empty) { index, acc, r -> if (p(index)) combine(acc, map(r)) else acc } } } @@ -92,6 +101,9 @@ public fun interface FilterIndex { override fun modify(source: Sequence, map: (focus: A) -> A): Sequence = source.mapIndexed { index, a -> if (p(index)) map(a) else a } + + override fun foldMap(empty: R, combine: (R, R) -> R, source: Sequence, map: (focus: A) -> R): R = + source.foldIndexed(empty) { index, acc, a -> if (p(index)) combine(acc, map(a)) else acc } } }