From fbba669996f2279d177404f07fd6d19525162737 Mon Sep 17 00:00:00 2001 From: Marc Moreno Ferrer Date: Mon, 5 Dec 2022 15:34:10 +0100 Subject: [PATCH] Feature/remove validated (#2795) Co-authored-by: Simon Vergauwen Co-authored-by: Alejandro Serrano --- README.md | 2 +- .../commonMain/kotlin/arrow/atomic/Atomic.kt | 1 + .../kotlin/examples/example-atomic-01.kt | 1 + .../kotlin/arrow/continuations/Reset.kt | 2 +- .../continuations/generic/ControlThrowable.kt | 2 +- .../continuations/generic/ControlThrowable.kt | 2 +- .../continuations/generic/ControlThrowable.kt | 2 +- .../generic/ControlThrowable.kt | 2 +- .../arrow-core-test/api/arrow-core-test.api | 1 - .../arrow/core/test/generators/Generators.kt | 5 - arrow-libs/core/arrow-core/api/arrow-core.api | 337 +------ .../commonMain/kotlin/arrow/core/Either.kt | 391 ++------ .../commonMain/kotlin/arrow/core/EitherZip.kt | 382 ++++++++ .../src/commonMain/kotlin/arrow/core/Ior.kt | 353 ++------ .../commonMain/kotlin/arrow/core/Iterable.kt | 220 ++--- .../kotlin/arrow/core/NonEmptyList.kt | 95 -- .../commonMain/kotlin/arrow/core/Option.kt | 65 -- .../commonMain/kotlin/arrow/core/Sequence.kt | 128 +-- .../commonMain/kotlin/arrow/core/Validated.kt | 856 ------------------ .../kotlin/arrow/core/computations/either.kt | 7 - .../kotlin/arrow/core/computations/result.kt | 73 +- .../arrow/core/continuations/EagerEffect.kt | 0 .../kotlin/arrow/core/continuations/Effect.kt | 9 +- .../arrow/core/continuations/Mappers.kt | 5 - .../kotlin/arrow/core/continuations/Raise.kt | 7 - .../src/commonMain/kotlin/arrow/core/map.kt | 82 -- .../commonMain/kotlin/arrow/core/predef.kt | 8 +- .../kotlin/arrow/typeclasses/Monoid.kt | 63 +- .../kotlin/arrow/typeclasses/Semigroup.kt | 55 +- .../kotlin/arrow/core/EitherTest.kt | 138 +-- .../kotlin/arrow/core/EitherZipTest.kt | 117 +++ .../commonTest/kotlin/arrow/core/IorTest.kt | 148 +-- .../kotlin/arrow/core/IterableTest.kt | 234 +---- .../commonTest/kotlin/arrow/core/MapKTest.kt | 87 +- .../kotlin/arrow/core/NonEmptyListTest.kt | 136 +-- .../kotlin/arrow/core/OptionTest.kt | 39 - .../kotlin/arrow/core/SequenceKTest.kt | 65 -- .../kotlin/arrow/core/ValidatedTest.kt | 519 ----------- .../arrow/core/computations/ResultTest.kt | 1 + .../jvmTest/java/arrow/core/DeadlockTest.kt | 14 - .../java/arrow/core/ValidatedUsage.java | 19 - .../arrow/typeclasses/MonoidUsageTest.java | 3 - .../arrow/typeclasses/SemigroupUsageTest.java | 1 - .../kotlin/examples/example-effect-02.kt | 3 - .../kotlin/examples/example-either-02.kt | 6 +- .../kotlin/examples/example-either-03.kt | 7 +- .../kotlin/examples/example-either-04.kt | 4 +- .../kotlin/examples/example-either-05.kt | 14 +- .../kotlin/examples/example-either-06.kt | 18 +- .../kotlin/examples/example-either-07.kt | 18 +- .../kotlin/examples/example-either-08.kt | 20 +- .../kotlin/examples/example-either-09.kt | 16 +- .../kotlin/examples/example-either-10.kt | 31 +- .../kotlin/examples/example-either-11.kt | 19 +- .../kotlin/examples/example-either-12.kt | 35 +- .../kotlin/examples/example-either-13.kt | 73 +- .../kotlin/examples/example-either-14.kt | 80 +- .../kotlin/examples/example-either-15.kt | 10 +- .../kotlin/examples/example-either-16.kt | 9 +- .../kotlin/examples/example-either-17.kt | 8 +- .../kotlin/examples/example-either-18.kt | 9 +- .../kotlin/examples/example-either-19.kt | 10 +- .../kotlin/examples/example-either-20.kt | 6 +- .../kotlin/examples/example-either-21.kt | 9 +- .../kotlin/examples/example-either-22.kt | 2 +- .../kotlin/examples/example-either-23.kt | 7 +- .../kotlin/examples/example-either-24.kt | 6 +- .../kotlin/examples/example-either-25.kt | 13 +- .../kotlin/examples/example-either-26.kt | 17 +- .../kotlin/examples/example-either-27.kt | 8 +- .../kotlin/examples/example-either-28.kt | 4 +- .../kotlin/examples/example-either-29.kt | 5 +- .../kotlin/examples/example-either-30.kt | 2 +- .../kotlin/examples/example-either-31.kt | 4 +- .../kotlin/examples/example-either-32.kt | 2 +- .../kotlin/examples/example-either-33.kt | 14 +- .../kotlin/examples/example-either-34.kt | 8 +- .../kotlin/examples/example-either-35.kt | 4 +- .../kotlin/examples/example-either-36.kt | 4 +- .../kotlin/examples/example-either-37.kt | 3 +- .../kotlin/examples/example-either-38.kt | 2 +- .../kotlin/examples/example-either-39.kt | 10 +- .../kotlin/examples/example-either-40.kt | 11 +- .../kotlin/examples/example-either-41.kt | 6 +- .../kotlin/examples/example-either-42.kt | 12 +- .../kotlin/examples/example-either-43.kt | 7 +- .../kotlin/examples/example-either-44.kt | 8 - .../kotlin/examples/example-either-45.kt | 12 + .../kotlin/examples/example-either-46.kt | 20 +- .../kotlin/examples/example-either-47.kt | 9 +- .../kotlin/examples/example-either-48.kt | 10 +- .../kotlin/examples/example-either-49.kt | 5 +- .../kotlin/examples/example-either-50.kt | 13 +- .../kotlin/examples/example-either-51.kt | 19 +- .../kotlin/examples/example-either-52.kt | 18 +- .../kotlin/examples/example-either-53.kt | 13 +- .../kotlin/examples/example-either-54.kt | 9 +- .../kotlin/examples/example-either-55.kt | 12 +- .../kotlin/examples/example-either-56.kt | 13 - .../jvmTest/kotlin/examples/example-ior-12.kt | 8 +- .../jvmTest/kotlin/examples/example-ior-13.kt | 15 +- .../jvmTest/kotlin/examples/example-ior-14.kt | 13 - .../example-result-computations-01.kt | 2 +- .../kotlin/examples/example-validated-01.kt | 14 - .../kotlin/examples/example-validated-02.kt | 12 - .../kotlin/examples/example-validated-03.kt | 9 - .../kotlin/examples/example-validated-04.kt | 9 - .../kotlin/examples/example-validated-05.kt | 13 - .../kotlin/examples/example-validated-06.kt | 11 - .../kotlin/examples/test/EitherKnitTest.kt | 24 +- .../api/arrow-fx-coroutines-test.api | 2 - .../kotlin/arrow/fx/coroutines/predef-test.kt | 20 - .../api/arrow-fx-coroutines.api | 18 - .../arrow/fx/coroutines/ParTraverseResult.kt | 8 +- .../fx/coroutines/ParTraverseValidated.kt | 210 ----- .../fx/coroutines/ParTraverseEitherTest.kt | 7 +- .../fx/coroutines/ParTraverseResultTest.kt | 6 +- .../fx/coroutines/ParTraverseValidatedTest.kt | 89 -- .../coroutines/ParTraverseValidatedJvmTest.kt | 26 - .../example-partraversevalidated-01.kt | 21 - .../example-partraversevalidated-02.kt | 26 - .../optics/arrow-optics/api/arrow-optics.api | 8 - .../commonMain/kotlin/arrow/optics/Fold.kt | 16 +- .../src/commonMain/kotlin/arrow/optics/Iso.kt | 37 - .../commonMain/kotlin/arrow/optics/predef.kt | 2 +- .../kotlin/arrow/optics/std/EitherTest.kt | 25 - .../kotlin/arrow/optics/std/ValidatedTest.kt | 27 - arrow-site/docs/_code/fx-home-code.md | 6 +- arrow-site/docs/_data/sidebar-core.yml | 3 - arrow-site/docs/docs/core/README.md | 7 +- .../docs/docs/datatypes/intro/README.md | 2 - .../docs/patterns/errorhandling/README.md | 40 +- .../docs/docs/patterns/monads/README.md | 2 +- arrow-site/docs/docs/quickstart/README.md | 2 +- 134 files changed, 1325 insertions(+), 4809 deletions(-) create mode 100644 arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/EitherZip.kt delete mode 100644 arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Validated.kt create mode 100644 arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffect.kt create mode 100644 arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherZipTest.kt delete mode 100644 arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ValidatedTest.kt delete mode 100644 arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/ValidatedUsage.java delete mode 100644 arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-56.kt delete mode 100644 arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-14.kt delete mode 100644 arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-01.kt delete mode 100644 arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-02.kt delete mode 100644 arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-03.kt delete mode 100644 arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-04.kt delete mode 100644 arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-05.kt delete mode 100644 arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-06.kt delete mode 100644 arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseValidated.kt delete mode 100644 arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedTest.kt delete mode 100644 arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedJvmTest.kt delete mode 100644 arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/examples/example-partraversevalidated-01.kt delete mode 100644 arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/examples/example-partraversevalidated-02.kt delete mode 100644 arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/std/EitherTest.kt delete mode 100644 arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/std/ValidatedTest.kt diff --git a/README.md b/README.md index b432f390580..ce858aa92b9 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Arrow aims to provide a [*lingua franca*](https://en.wikipedia.org/wiki/Lingua_franca) of interfaces and abstractions across Kotlin libraries. For this, it includes the most popular data types such -as `Option`, `Either`, `Validated` etc and functional operators such as `traverse` and computation +as `Option`, `Either` etc and functional operators such as `traverse` and computation blocks to empower users to write pure FP apps and libraries built atop higher order abstractions. Use the list below to learn more about Λrrow's main features. diff --git a/arrow-libs/core/arrow-atomic/src/commonMain/kotlin/arrow/atomic/Atomic.kt b/arrow-libs/core/arrow-atomic/src/commonMain/kotlin/arrow/atomic/Atomic.kt index b4824ff0ce4..a0b2ab1631c 100644 --- a/arrow-libs/core/arrow-atomic/src/commonMain/kotlin/arrow/atomic/Atomic.kt +++ b/arrow-libs/core/arrow-atomic/src/commonMain/kotlin/arrow/atomic/Atomic.kt @@ -9,6 +9,7 @@ public expect fun Atomic(initialValue: A): Atomic * import arrow.atomic.Atomic * import arrow.atomic.update * import arrow.fx.coroutines.parTraverse + * * suspend fun main() { * val count = Atomic(0) * (0 until 20_000).parTraverse { diff --git a/arrow-libs/core/arrow-atomic/src/jvmTest/kotlin/examples/example-atomic-01.kt b/arrow-libs/core/arrow-atomic/src/jvmTest/kotlin/examples/example-atomic-01.kt index 418d6c41d7a..5bf7a24ce01 100644 --- a/arrow-libs/core/arrow-atomic/src/jvmTest/kotlin/examples/example-atomic-01.kt +++ b/arrow-libs/core/arrow-atomic/src/jvmTest/kotlin/examples/example-atomic-01.kt @@ -4,6 +4,7 @@ package arrow.atomic.examples.exampleAtomic01 import arrow.atomic.Atomic import arrow.atomic.update import arrow.fx.coroutines.parTraverse + suspend fun main() { val count = Atomic(0) (0 until 20_000).parTraverse { diff --git a/arrow-libs/core/arrow-continuations/src/commonMain/kotlin/arrow/continuations/Reset.kt b/arrow-libs/core/arrow-continuations/src/commonMain/kotlin/arrow/continuations/Reset.kt index cd620c38fa7..c6a4dab39d7 100644 --- a/arrow-libs/core/arrow-continuations/src/commonMain/kotlin/arrow/continuations/Reset.kt +++ b/arrow-libs/core/arrow-continuations/src/commonMain/kotlin/arrow/continuations/Reset.kt @@ -20,7 +20,7 @@ internal object Reset { * The usage of `try { ... } catch(e: Throwable) { ... }` will catch the [ShortCircuit] error, * and will lead to recover of short-circuiting. * You should always prefer to catch the most specific exception class, or - * use `Either.catch`, `Validated.catch` etc or `e.nonFatalOrThrow()` + * use `Either.catch` etc or `e.nonFatalOrThrow()` * to ensure you're not catching `ShortCircuit`. */ @Deprecated(deprecateArrowContinuation) diff --git a/arrow-libs/core/arrow-continuations/src/commonMain/kotlin/arrow/continuations/generic/ControlThrowable.kt b/arrow-libs/core/arrow-continuations/src/commonMain/kotlin/arrow/continuations/generic/ControlThrowable.kt index 4ddbfe07b65..234953e85a9 100644 --- a/arrow-libs/core/arrow-continuations/src/commonMain/kotlin/arrow/continuations/generic/ControlThrowable.kt +++ b/arrow-libs/core/arrow-continuations/src/commonMain/kotlin/arrow/continuations/generic/ControlThrowable.kt @@ -4,7 +4,7 @@ package arrow.continuations.generic * A [Throwable] class intended for control flow. * Instance of [ControlThrowable] should **not** be caught, * and `arrow.core.NonFatal` does not catch this [Throwable]. - * Thus by extension `Either.catch` and `Validated.catch` also don't catch [ControlThrowable]. + * Thus by extension `Either.catch` also don't catch [ControlThrowable]. */ @Deprecated(deprecateArrowContinuation) public expect open class ControlThrowable() : Throwable diff --git a/arrow-libs/core/arrow-continuations/src/jsMain/kotlin/arrow/continuations/generic/ControlThrowable.kt b/arrow-libs/core/arrow-continuations/src/jsMain/kotlin/arrow/continuations/generic/ControlThrowable.kt index 83e3ef54c08..aab29577711 100644 --- a/arrow-libs/core/arrow-continuations/src/jsMain/kotlin/arrow/continuations/generic/ControlThrowable.kt +++ b/arrow-libs/core/arrow-continuations/src/jsMain/kotlin/arrow/continuations/generic/ControlThrowable.kt @@ -4,7 +4,7 @@ package arrow.continuations.generic * A [Throwable] class intended for control flow. * Instance of [ControlThrowable.kt] should **not** be caught, * and `arrow.core.NonFatal` does not catch this [Throwable]. - * Thus by extension `Either.catch` and `Validated.catch` also don't catch [ControlThrowable.kt]. + * Thus by extension `Either.catch` also don't catch [ControlThrowable.kt]. */ @Deprecated(deprecateArrowContinuation) public actual open class ControlThrowable : Throwable() diff --git a/arrow-libs/core/arrow-continuations/src/jvmMain/kotlin/arrow/continuations/generic/ControlThrowable.kt b/arrow-libs/core/arrow-continuations/src/jvmMain/kotlin/arrow/continuations/generic/ControlThrowable.kt index 5b773b30a7d..46bf67112e5 100644 --- a/arrow-libs/core/arrow-continuations/src/jvmMain/kotlin/arrow/continuations/generic/ControlThrowable.kt +++ b/arrow-libs/core/arrow-continuations/src/jvmMain/kotlin/arrow/continuations/generic/ControlThrowable.kt @@ -5,7 +5,7 @@ package arrow.continuations.generic * A [Throwable] class intended for control flow. * Instance of [ControlThrowable.kt] should **not** be caught, * and `arrow.core.NonFatal` does not catch this [Throwable]. - * Thus by extension `Either.catch` and `Validated.catch` also don't catch [ControlThrowable.kt]. + * Thus by extension `Either.catch` also don't catch [ControlThrowable.kt]. */ @Deprecated(deprecateArrowContinuation) public actual open class ControlThrowable : Throwable() { diff --git a/arrow-libs/core/arrow-continuations/src/nativeMain/kotlin/arrow.continuations/generic/ControlThrowable.kt b/arrow-libs/core/arrow-continuations/src/nativeMain/kotlin/arrow.continuations/generic/ControlThrowable.kt index dedc2b8463c..839dc4043ba 100644 --- a/arrow-libs/core/arrow-continuations/src/nativeMain/kotlin/arrow.continuations/generic/ControlThrowable.kt +++ b/arrow-libs/core/arrow-continuations/src/nativeMain/kotlin/arrow.continuations/generic/ControlThrowable.kt @@ -4,7 +4,7 @@ package arrow.continuations.generic * A [Throwable] class intended for control flow. * Instance of [ControlThrowable] should **not** be caught, * and `arrow.core.NonFatal` does not catch this [Throwable]. - * Thus by extension `Either.catch` and `Validated.catch` also don't catch [ControlThrowable]. + * Thus by extension `Either.catch` also don't catch [ControlThrowable]. */ @Deprecated(deprecateArrowContinuation) public actual open class ControlThrowable : Throwable() diff --git a/arrow-libs/core/arrow-core-test/api/arrow-core-test.api b/arrow-libs/core/arrow-core-test/api/arrow-core-test.api index 1d009c7d92f..edddd74f650 100644 --- a/arrow-libs/core/arrow-core-test/api/arrow-core-test.api +++ b/arrow-libs/core/arrow-core-test/api/arrow-core-test.api @@ -101,7 +101,6 @@ public final class arrow/core/test/generators/GeneratorsKt { public static final fun tuple8 (Lio/kotest/property/Arb$Companion;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;)Lio/kotest/property/Arb; public static final fun tuple9 (Lio/kotest/property/Arb$Companion;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;Lio/kotest/property/Arb;)Lio/kotest/property/Arb; public static final fun unit (Lio/kotest/property/Arb$Companion;)Lio/kotest/property/Arb; - public static final fun validated (Lio/kotest/property/Arb$Companion;Lio/kotest/property/Arb;Lio/kotest/property/Arb;)Lio/kotest/property/Arb; } public final class arrow/core/test/generators/UtilsKt { diff --git a/arrow-libs/core/arrow-core-test/src/commonMain/kotlin/arrow/core/test/generators/Generators.kt b/arrow-libs/core/arrow-core-test/src/commonMain/kotlin/arrow/core/test/generators/Generators.kt index 49c19601228..06b2caee06e 100644 --- a/arrow-libs/core/arrow-core-test/src/commonMain/kotlin/arrow/core/test/generators/Generators.kt +++ b/arrow-libs/core/arrow-core-test/src/commonMain/kotlin/arrow/core/test/generators/Generators.kt @@ -13,7 +13,6 @@ import arrow.core.Tuple6 import arrow.core.Tuple7 import arrow.core.Tuple8 import arrow.core.Tuple9 -import arrow.core.Validated import arrow.core.left import arrow.core.right import arrow.core.test.concurrency.deprecateArrowTestModules @@ -220,10 +219,6 @@ public fun Arb.Companion.either(arbE: Arb, arbA: Arb): Arb Arb.or(arbA: Arb): Arb> = Arb.either(this, arbA) -@Deprecated(deprecateArrowTestModules) -public fun Arb.Companion.validated(arbE: Arb, arbA: Arb): Arb> = - Arb.either(arbE, arbA).map { Validated.fromEither(it) } - @Deprecated(deprecateArrowTestModules) public fun Arb.Companion.unit(): Arb = Arb.constant(Unit) diff --git a/arrow-libs/core/arrow-core/api/arrow-core.api b/arrow-libs/core/arrow-core/api/arrow-core.api index a6fc6341ea9..cc1e8a88fda 100644 --- a/arrow-libs/core/arrow-core/api/arrow-core.api +++ b/arrow-libs/core/arrow-core/api/arrow-core.api @@ -155,10 +155,6 @@ public abstract class arrow/core/Either { public final fun bifoldLeft (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public final fun bifoldMap (Larrow/typeclasses/Monoid;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public final fun bimap (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public final fun bitraverse (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public final fun bitraverseNullable (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public final fun bitraverseOption (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public final fun bitraverseValidated (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; public static final fun conditionally (ZLkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)Larrow/core/Either; public final fun exists (Lkotlin/jvm/functions/Function1;)Z public final fun findOrNull (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; @@ -186,14 +182,6 @@ public abstract class arrow/core/Either { public final fun tap (Lkotlin/jvm/functions/Function1;)Larrow/core/Either; public final fun tapLeft (Lkotlin/jvm/functions/Function1;)Larrow/core/Either; public fun toString ()Ljava/lang/String; - public final fun toValidated ()Larrow/core/Validated; - public final fun toValidatedNel ()Larrow/core/Validated; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public final fun traverseNullable (Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public final fun traverseOption (Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public final fun traverseValidated (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; public static final fun tryCatch (Lkotlin/jvm/functions/Function0;)Larrow/core/Either; public static final fun tryCatch (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Larrow/core/Either; public static final fun tryCatchAndFlatten (Lkotlin/jvm/functions/Function0;)Larrow/core/Either; @@ -246,10 +234,6 @@ public final class arrow/core/Either$Right$Companion { public final class arrow/core/EitherKt { public static final field NicheAPI Ljava/lang/String; public static final field RedundantAPI Ljava/lang/String; - public static final fun bisequence (Larrow/core/Either;)Ljava/util/List; - public static final fun bisequenceNullable (Larrow/core/Either;)Larrow/core/Either; - public static final fun bisequenceOption (Larrow/core/Either;)Larrow/core/Option; - public static final fun bisequenceValidated (Larrow/core/Either;)Larrow/core/Validated; public static final fun combine (Larrow/core/Either;Larrow/typeclasses/Semigroup;Larrow/typeclasses/Semigroup;Larrow/core/Either;)Larrow/core/Either; public static final fun combineAll (Ljava/lang/Iterable;Larrow/typeclasses/Monoid;Larrow/typeclasses/Monoid;)Larrow/core/Either; public static final fun combineK (Larrow/core/Either;Larrow/core/Either;)Larrow/core/Either; @@ -277,15 +261,9 @@ public final class arrow/core/EitherKt { public static final fun right (Ljava/lang/Object;)Larrow/core/Either; public static final fun rightIfNotNull (Ljava/lang/Object;Lkotlin/jvm/functions/Function0;)Larrow/core/Either; public static final fun rightIfNull (Ljava/lang/Object;Lkotlin/jvm/functions/Function0;)Larrow/core/Either; - public static final fun sequence (Larrow/core/Either;)Larrow/core/Either; - public static final fun sequence (Larrow/core/Either;)Larrow/core/Option; - public static final fun sequence (Larrow/core/Either;)Larrow/core/Validated; - public static final fun sequence (Larrow/core/Either;)Ljava/util/List; - public static final fun sequenceNullable (Larrow/core/Either;)Larrow/core/Either; - public static final fun sequenceOption (Larrow/core/Either;)Larrow/core/Option; - public static final fun sequenceValidated (Larrow/core/Either;)Larrow/core/Validated; + public static final fun toEitherNel (Larrow/core/Either;)Larrow/core/Either; + public static final fun toEitherNel (Ljava/lang/Object;)Larrow/core/Either; public static final fun widen (Larrow/core/Either;)Larrow/core/Either; - public static final fun zip (Larrow/core/Either;Larrow/core/Either;)Larrow/core/Either; public static final fun zip (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 static final fun zip (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 static final fun zip (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; @@ -295,10 +273,29 @@ public final class arrow/core/EitherKt { public static final fun zip (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function4;)Larrow/core/Either; public static final fun zip (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function3;)Larrow/core/Either; public static final fun zip (Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function2;)Larrow/core/Either; + public static final fun zip (Larrow/core/Either;Larrow/typeclasses/Semigroup;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 static final fun zip (Larrow/core/Either;Larrow/typeclasses/Semigroup;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 static final fun zip (Larrow/core/Either;Larrow/typeclasses/Semigroup;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 static final fun zip (Larrow/core/Either;Larrow/typeclasses/Semigroup;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 static final fun zip (Larrow/core/Either;Larrow/typeclasses/Semigroup;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function6;)Larrow/core/Either; + public static final fun zip (Larrow/core/Either;Larrow/typeclasses/Semigroup;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function5;)Larrow/core/Either; + public static final fun zip (Larrow/core/Either;Larrow/typeclasses/Semigroup;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function4;)Larrow/core/Either; + public static final fun zip (Larrow/core/Either;Larrow/typeclasses/Semigroup;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function3;)Larrow/core/Either; + public static final fun zip (Larrow/core/Either;Larrow/typeclasses/Semigroup;Larrow/core/Either;Lkotlin/jvm/functions/Function2;)Larrow/core/Either; + public static final fun zipNonEmptyList (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 static final fun zipNonEmptyList (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 static final fun zipNonEmptyList (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 static final fun zipNonEmptyList (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 static final fun zipNonEmptyList (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 static final fun zipNonEmptyList (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function5;)Larrow/core/Either; + public static final fun zipNonEmptyList (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function4;)Larrow/core/Either; + public static final fun zipNonEmptyList (Larrow/core/Either;Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function3;)Larrow/core/Either; + public static final fun zipNonEmptyList (Larrow/core/Either;Larrow/core/Either;Lkotlin/jvm/functions/Function2;)Larrow/core/Either; } public final class arrow/core/EmptyValue { public static final field INSTANCE Larrow/core/EmptyValue; + public final fun combine (Ljava/lang/Object;Ljava/lang/Object;Larrow/typeclasses/Semigroup;)Ljava/lang/Object; public final fun unbox (Ljava/lang/Object;)Ljava/lang/Object; } @@ -429,11 +426,6 @@ public abstract class arrow/core/Ior { public final fun bifoldLeft (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public final fun bifoldMap (Larrow/typeclasses/Monoid;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public final fun bimap (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Ior; - public final fun bitraverse (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public final fun bitraverseEither (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public final fun bitraverseNullable (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Ior; - public final fun bitraverseOption (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public final fun bitraverseValidated (Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; public static final fun bothNel (Ljava/lang/Object;Ljava/lang/Object;)Larrow/core/Ior; public final fun crosswalk (Lkotlin/jvm/functions/Function1;)Ljava/util/List; public final fun crosswalkMap (Lkotlin/jvm/functions/Function1;)Ljava/util/Map; @@ -460,15 +452,6 @@ public abstract class arrow/core/Ior { public final fun swap ()Larrow/core/Ior; public final fun toEither ()Larrow/core/Either; public fun toString ()Ljava/lang/String; - public final fun toValidated ()Larrow/core/Validated; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public final fun traverseEither (Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public final fun traverseNullable (Lkotlin/jvm/functions/Function1;)Larrow/core/Ior; - public final fun traverseOption (Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public final fun traverseValidated (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; public final fun unwrap ()Larrow/core/Either; public final fun void ()Larrow/core/Ior; } @@ -535,11 +518,6 @@ public final class arrow/core/Ior$Right$Companion { } public final class arrow/core/IorKt { - public static final fun bisequence (Larrow/core/Ior;)Ljava/util/List; - public static final fun bisequenceEither (Larrow/core/Ior;)Larrow/core/Either; - public static final fun bisequenceNullable (Larrow/core/Ior;)Larrow/core/Ior; - public static final fun bisequenceOption (Larrow/core/Ior;)Larrow/core/Option; - public static final fun bisequenceValidated (Larrow/core/Ior;Larrow/typeclasses/Semigroup;)Larrow/core/Validated; public static final fun bothIor (Lkotlin/Pair;)Larrow/core/Ior; public static final fun combine (Larrow/core/Ior;Larrow/typeclasses/Semigroup;Larrow/typeclasses/Semigroup;Larrow/core/Ior;)Larrow/core/Ior; public static final fun compareTo (Larrow/core/Ior;Larrow/core/Ior;)I @@ -551,15 +529,6 @@ public final class arrow/core/IorKt { public static final fun replicate (Larrow/core/Ior;Larrow/typeclasses/Semigroup;I)Larrow/core/Ior; public static final fun replicate (Larrow/core/Ior;Larrow/typeclasses/Semigroup;ILarrow/typeclasses/Monoid;)Larrow/core/Ior; public static final fun rightIor (Ljava/lang/Object;)Larrow/core/Ior; - public static final fun sequence (Larrow/core/Ior;)Larrow/core/Either; - public static final fun sequence (Larrow/core/Ior;)Larrow/core/Ior; - public static final fun sequence (Larrow/core/Ior;)Larrow/core/Option; - public static final fun sequence (Larrow/core/Ior;)Larrow/core/Validated; - public static final fun sequence (Larrow/core/Ior;)Ljava/util/List; - public static final fun sequenceEither (Larrow/core/Ior;)Larrow/core/Either; - public static final fun sequenceNullable (Larrow/core/Ior;)Larrow/core/Ior; - public static final fun sequenceOption (Larrow/core/Ior;)Larrow/core/Option; - public static final fun sequenceValidated (Larrow/core/Ior;)Larrow/core/Validated; public static final fun widen (Larrow/core/Ior;)Larrow/core/Ior; public static final fun zip (Larrow/core/Ior;Larrow/typeclasses/Semigroup;Larrow/core/Ior;)Larrow/core/Ior; public static final fun zip (Larrow/core/Ior;Larrow/typeclasses/Semigroup;Larrow/core/Ior;Larrow/core/Ior;Larrow/core/Ior;Larrow/core/Ior;Larrow/core/Ior;Larrow/core/Ior;Larrow/core/Ior;Larrow/core/Ior;Larrow/core/Ior;Lkotlin/jvm/functions/Function10;)Larrow/core/Ior; @@ -597,6 +566,8 @@ public final class arrow/core/IterableKt { public static final fun lastOrNone (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; public static final fun leftPadZip (Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/List; public static final fun leftPadZip (Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Ljava/util/List; + public static final fun mapOrAccumulate (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function2;)Larrow/core/Either; + public static final fun mapOrAccumulate (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Larrow/core/Either; public static final fun padZip (Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/List; public static final fun padZip (Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Ljava/util/List; public static final fun prependTo (Ljava/lang/Object;Ljava/lang/Iterable;)Ljava/util/List; @@ -608,39 +579,13 @@ public final class arrow/core/IterableKt { public static final fun rightPadZip (Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Ljava/util/List; public static final fun salign (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;Ljava/lang/Iterable;)Ljava/lang/Iterable; public static final fun separateEither (Ljava/lang/Iterable;)Lkotlin/Pair; - public static final fun separateValidated (Ljava/lang/Iterable;)Lkotlin/Pair; - public static final fun sequence (Ljava/lang/Iterable;)Larrow/core/Either; - public static final fun sequence (Ljava/lang/Iterable;)Larrow/core/Option; - public static final fun sequence (Ljava/lang/Iterable;)Larrow/core/Validated; - public static final fun sequence (Ljava/lang/Iterable;)Ljava/lang/Object; - public static final fun sequence (Ljava/lang/Iterable;)Ljava/util/List; - public static final fun sequence (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;)Larrow/core/Validated; - public static final fun sequenceEither (Ljava/lang/Iterable;)Larrow/core/Either; - public static final fun sequenceNullable (Ljava/lang/Iterable;)Ljava/util/List; - public static final fun sequenceOption (Ljava/lang/Iterable;)Larrow/core/Option; - public static final fun sequenceResult (Ljava/lang/Iterable;)Ljava/lang/Object; - public static final fun sequenceValidated (Ljava/lang/Iterable;)Larrow/core/Validated; - public static final fun sequenceValidated (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;)Larrow/core/Validated; public static final fun singleOrNone (Ljava/lang/Iterable;)Larrow/core/Option; public static final fun singleOrNone (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; public static final fun split (Ljava/lang/Iterable;)Lkotlin/Pair; public static final fun tail (Ljava/lang/Iterable;)Ljava/util/List; - public static final fun traverse (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public static final fun traverse (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public static final fun traverse (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public static final fun traverse (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public static final fun traverse (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public static final fun traverse (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public static final fun traverseEither (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public static final fun traverseNullable (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public static final fun traverseOption (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public static final fun traverseResult (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public static final fun traverseValidated (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public static final fun traverseValidated (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; public static final fun unalign (Ljava/lang/Iterable;)Lkotlin/Pair; public static final fun unalign (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair; public static final fun uniteEither (Ljava/lang/Iterable;)Ljava/util/List; - public static final fun uniteValidated (Ljava/lang/Iterable;)Ljava/util/List; public static final fun unweave (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/util/List; public static final fun unzip (Ljava/lang/Iterable;)Lkotlin/Pair; public static final fun unzip (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair; @@ -670,18 +615,6 @@ public final class arrow/core/MapKt { public static final fun padZip (Ljava/util/Map;Ljava/util/Map;)Ljava/util/Map; public static final fun padZip (Ljava/util/Map;Ljava/util/Map;Lkotlin/jvm/functions/Function3;)Ljava/util/Map; public static final fun salign (Ljava/util/Map;Larrow/typeclasses/Semigroup;Ljava/util/Map;)Ljava/util/Map; - public static final fun sequence (Ljava/util/Map;)Larrow/core/Either; - public static final fun sequence (Ljava/util/Map;)Larrow/core/Option; - public static final fun sequence (Ljava/util/Map;Larrow/typeclasses/Semigroup;)Larrow/core/Validated; - public static final fun sequenceEither (Ljava/util/Map;)Larrow/core/Either; - public static final fun sequenceOption (Ljava/util/Map;)Larrow/core/Option; - public static final fun sequenceValidated (Ljava/util/Map;Larrow/typeclasses/Semigroup;)Larrow/core/Validated; - public static final fun traverse (Ljava/util/Map;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public static final fun traverse (Ljava/util/Map;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public static final fun traverse (Ljava/util/Map;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public static final fun traverseEither (Ljava/util/Map;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public static final fun traverseOption (Ljava/util/Map;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public static final fun traverseValidated (Ljava/util/Map;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; public static final fun unalign (Ljava/util/Map;)Lkotlin/Pair; public static final fun unalign (Ljava/util/Map;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair; public static final fun unzip (Ljava/util/Map;)Lkotlin/Pair; @@ -763,20 +696,8 @@ public final class arrow/core/NonEmptyListKt { public static final fun minBy (Larrow/core/NonEmptyList;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static final fun nel (Ljava/lang/Object;)Larrow/core/NonEmptyList; public static final fun nonEmptyListOf (Ljava/lang/Object;[Ljava/lang/Object;)Larrow/core/NonEmptyList; - public static final fun sequence (Larrow/core/NonEmptyList;)Larrow/core/Either; - public static final fun sequence (Larrow/core/NonEmptyList;)Larrow/core/Option; - public static final fun sequence (Larrow/core/NonEmptyList;Larrow/typeclasses/Semigroup;)Larrow/core/Validated; - public static final fun sequenceEither (Larrow/core/NonEmptyList;)Larrow/core/Either; - public static final fun sequenceOption (Larrow/core/NonEmptyList;)Larrow/core/Option; - public static final fun sequenceValidated (Larrow/core/NonEmptyList;Larrow/typeclasses/Semigroup;)Larrow/core/Validated; public static final fun toNonEmptyListOrNone (Ljava/lang/Iterable;)Larrow/core/Option; public static final fun toNonEmptyListOrNull (Ljava/lang/Iterable;)Larrow/core/NonEmptyList; - public static final fun traverse (Larrow/core/NonEmptyList;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public static final fun traverse (Larrow/core/NonEmptyList;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public static final fun traverse (Larrow/core/NonEmptyList;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public static final fun traverseEither (Larrow/core/NonEmptyList;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public static final fun traverseOption (Larrow/core/NonEmptyList;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public static final fun traverseValidated (Larrow/core/NonEmptyList;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; public static final fun unzip (Larrow/core/NonEmptyList;)Lkotlin/Pair; public static final fun unzip (Larrow/core/NonEmptyList;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair; } @@ -848,11 +769,6 @@ public abstract class arrow/core/Option { public final fun toEither (Lkotlin/jvm/functions/Function0;)Larrow/core/Either; public final fun toList ()Ljava/util/List; public fun toString ()Ljava/lang/String; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public final fun traverseEither (Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public final fun traverseValidated (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; public static final fun tryCatch (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Larrow/core/Option; public static final fun tryCatchOrNone (Lkotlin/jvm/functions/Function0;)Larrow/core/Option; public final fun void ()Larrow/core/Option; @@ -896,12 +812,6 @@ public final class arrow/core/OptionKt { public static final fun rethrow (Larrow/core/Option;)Larrow/core/Option; public static final fun salign (Larrow/core/Option;Larrow/typeclasses/Semigroup;Larrow/core/Option;)Larrow/core/Option; public static final fun separateEither (Larrow/core/Option;)Lkotlin/Pair; - public static final fun separateValidated (Larrow/core/Option;)Lkotlin/Pair; - public static final fun sequence (Larrow/core/Option;)Larrow/core/Either; - public static final fun sequence (Larrow/core/Option;)Larrow/core/Validated; - public static final fun sequence (Larrow/core/Option;)Ljava/util/List; - public static final fun sequenceEither (Larrow/core/Option;)Larrow/core/Either; - public static final fun sequenceValidated (Larrow/core/Option;)Larrow/core/Validated; public static final fun some (Ljava/lang/Object;)Larrow/core/Option; public static final fun toMap (Larrow/core/Option;)Ljava/util/Map; public static final fun toOption (Ljava/lang/Object;)Larrow/core/Option; @@ -909,7 +819,6 @@ public final class arrow/core/OptionKt { public static final fun unalign (Larrow/core/Option;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair; public static final fun unite (Larrow/core/Option;Larrow/typeclasses/Monoid;)Larrow/core/Option; public static final fun uniteEither (Larrow/core/Option;)Larrow/core/Option; - public static final fun uniteValidated (Larrow/core/Option;)Larrow/core/Option; public static final fun unzip (Larrow/core/Option;)Lkotlin/Pair; public static final fun unzip (Larrow/core/Option;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair; public static final fun widen (Larrow/core/Option;)Larrow/core/Option; @@ -1471,26 +1380,12 @@ public final class arrow/core/SequenceKt { public static final fun rightPadZip (Lkotlin/sequences/Sequence;Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence; public static final fun salign (Lkotlin/sequences/Sequence;Larrow/typeclasses/Semigroup;Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; public static final fun separateEither (Lkotlin/sequences/Sequence;)Lkotlin/Pair; - public static final fun separateValidated (Lkotlin/sequences/Sequence;)Lkotlin/Pair; - public static final fun sequence (Lkotlin/sequences/Sequence;)Larrow/core/Either; - public static final fun sequence (Lkotlin/sequences/Sequence;)Larrow/core/Option; - public static final fun sequence (Lkotlin/sequences/Sequence;Larrow/typeclasses/Semigroup;)Larrow/core/Validated; - public static final fun sequenceEither (Lkotlin/sequences/Sequence;)Larrow/core/Either; - public static final fun sequenceOption (Lkotlin/sequences/Sequence;)Larrow/core/Option; - public static final fun sequenceValidated (Lkotlin/sequences/Sequence;Larrow/typeclasses/Semigroup;)Larrow/core/Validated; public static final fun some (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; public static final fun split (Lkotlin/sequences/Sequence;)Lkotlin/Pair; public static final fun tail (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; - public static final fun traverse (Lkotlin/sequences/Sequence;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public static final fun traverse (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public static final fun traverse (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public static final fun traverseEither (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public static final fun traverseOption (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public static final fun traverseValidated (Lkotlin/sequences/Sequence;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; public static final fun unalign (Lkotlin/sequences/Sequence;)Lkotlin/Pair; public static final fun unalign (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair; public static final fun uniteEither (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; - public static final fun uniteValidated (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; public static final fun unweave (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence; public static final fun unzip (Lkotlin/sequences/Sequence;)Lkotlin/Pair; public static final fun unzip (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair; @@ -2312,164 +2207,14 @@ public final class arrow/core/UtilsKt { public static final fun mapNullable (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1; } -public abstract class arrow/core/Validated { - public static final field Companion Larrow/core/Validated$Companion; - public final fun all (Lkotlin/jvm/functions/Function1;)Z - public final fun bifoldLeft (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public final fun bifoldMap (Larrow/typeclasses/Monoid;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public final fun bimap (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public final fun bitraverse (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public final fun bitraverseEither (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public final fun bitraverseNullable (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public final fun bitraverseOption (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public static final fun catchNel (Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public final fun exist (Lkotlin/jvm/functions/Function1;)Z - public final fun findOrNull (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public final fun fold (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public final fun foldLeft (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public final fun foldMap (Larrow/typeclasses/Monoid;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public static final fun fromEither (Larrow/core/Either;)Larrow/core/Validated; - public static final fun fromNullable (Ljava/lang/Object;Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public static final fun fromOption (Larrow/core/Option;Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public static final fun invalidNel (Ljava/lang/Object;)Larrow/core/Validated; - public final fun isEmpty ()Z - public final fun isInvalid ()Z - public final fun isNotEmpty ()Z - public final fun isValid ()Z - public static final fun lift (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1; - public static final fun lift (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1; - public final fun map (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public final fun mapLeft (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public final fun swap ()Larrow/core/Validated; - public final fun tap (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public final fun tapInvalid (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public final fun toEither ()Larrow/core/Either; - public final fun toList ()Ljava/util/List; - public final fun toOption ()Larrow/core/Option; - public fun toString ()Ljava/lang/String; - public final fun toValidatedNel ()Larrow/core/Validated; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public final fun traverse (Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public final fun traverseEither (Lkotlin/jvm/functions/Function1;)Larrow/core/Either; - public final fun traverseNullable (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public final fun traverseOption (Lkotlin/jvm/functions/Function1;)Larrow/core/Option; - public static final fun tryCatch (Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public static final fun tryCatch (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public static final fun validNel (Ljava/lang/Object;)Larrow/core/Validated; - public final fun void ()Larrow/core/Validated; - public final fun withEither (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; -} - -public final class arrow/core/Validated$Companion { - public final fun catchNel (Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public final fun fromEither (Larrow/core/Either;)Larrow/core/Validated; - public final fun fromNullable (Ljava/lang/Object;Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public final fun fromOption (Larrow/core/Option;Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public final fun invalidNel (Ljava/lang/Object;)Larrow/core/Validated; - public final fun lift (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1; - public final fun lift (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1; - public final fun tryCatch (Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public final fun tryCatch (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public final fun validNel (Ljava/lang/Object;)Larrow/core/Validated; -} - -public final class arrow/core/Validated$Invalid : arrow/core/Validated { - public fun (Ljava/lang/Object;)V - public final fun component1 ()Ljava/lang/Object; - public final fun copy (Ljava/lang/Object;)Larrow/core/Validated$Invalid; - public static synthetic fun copy$default (Larrow/core/Validated$Invalid;Ljava/lang/Object;ILjava/lang/Object;)Larrow/core/Validated$Invalid; - public fun equals (Ljava/lang/Object;)Z - public final fun getValue ()Ljava/lang/Object; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class arrow/core/Validated$Valid : arrow/core/Validated { - public static final field Companion Larrow/core/Validated$Valid$Companion; - public fun (Ljava/lang/Object;)V - public final fun component1 ()Ljava/lang/Object; - public final fun copy (Ljava/lang/Object;)Larrow/core/Validated$Valid; - public static synthetic fun copy$default (Larrow/core/Validated$Valid;Ljava/lang/Object;ILjava/lang/Object;)Larrow/core/Validated$Valid; - public fun equals (Ljava/lang/Object;)Z - public final fun getValue ()Ljava/lang/Object; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class arrow/core/Validated$Valid$Companion { - public final fun getUnit ()Larrow/core/Validated; -} - -public final class arrow/core/ValidatedKt { - public static final fun andThen (Larrow/core/Validated;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public static final fun attempt (Larrow/core/Validated;)Larrow/core/Validated; - public static final fun bisequence (Larrow/core/Validated;)Ljava/util/List; - public static final fun bisequenceEither (Larrow/core/Validated;)Larrow/core/Either; - public static final fun bisequenceNullable (Larrow/core/Validated;)Larrow/core/Validated; - public static final fun bisequenceOption (Larrow/core/Validated;)Larrow/core/Option; - public static final fun combine (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/typeclasses/Semigroup;Larrow/core/Validated;)Larrow/core/Validated; - public static final fun combineAll (Larrow/core/Validated;Larrow/typeclasses/Monoid;)Ljava/lang/Object; - public static final fun combineK (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/core/Validated;)Larrow/core/Validated; - public static final fun compareTo (Larrow/core/Validated;Larrow/core/Validated;)I - public static final fun findValid (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public static final fun fold (Larrow/core/Validated;Larrow/typeclasses/Monoid;)Ljava/lang/Object; - public static final fun getOrElse (Larrow/core/Validated;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object; - public static final fun handleError (Larrow/core/Validated;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public static final fun handleErrorWith (Larrow/core/Validated;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public static final fun invalid (Ljava/lang/Object;)Larrow/core/Validated; - public static final fun invalidNel (Ljava/lang/Object;)Larrow/core/Validated; - public static final fun leftWiden (Larrow/core/Validated;)Larrow/core/Validated; - public static final fun merge (Larrow/core/Validated;)Ljava/lang/Object; - public static final fun orElse (Larrow/core/Validated;Lkotlin/jvm/functions/Function0;)Larrow/core/Validated; - public static final fun orNone (Larrow/core/Validated;)Larrow/core/Option; - public static final fun orNull (Larrow/core/Validated;)Ljava/lang/Object; - public static final fun redeem (Larrow/core/Validated;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public static final fun replicate (Larrow/core/Validated;Larrow/typeclasses/Semigroup;I)Larrow/core/Validated; - public static final fun replicate (Larrow/core/Validated;Larrow/typeclasses/Semigroup;ILarrow/typeclasses/Monoid;)Larrow/core/Validated; - public static final fun sequence (Larrow/core/Validated;)Larrow/core/Either; - public static final fun sequence (Larrow/core/Validated;)Larrow/core/Option; - public static final fun sequence (Larrow/core/Validated;)Larrow/core/Validated; - public static final fun sequence (Larrow/core/Validated;)Ljava/util/List; - public static final fun sequenceEither (Larrow/core/Validated;)Larrow/core/Either; - public static final fun sequenceNullable (Larrow/core/Validated;)Larrow/core/Validated; - public static final fun sequenceOption (Larrow/core/Validated;)Larrow/core/Option; - public static final fun toIor (Larrow/core/Validated;)Larrow/core/Ior; - public static final fun valid (Ljava/lang/Object;)Larrow/core/Validated; - public static final fun validNel (Ljava/lang/Object;)Larrow/core/Validated; - public static final fun valueOr (Larrow/core/Validated;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public static final fun widen (Larrow/core/Validated;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function10;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function9;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function8;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function7;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function6;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function5;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function4;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function3;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function2;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/core/Validated;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function10;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function9;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function8;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function7;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function6;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function5;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/core/Validated;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function4;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/core/Validated;Larrow/core/Validated;Lkotlin/jvm/functions/Function3;)Larrow/core/Validated; - public static final fun zip (Larrow/core/Validated;Larrow/typeclasses/Semigroup;Larrow/core/Validated;Lkotlin/jvm/functions/Function2;)Larrow/core/Validated; -} - public abstract interface class arrow/core/computations/EitherEffect : arrow/continuations/Effect { public abstract fun bind (Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public abstract fun bind (Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun bind (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class arrow/core/computations/EitherEffect$DefaultImpls { public static fun bind (Larrow/core/computations/EitherEffect;Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static fun bind (Larrow/core/computations/EitherEffect;Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/computations/EitherEffect;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun ensure (Larrow/core/computations/EitherEffect;ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } @@ -2521,7 +2266,6 @@ public abstract interface class arrow/core/computations/RestrictedEitherEffect : public final class arrow/core/computations/RestrictedEitherEffect$DefaultImpls { public static fun bind (Larrow/core/computations/RestrictedEitherEffect;Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static fun bind (Larrow/core/computations/RestrictedEitherEffect;Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/computations/RestrictedEitherEffect;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun ensure (Larrow/core/computations/RestrictedEitherEffect;ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } @@ -2553,10 +2297,14 @@ public final class arrow/core/computations/RestrictedOptionEffect$DefaultImpls { public final class arrow/core/computations/ResultEffect { public static final field INSTANCE Larrow/core/computations/ResultEffect; public final fun bind (Larrow/core/Either;)Ljava/lang/Object; - public final fun bind (Larrow/core/Validated;)Ljava/lang/Object; public final fun bind (Ljava/lang/Object;)Ljava/lang/Object; } +public final class arrow/core/computations/ResultEffect$result { + public static final field INSTANCE Larrow/core/computations/ResultEffect$result; + public final fun invoke-IoAF18A (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; +} + public final class arrow/core/computations/either { public static final field INSTANCE Larrow/core/computations/either; public final fun eager (Lkotlin/jvm/functions/Function2;)Larrow/core/Either; @@ -2581,16 +2329,10 @@ public final class arrow/core/computations/option { public final fun invoke (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } -public final class arrow/core/computations/result { - public static final field INSTANCE Larrow/core/computations/result; - public final fun invoke-IoAF18A (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; -} - public final class arrow/core/continuations/DefaultRaise : arrow/core/continuations/Raise { public fun ()V public fun bind (Larrow/core/Either;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public fun bind (Larrow/core/Validated;)Ljava/lang/Object; public fun bind (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2608,7 +2350,6 @@ public final class arrow/core/continuations/DefaultStateRaise : arrow/atomic/Ato public fun (Larrow/atomic/Atomic;Larrow/core/continuations/Raise;)V public fun bind (Larrow/core/Either;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public fun bind (Larrow/core/Validated;)Ljava/lang/Object; public fun bind (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2659,8 +2400,6 @@ public final class arrow/core/continuations/Effect { public static final fun toResult (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static final fun toResult (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun toResult (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static final fun toValidated (Lkotlin/jvm/functions/Function1;)Larrow/core/Validated; - public static final fun toValidated (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public abstract interface annotation class arrow/core/continuations/EffectDSL : java/lang/annotation/Annotation { @@ -2673,10 +2412,10 @@ public final class arrow/core/continuations/EffectKt { public final class arrow/core/continuations/IorRaise : arrow/core/continuations/Raise, arrow/typeclasses/Semigroup { public fun (Larrow/typeclasses/Semigroup;Larrow/core/continuations/StateRaise;)V + public fun append (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun bind (Larrow/core/Either;)Ljava/lang/Object; public final fun bind (Larrow/core/Ior;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public fun bind (Larrow/core/Validated;)Ljava/lang/Object; public fun bind (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2697,14 +2436,12 @@ public final class arrow/core/continuations/IorRaise : arrow/core/continuations/ public final class arrow/core/continuations/NullableRaise : arrow/core/continuations/Raise { public fun bind (Larrow/core/Either;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public fun bind (Larrow/core/Validated;)Ljava/lang/Object; public fun bind (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Larrow/core/Either;)Ljava/lang/Object; public static final fun bind-impl (Larrow/core/continuations/Raise;Larrow/core/Option;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public static fun bind-impl (Larrow/core/continuations/Raise;Larrow/core/Validated;)Ljava/lang/Object; public static final fun bind-impl (Larrow/core/continuations/Raise;Ljava/lang/Object;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; @@ -2743,14 +2480,12 @@ public final class arrow/core/continuations/NullableRaise : arrow/core/continuat public final class arrow/core/continuations/OptionRaise : arrow/core/continuations/Raise { public fun bind (Larrow/core/Either;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public fun bind (Larrow/core/Validated;)Ljava/lang/Object; public fun bind (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Larrow/core/Either;)Ljava/lang/Object; public static final fun bind-impl (Larrow/core/continuations/Raise;Larrow/core/Option;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public static fun bind-impl (Larrow/core/continuations/Raise;Larrow/core/Validated;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2788,7 +2523,6 @@ public final class arrow/core/continuations/OptionRaise : arrow/core/continuatio public abstract interface class arrow/core/continuations/Raise { public abstract fun bind (Larrow/core/Either;)Ljava/lang/Object; public abstract fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public abstract fun bind (Larrow/core/Validated;)Ljava/lang/Object; public abstract fun bind (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public abstract fun bind (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public abstract fun bind (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2805,7 +2539,6 @@ public abstract interface class arrow/core/continuations/Raise { public final class arrow/core/continuations/Raise$DefaultImpls { public static fun bind (Larrow/core/continuations/Raise;Larrow/core/Either;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/Raise;Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public static fun bind (Larrow/core/continuations/Raise;Larrow/core/Validated;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/Raise;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2829,13 +2562,11 @@ public final class arrow/core/continuations/RaiseKt { public final class arrow/core/continuations/ResultRaise : arrow/core/continuations/Raise { public fun bind (Larrow/core/Either;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public fun bind (Larrow/core/Validated;)Ljava/lang/Object; public fun bind (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun bind (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Larrow/core/Either;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public static fun bind-impl (Larrow/core/continuations/Raise;Larrow/core/Validated;)Ljava/lang/Object; public static final fun bind-impl (Larrow/core/continuations/Raise;Ljava/lang/Object;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; @@ -2875,7 +2606,6 @@ public abstract interface class arrow/core/continuations/StateRaise : arrow/atom public final class arrow/core/continuations/StateRaise$DefaultImpls { public static fun bind (Larrow/core/continuations/StateRaise;Larrow/core/Either;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/StateRaise;Larrow/core/Option;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public static fun bind (Larrow/core/continuations/StateRaise;Larrow/core/Validated;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/StateRaise;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/StateRaise;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/StateRaise;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2913,7 +2643,6 @@ public abstract interface class arrow/typeclasses/Monoid : arrow/typeclasses/Sem public static fun pair (Larrow/typeclasses/Monoid;Larrow/typeclasses/Monoid;)Larrow/typeclasses/Monoid; public static fun sequence ()Larrow/typeclasses/Monoid; public static fun string ()Larrow/typeclasses/Monoid; - public static fun validated (Larrow/typeclasses/Semigroup;Larrow/typeclasses/Monoid;)Larrow/typeclasses/Monoid; } public final class arrow/typeclasses/Monoid$Companion { @@ -2931,10 +2660,10 @@ public final class arrow/typeclasses/Monoid$Companion { public final fun pair (Larrow/typeclasses/Monoid;Larrow/typeclasses/Monoid;)Larrow/typeclasses/Monoid; public final fun sequence ()Larrow/typeclasses/Monoid; public final fun string ()Larrow/typeclasses/Monoid; - public final fun validated (Larrow/typeclasses/Semigroup;Larrow/typeclasses/Monoid;)Larrow/typeclasses/Monoid; } public final class arrow/typeclasses/Monoid$DefaultImpls { + public static fun combine (Larrow/typeclasses/Monoid;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public static fun combineAll (Larrow/typeclasses/Monoid;Ljava/util/Collection;)Ljava/lang/Object; public static fun combineAll (Larrow/typeclasses/Monoid;Ljava/util/List;)Ljava/lang/Object; public static fun fold (Larrow/typeclasses/Monoid;Ljava/util/Collection;)Ljava/lang/Object; @@ -2950,6 +2679,7 @@ public abstract interface class arrow/typeclasses/Semigroup { public static fun Integer ()Larrow/typeclasses/Semigroup; public static fun Long ()Larrow/typeclasses/Semigroup; public static fun Short ()Larrow/typeclasses/Semigroup; + public abstract fun append (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public abstract fun combine (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public static fun constant (Larrow/typeclasses/Semigroup;)Larrow/typeclasses/Semigroup; public static fun either (Larrow/typeclasses/Semigroup;Larrow/typeclasses/Semigroup;)Larrow/typeclasses/Semigroup; @@ -2964,7 +2694,6 @@ public abstract interface class arrow/typeclasses/Semigroup { public abstract fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public static fun sequence ()Larrow/typeclasses/Semigroup; public static fun string ()Larrow/typeclasses/Semigroup; - public static fun validated (Larrow/typeclasses/Semigroup;Larrow/typeclasses/Semigroup;)Larrow/typeclasses/Semigroup; } public final class arrow/typeclasses/Semigroup$Companion { @@ -2984,11 +2713,12 @@ public final class arrow/typeclasses/Semigroup$Companion { public final fun pair (Larrow/typeclasses/Semigroup;Larrow/typeclasses/Semigroup;)Larrow/typeclasses/Semigroup; public final fun sequence ()Larrow/typeclasses/Semigroup; public final fun string ()Larrow/typeclasses/Semigroup; - public final fun validated (Larrow/typeclasses/Semigroup;Larrow/typeclasses/Semigroup;)Larrow/typeclasses/Semigroup; } public final class arrow/typeclasses/Semigroup$Companion$NonEmptyListSemigroup : arrow/typeclasses/Semigroup { public static final field INSTANCE Larrow/typeclasses/Semigroup$Companion$NonEmptyListSemigroup; + public fun append (Larrow/core/NonEmptyList;Larrow/core/NonEmptyList;)Larrow/core/NonEmptyList; + public synthetic fun append (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun combine (Larrow/core/NonEmptyList;Larrow/core/NonEmptyList;)Larrow/core/NonEmptyList; public synthetic fun combine (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun maybeCombine (Larrow/core/NonEmptyList;Larrow/core/NonEmptyList;)Larrow/core/NonEmptyList; @@ -2998,6 +2728,7 @@ public final class arrow/typeclasses/Semigroup$Companion$NonEmptyListSemigroup : } public final class arrow/typeclasses/Semigroup$DefaultImpls { + public static fun combine (Larrow/typeclasses/Semigroup;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public static fun maybeCombine (Larrow/typeclasses/Semigroup;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public static fun plus (Larrow/typeclasses/Semigroup;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; } 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 da0d73775b6..628bd817272 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,16 +1,19 @@ +@file:JvmMultifileClass +@file:JvmName("EitherKt") package arrow.core import arrow.core.Either.Companion.resolve import arrow.core.Either.Left import arrow.core.Either.Right +import arrow.core.EmptyValue.combine as emptyCombine import arrow.core.continuations.Raise import arrow.core.continuations.either import arrow.typeclasses.Monoid import arrow.typeclasses.Semigroup import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract -import kotlin.experimental.ExperimentalTypeInference import kotlin.js.JsName +import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmName import kotlin.jvm.JvmStatic @@ -47,25 +50,6 @@ import kotlin.jvm.JvmStatic * * How then do we communicate an error? By making it explicit in the data type we return. * - * ## Either vs Validated - * - * In general, `Validated` is used to accumulate errors, while `Either` is used to short-circuit a computation - * upon the first error. For more information, see the `Validated` vs `Either` section of the `Validated` documentation. - * - * By convention, the right side of an `Either` is used to hold successful values. - * - * ```kotlin - * import arrow.core.Either - * - * val right: Either = - * //sampleStart - * Either.Right(5) - * //sampleEnd - * fun main() { - * println(right) - * } - * ``` - * * * ```kotlin * import arrow.core.Either @@ -78,7 +62,7 @@ import kotlin.jvm.JvmStatic * println(left) * } * ``` - * + * * * Because `Either` is right-biased, it is possible to define a Monad instance for it. * @@ -99,7 +83,7 @@ import kotlin.jvm.JvmStatic * println("value = $value") * } * ``` - * + * * * ```kotlin * import arrow.core.Either @@ -113,7 +97,7 @@ import kotlin.jvm.JvmStatic * println("value = $value") * } * ``` - * + * * * ## Using Either instead of exceptions * @@ -141,7 +125,7 @@ import kotlin.jvm.JvmStatic * fun stringify(d: Double): String = d.toString() * //sampleEnd * ``` - * + * * * Instead, let's make the fact that some of our functions can fail explicit in the return type. * @@ -167,7 +151,7 @@ import kotlin.jvm.JvmStatic * parse(s).flatMap { reciprocal(it) }.map { stringify(it) } * //sampleEnd * ``` - * + * * * These calls to `parse` return a [Left] and [Right] value * @@ -187,7 +171,7 @@ import kotlin.jvm.JvmStatic * println("number2 = $number2") * } * ``` - * + * * * Now, using combinators like `flatMap` and `map`, we can compose our functions together. * @@ -219,7 +203,7 @@ import kotlin.jvm.JvmStatic * println("magicNotANumber = $magicNotANumber") * } * ``` - * + * * * In the following exercise, we pattern-match on every case in which the `Either` returned by `magic` can be in. * Note the `when` clause in the [Left] - the compiler will complain if we leave that out because it knows that, @@ -260,7 +244,7 @@ import kotlin.jvm.JvmStatic * println("value = $value") * } * ``` - * + * * * Instead of using exceptions as our error value, let's instead enumerate explicitly the things that * can go wrong in our program. @@ -290,7 +274,7 @@ import kotlin.jvm.JvmStatic * parse(s).flatMap{reciprocal(it)}.map{ stringify(it) } * //sampleEnd * ``` - * + * * * For our little module, we enumerate any and all errors that can occur. Then, instead of using * exception classes as error values, we use one of the enumerated cases. Now, when we pattern match, @@ -333,7 +317,7 @@ import kotlin.jvm.JvmStatic * println("value = $value") * } * ``` - * + * * * ## Either.catch exceptions * @@ -358,7 +342,7 @@ import kotlin.jvm.JvmStatic * object SpecificError : Error() * } * ``` - * + * * * ## Resolve Either into one type of value * In some cases you can not use Either as a value. For instance, when you need to respond to an HTTP request. To resolve Either into one type of value, you can use the resolve function. @@ -448,7 +432,7 @@ import kotlin.jvm.JvmStatic * data class ErrorResponse(val errorMessage: String) * enum class Level { INFO, WARN, ERROR } * ``` - * + * * * There are far more use cases for the resolve function, the HTTP endpoint example is just one of them. * @@ -470,7 +454,7 @@ import kotlin.jvm.JvmStatic * println("leftMapLeft = $leftMapLeft") * } * ``` - * + * * * `Either` can be transformed to `Either` using the `swap()` method. * @@ -486,7 +470,7 @@ import kotlin.jvm.JvmStatic * println("swapped = $swapped") * } * ``` - * + * * * For using Either's syntax on arbitrary data types. * This will make possible to use the `left()`, `right()`, `contains()`, `getOrElse()` and `getOrHandle()` methods: @@ -502,7 +486,7 @@ import kotlin.jvm.JvmStatic * println(right7) * } * ``` - * + * * * ```kotlin * import arrow.core.left @@ -515,7 +499,7 @@ import kotlin.jvm.JvmStatic * println(leftHello) * } * ``` - * + * * * ```kotlin * import arrow.core.right @@ -529,7 +513,7 @@ import kotlin.jvm.JvmStatic * println("contains7 = $contains7") * } * ``` - * + * * * ```kotlin * import arrow.core.left @@ -543,7 +527,7 @@ import kotlin.jvm.JvmStatic * println("getOr7 = $getOr7") * } * ``` - * + * * * ```kotlin * import arrow.core.left @@ -557,7 +541,7 @@ import kotlin.jvm.JvmStatic * println("value = $value") * } * ``` - * + * * * For creating Either instance based on a predicate, use `Either.conditionally()` method. It will evaluate an expression * passed as first parameter, in case the expression evaluates to `false` it will give an `Either.Left` build from the second parameter. @@ -574,7 +558,7 @@ import kotlin.jvm.JvmStatic * println(value) * } * ``` - * + * * * ```kotlin * import arrow.core.Either @@ -587,7 +571,7 @@ import kotlin.jvm.JvmStatic * println(value) * } * ``` - * + * * * Another operation is `fold`. This operation will extract the value from the Either, or provide a default if the value is [Left] * @@ -603,7 +587,7 @@ import kotlin.jvm.JvmStatic * println("fold = $fold") * } * ``` - * + * * * ```kotlin * import arrow.core.Either @@ -617,7 +601,7 @@ import kotlin.jvm.JvmStatic * println("fold = $fold") * } * ``` - * + * * * The `getOrHandle()` operation allows the transformation of an `Either.Left` value to a `Either.Right` using * the value of [Left]. This can be useful when mapping to a single result type is required like `fold()`, but without @@ -642,7 +626,7 @@ import kotlin.jvm.JvmStatic * println("httpStatusCode = $httpStatusCode") * } * ``` - * + * * * The ```leftIfNull``` operation transforms a null `Either.Right` value to the specified ```Either.Left``` value. * If the value is non-null, the value wrapped into a non-nullable ```Either.Right``` is returned (very useful to @@ -663,7 +647,7 @@ import kotlin.jvm.JvmStatic * println(value) * } * ``` - * + * * * ```kotlin * import arrow.core.Either.Right @@ -677,7 +661,7 @@ import kotlin.jvm.JvmStatic * println(value) * } * ``` - * + * * * ```kotlin * import arrow.core.Either.Left @@ -691,7 +675,7 @@ import kotlin.jvm.JvmStatic * println(value) * } * ``` - * + * * * Another useful operation when working with null is `rightIfNotNull`. * If the value is null, it will be transformed to the specified `Either.Left` and, if it's not null, the type will @@ -710,7 +694,7 @@ import kotlin.jvm.JvmStatic * println(value) * } * ``` - * + * * * ```kotlin * import arrow.core.rightIfNotNull @@ -723,7 +707,7 @@ import kotlin.jvm.JvmStatic * println(value) * } * ``` - * + * * * The inverse of `rightIfNotNull`, `rightIfNull`. * If the value is null it will be transformed to the specified `Either.right` and the type will be `Nothing?`. @@ -742,7 +726,7 @@ import kotlin.jvm.JvmStatic * println(value) * } * ``` - * + * * * ```kotlin * import arrow.core.rightIfNull @@ -755,7 +739,7 @@ import kotlin.jvm.JvmStatic * println(value) * } * ``` - * + * * * Arrow contains `Either` instances for many useful typeclasses that allows you to use and transform right values. * Option does not require a type parameter with the following functions, but it is specifically used for Either.Left @@ -814,7 +798,7 @@ public sealed class Either { * .fold({ -1 }, { fail("Cannot be right") }) shouldBe -1 * } * ``` - * + * * * * @param ifLeft transform the [Either.Left] type [A] to [C]. @@ -867,7 +851,7 @@ public sealed class Either { * Either.Right("right").swap() shouldBe Either.Left("right") * } * ``` - * + * * */ public fun swap(): Either = @@ -885,7 +869,7 @@ public sealed class Either { * Either.Left(12).map { _: Nothing -> "flower" } shouldBe Either.Left(12) * } * ``` - * + * * */ public inline fun map(f: (right: B) -> C): Either = @@ -903,7 +887,7 @@ public sealed class Either { * Either.Left(12).mapLeft { _: Int -> "flower" } shouldBe Either.Left("flower") * } * ``` - * + * * */ public inline fun mapLeft(f: (A) -> C): Either = @@ -935,7 +919,7 @@ public sealed class Either { * Either.Right(1).onRight(::println) shouldBe Either.Right(1) * } * ``` - * + * * */ public inline fun onRight(action: (right: B) -> Unit): Either = @@ -953,7 +937,7 @@ public sealed class Either { * Either.Left(2).onLeft(::println) shouldBe Either.Left(2) * } * ``` - * + * * */ public inline fun onLeft(action: (left: A) -> Unit): Either = @@ -986,7 +970,7 @@ public sealed class Either { * left.exists { it > 10 } // Result: false * } * ``` - * + * */ @Deprecated( NicheAPI + "Prefer when or fold instead", @@ -1033,7 +1017,7 @@ public sealed class Either { * Either.Left(12).getOrNull() shouldBe null * } * ``` - * + * * */ public fun getOrNull(): B? = getOrElse { null } @@ -1056,7 +1040,7 @@ public sealed class Either { * Either.Left(12).getOrNone() shouldBe None * } * ``` - * + * * */ public fun getOrNone(): Option = fold({ None }, { Some(it) }) @@ -1066,81 +1050,12 @@ public sealed class Either { ReplaceWith("if (n <= 0) Right(emptyList()) else map { b -> List(n) { b } }") ) public fun replicate(n: Int): Either> = - if (n <= 0) Right(emptyList()) else map { b -> List(n) { b } } - - @Deprecated( - NicheAPI + "Prefer using the Either DSL, or explicit fold or when", - ReplaceWith("fold({ emptyList() }, { fa(it).map(::Right) })") - ) - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (B) -> Iterable): List> = - fold({ emptyList() }, { fa(it).map(::Right) }) - - @Deprecated( - NicheAPI + "Prefer using the Either DSL, or explicit fold or when", - ReplaceWith("fold({ None }, { right -> fa(right).map(::Right) })") - ) - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (B) -> Option): Option> = - fold({ None }, { right -> fa(right).map(::Right) }) - - @Deprecated("traverseOption is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(fa)")) - public inline fun traverseOption(fa: (B) -> Option): Option> = - traverse(fa) - - @Deprecated( - RedundantAPI + "Use orNull() and Kotlin nullable types", - ReplaceWith("orNull()?.let(fa)?.right()") - ) - public inline fun traverseNullable(fa: (B) -> C?): Either? = - getOrNull()?.let(fa)?.right() - - // TODO will be renamed to mapAccumulating in 2.x.x. Backport, and deprecate in 1.x.x - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (B) -> Validated): Validated> = - when (this) { - is Right -> fa(this.value).map(::Right) - is Left -> this.valid() + if (n <= 0) emptyList().right() + else when (this) { + is Left -> this + is Right -> List(n) { this.value }.right() } - @Deprecated("traverseValidated is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(fa)")) - public inline fun traverseValidated(fa: (B) -> Validated): Validated> = - traverse(fa) - - @Deprecated( - NicheAPI + "Prefer explicit fold instead", - ReplaceWith("fold({ fe(it).map { aa -> Left(aa) } }, { fa(it).map { c -> Right(c) } })") - ) - public inline fun bitraverse(fe: (A) -> Iterable, fa: (B) -> Iterable): List> = - fold({ fe(it).map { aa -> Left(aa) } }, { fa(it).map { c -> Right(c) } }) - - @Deprecated( - NicheAPI + "Prefer explicit fold instead", - ReplaceWith("fold({ fl(it).map(::Left) }, { fr(it).map(::Right) })") - ) - public inline fun bitraverseOption(fl: (A) -> Option, fr: (B) -> Option): Option> = - fold({ fl(it).map(::Left) }, { fr(it).map(::Right) }) - - @Deprecated( - NicheAPI + "Prefer explicit fold instead", - ReplaceWith("fold({ fl(it)?.let(::Left) }, { fr(it)?.let(::Right) })") - ) - public inline fun bitraverseNullable(fl: (A) -> AA?, fr: (B) -> C?): Either? = - fold({ fl(it)?.let(::Left) }, { fr(it)?.let(::Right) }) - - @Deprecated( - NicheAPI + "Prefer explicit fold instead", - ReplaceWith("fold({ fe(it).map { Left(it) } }, { fa(it).map { Right(it) } })") - ) - public inline fun bitraverseValidated( - fe: (A) -> Validated, - fa: (B) -> Validated, - ): Validated> = - fold({ fe(it).map { Left(it) } }, { fa(it).map { Right(it) } }) - @Deprecated( NicheAPI + "Prefer Kotlin nullable syntax instead", ReplaceWith("orNull()?.takeIf(predicate)") @@ -1161,7 +1076,7 @@ public sealed class Either { * Either.Right("foo").isEmpty() // Result: false * } * ``` - * + * */ @Deprecated( RedundantAPI + "Use `is Either.Left<*>`, `when`, or `fold` instead", @@ -1183,7 +1098,7 @@ public sealed class Either { * //sampleEnd * } * ``` - * + * */ @Deprecated( RedundantAPI + "Use `is Either.Right<*>`, `when`, or `fold` instead", @@ -1200,6 +1115,7 @@ public sealed class Either { ReplaceWith("(this is Either.Left<*>)") ) override val isLeft = true + @Deprecated( RedundantAPI + "Use `is Either.Right<*>`, `when`, or `fold` instead", ReplaceWith("(this is Either.Right<*>)") @@ -1224,6 +1140,7 @@ public sealed class Either { ReplaceWith("(this is Either.Left<*>)") ) override val isLeft = false + @Deprecated( RedundantAPI + "Use `is Either.Right<*>`, `when`, or `fold` instead", ReplaceWith("(this is Either.Right<*>)") @@ -1244,12 +1161,6 @@ public sealed class Either { { "Either.Right($it)" } ) - public fun toValidatedNel(): ValidatedNel = - fold({ Validated.invalidNel(it) }, ::Valid) - - public fun toValidated(): Validated = - fold({ it.invalid() }, { it.valid() }) - public companion object { @Deprecated( @@ -1331,9 +1242,9 @@ public sealed class Either { }.recover { t: Throwable -> throwable(t).bind() }.getOrElse { t: Throwable -> - unrecoverableState(t) - throw t - } + unrecoverableState(t) + throw t + } /** * Lifts a function `(B) -> C` to the [Either] structure returning a polymorphic function @@ -1351,7 +1262,7 @@ public sealed class Either { * println(result) * } * ``` - * + * */ @JvmStatic @Deprecated( @@ -1396,7 +1307,7 @@ public sealed class Either { * val b: Either = error.recover { error -> raise("other-failure") } // Either.Left(other-failure) * val c: Either = error.recover { error -> User } // Either.Right(User) * ``` - * + * */ public inline fun Either.recover(recover: Raise.(E) -> A): Either = when (this) { @@ -1434,7 +1345,7 @@ public fun Either>.flatten(): Either = * Left(12).getOrElse { 17 } // Result: 17 * } * ``` - * + * */ @Deprecated( RedundantAPI + "This API is overloaded with an API with a single argument", @@ -1456,7 +1367,7 @@ public inline fun Either<*, B>.getOrElse(default: () -> B): B = * Either.Left(12).getOrElse { it + 5 } shouldBe 17 * } * ``` - * + * * */ public inline fun Either.getOrElse(default: (A) -> B): B = @@ -1475,7 +1386,7 @@ public inline fun Either.getOrElse(default: (A) -> B): B = * Left(12).orNull() // Result: null * } * ``` - * + * */ @Deprecated( "Duplicated API. Please use Either's member function orNull. This will be removed towards Arrow 2.0", @@ -1498,7 +1409,7 @@ public fun Either<*, B>.orNull(): B? = * Left(12).getOrHandle { it + 5 } // Result: 17 * } * ``` - * + * */ @Deprecated( RedundantAPI + "Use other getOrElse signature", @@ -1530,7 +1441,7 @@ public inline fun Either.getOrHandle(default: (A) -> B): B = * left.filterOrElse({ it > 10 }, { -1 }) // Result: Left(12) * } * ``` - * + * */ @Deprecated( RedundantAPI + "Prefer if-else statement inside either DSL, or replace with explicit flatMap", @@ -1567,7 +1478,7 @@ public inline fun Either.filterOrElse(predicate: (B) -> Boolean, de * //sampleEnd * } * ``` - * + * */ @Deprecated( RedundantAPI + "Prefer if-else statement inside either DSL, or replace with explicit flatMap", @@ -1590,7 +1501,7 @@ public inline fun Either.filterOrOther(predicate: (B) -> Boolean, d * Left(12).merge() // Result: 12 * } * ``` - * + * * */ public inline fun Either.merge(): A = @@ -1616,7 +1527,7 @@ public inline fun Either.merge(): A = * Left(12).leftIfNull({ -1 }) // Result: Left(12) * } * ``` - * + * */ @Deprecated( RedundantAPI + "Prefer Kotlin nullable syntax inside either DSL, or replace with explicit flatMap", @@ -1677,7 +1588,7 @@ public fun A.right(): Either = Right(this) * null.rightIfNotNull { "left" } // Left(a="left") * } * ``` - * + * */ @Deprecated( RedundantAPI + "Prefer Kotlin nullable syntax", @@ -1750,7 +1661,7 @@ public fun Iterable>.combineAll(MA: Monoid, MB: Monoid fold(Monoid.either(MA, MB)) /** - * Given [B] is a sub type of [C], re-type this value from Either to Either + * Given [B] is a subtype of [C], re-type this value from Either to Either * * ```kotlin * import arrow.core.* @@ -1764,7 +1675,7 @@ public fun Iterable>.combineAll(MA: Monoid, MB: Monoid * println(chars) * } * ``` - * + * */ public fun Either.widen(): Either = this @@ -1772,98 +1683,6 @@ public fun Either.widen(): Either = public fun Either.leftWiden(): Either = this -// TODO this will be completely breaking from 1.x.x -> 2.x.x. Only _real_ solution is `inline fun either { }` -public fun Either.zip(fb: Either, f: (B, C) -> D): Either = - either { f(bind(), fb.bind()) } - -public fun Either.zip(fb: Either): Either> = - either { Pair(bind(), fb.bind()) } - -public inline fun Either.zip( - c: Either, - d: Either, - map: (B, C, D) -> E, -): Either = - either { map(bind(), c.bind(), d.bind()) } - -public inline fun Either.zip( - c: Either, - d: Either, - e: Either, - map: (B, C, D, E) -> F, -): Either = - either { map(bind(), c.bind(), d.bind(), e.bind()) } - -public inline fun Either.zip( - c: Either, - d: Either, - e: Either, - f: Either, - map: (B, C, D, E, F) -> G, -): Either = - either { map(bind(), c.bind(), d.bind(), e.bind(), f.bind()) } - -public inline fun Either.zip( - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - map: (B, C, D, E, F, G) -> H, -): Either = - either { map(bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind()) } - -public inline fun Either.zip( - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - h: Either, - map: (B, C, D, E, F, G, H) -> I, -): Either = - either { map(bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind()) } - -public inline fun Either.zip( - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - h: Either, - i: Either, - map: (B, C, D, E, F, G, H, I) -> J, -): Either = - either { map(bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind(), i.bind()) } - -public inline fun Either.zip( - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - h: Either, - i: Either, - j: Either, - map: (B, C, D, E, F, G, H, I, J) -> K, -): Either = - either { map(bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind(), i.bind(), j.bind()) } - -public inline fun Either.zip( - c: Either, - d: Either, - e: Either, - f: Either, - g: Either, - h: Either, - i: Either, - j: Either, - k: Either, - map: (B, C, D, E, F, G, H, I, J, K) -> L -): Either = either { - map(bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind(), i.bind(), j.bind(), k.bind()) -} - @Deprecated( NicheAPI + "Prefer using the Either DSL, or map", ReplaceWith("if (n <= 0) Right(MB.empty()) else map { b -> List(n) { b }.fold(MB) }") @@ -1885,80 +1704,6 @@ public inline fun Either.ensure(error: () -> A, predicate: (B) -> B public inline fun Either.redeemWith(fa: (A) -> Either, fb: (B) -> Either): Either = fold(fa, fb) -@Deprecated( - "Prefer Kotlin nullable syntax inside either DSL, or replace with explicit fold", - ReplaceWith( - "fold({ emptyList() }, { iterable -> iterable.map { it.right() } })", - "arrow.core.right", - ) -) -public fun Either>.sequence(): List> = - fold({ emptyList() }, { iterable -> iterable.map { it.right() } }) - -@Deprecated( - "Prefer Kotlin nullable syntax inside either DSL, or replace with explicit fold", - ReplaceWith( - "fold({ emptyList() }, { iterable -> iterable.map { it.right() } })", - "arrow.core.right", - ) -) -public fun Either>.sequenceOption(): Option> = - sequence() - -@Deprecated( - "Prefer Kotlin nullable syntax inside either DSL, or replace with explicit fold", - ReplaceWith( - "orNull()?.orNull()?.right().toOption()", - "arrow.core.toOption", - "arrow.core.right", - "arrow.core.left" - ) -) -public fun Either>.sequence(): Option> = - getOrNull()?.orNull()?.right().toOption() - -@Deprecated( - "Prefer Kotlin nullable syntax inside either DSL, or replace with explicit fold", - ReplaceWith( - "fold({ it.left() }, { it.orNull()?.right() }).toOption()", - "arrow.core.toOption", - "arrow.core.right", - "arrow.core.left" - ) -) -public fun Either.sequenceNullable(): Either? = - sequence() - -@Deprecated( - "Prefer Kotlin nullable syntax", - ReplaceWith("orNull()?.right()", "arrow.core.right") -) -public fun Either.sequence(): Either? = - getOrNull()?.right() - -@Deprecated( - "sequenceValidated is being renamed to sequence to simplify the Arrow API", - ReplaceWith("sequence()", "arrow.core.sequence") -) -public fun Either>.sequenceValidated(): Validated> = - sequence() - -// TODO deprecate for mapAccumulating after back-port. -public fun Either>.sequence(): Validated> = - traverse(::identity) - -public fun Either, Iterable>.bisequence(): List> = - bitraverse(::identity, ::identity) - -public fun Either, Option>.bisequenceOption(): Option> = - bitraverseOption(::identity, ::identity) - -public fun Either.bisequenceNullable(): Either? = - bitraverseNullable(::identity, ::identity) - -public fun Either, Validated>.bisequenceValidated(): Validated> = - bitraverseValidated(::identity, ::identity) - public const val NicheAPI: String = "This API is niche and will be removed in the future. If this method is crucial for you, please let us know on the Arrow Github. Thanks!\n https://github.com/arrow-kt/arrow/issues\n" diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/EitherZip.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/EitherZip.kt new file mode 100644 index 00000000000..a9770ae8217 --- /dev/null +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/EitherZip.kt @@ -0,0 +1,382 @@ +@file:JvmMultifileClass +@file:JvmName("EitherKt") +package arrow.core + +import arrow.typeclasses.Semigroup +import kotlin.jvm.JvmMultifileClass +import kotlin.jvm.JvmName + +@PublishedApi +internal val unit: Either = Either.Right(Unit) + +public inline fun Either.zip( + combine: Semigroup, + b: Either, + transform: (A, B) -> Z, +): Either = zip(combine, b, unit, unit, unit, unit, unit, unit, unit, unit) { a, bb, _, _, _, _, _, _, _, _ -> + transform(a, bb) +} + +public inline fun Either.zip( + combine: Semigroup, + b: Either, + c: Either, + transform: (A, B, C) -> Z, +): Either = zip(combine, b, c, unit, unit, unit, unit, unit, unit, unit) { a, bb, cc, _, _, _, _, _, _, _ -> + transform(a, bb, cc) +} + +public inline fun Either.zip( + combine: Semigroup, + b: Either, + c: Either, + d: Either, + transform: (A, B, C, D) -> Z, +): Either = zip(combine, b, c, d, unit, unit, unit, unit, unit, unit) { a, bb, cc, dd, _, _, _, _, _, _ -> + transform(a, bb, cc, dd) +} + +public inline fun Either.zip( + combine: Semigroup, + b: Either, + c: Either, + d: Either, + e: Either, + transform: (A, B, C, D, EE) -> Z, +): Either = zip(combine, b, c, d, e, unit, unit, unit, unit, unit) { a, bb, cc, dd, ee, _, _, _, _, _ -> + transform(a, bb, cc, dd, ee) +} + +public inline fun Either.zip( + combine: Semigroup, + b: Either, + c: Either, + d: Either, + e: Either, + f: Either, + transform: (A, B, C, D, EE, FF) -> Z, +): Either = zip(combine, b, c, d, e, f, unit, unit, unit, unit) { a, bb, cc, dd, ee, ff, _, _, _, _ -> + transform(a, bb, cc, dd, ee, ff) +} + +public inline fun Either.zip( + combine: Semigroup, + b: Either, + c: Either, + d: Either, + e: Either, + f: Either, + g: Either, + transform: (A, B, C, D, EE, F, G) -> Z, +): Either = zip(combine, b, c, d, e, f, g, unit, unit, unit) { a, bb, cc, dd, ee, ff, gg, _, _, _ -> + transform(a, bb, cc, dd, ee, ff, gg) +} + +public inline fun Either.zip( + combine: Semigroup, + 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 = zip(combine, b, c, d, e, f, g, h, unit, unit) { a, bb, cc, dd, ee, ff, gg, hh, _, _ -> + transform(a, bb, cc, dd, ee, ff, gg, hh) +} + +public inline fun Either.zip( + combine: Semigroup, + 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 = zip(combine, b, c, d, e, f, g, h, i, unit) { a, bb, cc, dd, ee, ff, gg, hh, ii, _ -> + transform(a, bb, cc, dd, ee, ff, gg, hh, ii) +} + +@Suppress("DuplicatedCode") +public inline fun Either.zip( + combine: Semigroup, + 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 = + if (this is Either.Right && b is Either.Right && c is Either.Right && d is Either.Right && e is Either.Right && f is Either.Right && g is Either.Right && h is Either.Right && i is Either.Right && j is Either.Right) { + Either.Right(transform(this.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 (this@zip is Either.Left) this@zip.value else accumulatedError + accumulatedError = if (b is Either.Left) EmptyValue.combine(accumulatedError, b.value, combine) else accumulatedError + accumulatedError = if (c is Either.Left) EmptyValue.combine(accumulatedError, c.value, combine) else accumulatedError + accumulatedError = if (d is Either.Left) EmptyValue.combine(accumulatedError, d.value, combine) else accumulatedError + accumulatedError = if (e is Either.Left) EmptyValue.combine(accumulatedError, e.value, combine) else accumulatedError + accumulatedError = if (f is Either.Left) EmptyValue.combine(accumulatedError, f.value, combine) else accumulatedError + accumulatedError = if (g is Either.Left) EmptyValue.combine(accumulatedError, g.value, combine) else accumulatedError + accumulatedError = if (h is Either.Left) EmptyValue.combine(accumulatedError, h.value, combine) else accumulatedError + accumulatedError = if (i is Either.Left) EmptyValue.combine(accumulatedError, i.value, combine) else accumulatedError + accumulatedError = if (j is Either.Left) EmptyValue.combine(accumulatedError, j.value, combine) else accumulatedError + + @Suppress("UNCHECKED_CAST") + (Either.Left(accumulatedError as E)) + } + +public inline fun Either.zip( + b: Either, + transform: (A, B) -> Z, +): Either, Z> = zip(b, unit, unit, unit, unit, unit, unit, unit, unit) { a, bb, _, _, _, _, _, _, _, _ -> + transform(a, bb) +} + +public inline fun Either.zip( + b: Either, + c: Either, + transform: (A, B, C) -> Z, +): Either, Z> = zip(b, c, unit, unit, unit, unit, unit, unit, unit) { a, bb, cc, _, _, _, _, _, _, _ -> + transform(a, bb, cc) +} + +public inline fun Either.zip( + b: Either, + c: Either, + d: Either, + transform: (A, B, C, D) -> Z, +): Either, Z> = zip(b, c, d, unit, unit, unit, unit, unit, unit) { a, bb, cc, dd, _, _, _, _, _, _ -> + transform(a, bb, cc, dd) +} + +public inline fun Either.zip( + b: Either, + c: Either, + d: Either, + e: Either, + transform: (A, B, C, D, EE) -> Z, +): Either, Z> = zip(b, c, d, e, unit, unit, unit, unit, unit) { a, bb, cc, dd, ee, _, _, _, _, _ -> + transform(a, bb, cc, dd, ee) +} + +public inline fun Either.zip( + b: Either, + c: Either, + d: Either, + e: Either, + f: Either, + transform: (A, B, C, D, EE, FF) -> Z, +): Either, Z> = zip(b, c, d, e, f, unit, unit, unit, unit) { a, bb, cc, dd, ee, ff, _, _, _, _ -> + transform(a, bb, cc, dd, ee, ff) +} + +public inline fun Either.zip( + b: Either, + c: Either, + d: Either, + e: Either, + f: Either, + g: Either, + transform: (A, B, C, D, EE, F, G) -> Z, +): Either, Z> = zip(b, c, d, e, f, g, unit, unit, unit) { a, bb, cc, dd, ee, ff, gg, _, _, _ -> + transform(a, bb, cc, dd, ee, ff, gg) +} + +public inline fun Either.zip( + 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> = zip(b, c, d, e, f, g, h, unit, unit) { a, bb, cc, dd, ee, ff, gg, hh, _, _ -> + transform(a, bb, cc, dd, ee, ff, gg, hh) +} + +public inline fun Either.zip( + 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> = zip(b, c, d, e, f, g, h, i, unit) { a, bb, cc, dd, ee, ff, gg, hh, ii, _ -> + transform(a, bb, cc, dd, ee, ff, gg, hh, ii) +} + +@Suppress("DuplicatedCode") +public inline fun Either.zip( + 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> = + if (this is Either.Right && b is Either.Right && c is Either.Right && d is Either.Right && e is Either.Right && f is Either.Right && g is Either.Right && h is Either.Right && i is Either.Right && j is Either.Right) { + Either.Right(transform(this.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 (this@zip is Either.Left) add(this@zip.value) + if (b is Either.Left) add(b.value) + if (c is Either.Left) add(c.value) + if (d is Either.Left) add(d.value) + if (e is Either.Left) add(e.value) + if (f is Either.Left) add(f.value) + if (g is Either.Left) add(g.value) + if (h is Either.Left) add(h.value) + if (i is Either.Left) add(i.value) + if (j is Either.Left) add(j.value) + } + Either.Left(NonEmptyList(list[0], list.drop(1))) + } + +public typealias EitherNel = Either, A> + +public fun Either.toEitherNel(): EitherNel = + mapLeft { nonEmptyListOf(it) } + +public fun E.toEitherNel(): EitherNel = + nonEmptyListOf(this).left() + +@JvmName("zipNonEmptyList") +public inline fun EitherNel.zip( + b: EitherNel, + transform: (A, B) -> Z, +): EitherNel = zip(b, unit, unit, unit, unit, unit, unit, unit, unit) { a, bb, _, _, _, _, _, _, _, _ -> + transform(a, bb) +} + +@JvmName("zipNonEmptyList") +public inline fun EitherNel.zip( + b: EitherNel, + c: EitherNel, + transform: (A, B, C) -> Z, +): EitherNel = zip(b, c, unit, unit, unit, unit, unit, unit, unit) { a, bb, cc, _, _, _, _, _, _, _ -> + transform(a, bb, cc) +} + +@JvmName("zipNonEmptyList") +public inline fun EitherNel.zip( + b: EitherNel, + c: EitherNel, + d: EitherNel, + transform: (A, B, C, D) -> Z, +): EitherNel = zip(b, c, d, unit, unit, unit, unit, unit, unit) { a, bb, cc, dd, _, _, _, _, _, _ -> + transform(a, bb, cc, dd) +} + +@JvmName("zipNonEmptyList") +public inline fun EitherNel.zip( + b: EitherNel, + c: EitherNel, + d: EitherNel, + e: EitherNel, + transform: (A, B, C, D, EE) -> Z, +): EitherNel = zip(b, c, d, e, unit, unit, unit, unit, unit) { a, bb, cc, dd, ee, _, _, _, _, _ -> + transform(a, bb, cc, dd, ee) +} + +@JvmName("zipNonEmptyList") +public inline fun EitherNel.zip( + b: EitherNel, + c: EitherNel, + d: EitherNel, + e: EitherNel, + f: EitherNel, + transform: (A, B, C, D, EE, FF) -> Z, +): EitherNel = zip(b, c, d, e, f, unit, unit, unit, unit) { a, bb, cc, dd, ee, ff, _, _, _, _ -> + transform(a, bb, cc, dd, ee, ff) +} + +@JvmName("zipNonEmptyList") +public inline fun EitherNel.zip( + b: EitherNel, + c: EitherNel, + d: EitherNel, + e: EitherNel, + f: EitherNel, + g: EitherNel, + transform: (A, B, C, D, EE, F, G) -> Z, +): EitherNel = zip(b, c, d, e, f, g, unit, unit, unit) { a, bb, cc, dd, ee, ff, gg, _, _, _ -> + transform(a, bb, cc, dd, ee, ff, gg) +} + +@JvmName("zipNonEmptyList") +public inline fun EitherNel.zip( + 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 = zip(b, c, d, e, f, g, h, unit, unit) { a, bb, cc, dd, ee, ff, gg, hh, _, _ -> + transform(a, bb, cc, dd, ee, ff, gg, hh) +} + +@JvmName("zipNonEmptyList") +public inline fun EitherNel.zip( + 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 = zip(b, c, d, e, f, g, h, i, unit) { a, bb, cc, dd, ee, ff, gg, hh, ii, _ -> + transform(a, bb, cc, dd, ee, ff, gg, hh, ii) +} + +@Suppress("DuplicatedCode") +@JvmName("zipNonEmptyList") +public inline fun EitherNel.zip( + 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 = + if (this is Either.Right && b is Either.Right && c is Either.Right && d is Either.Right && e is Either.Right && f is Either.Right && g is Either.Right && h is Either.Right && i is Either.Right && j is Either.Right) { + Either.Right(transform(this.value, b.value, c.value, d.value, e.value, f.value, g.value, h.value, i.value, j.value)) + } else { + val list = buildList { + if (this@zip is Either.Left) addAll(this@zip.value) + if (b is Either.Left) addAll(b.value) + if (c is Either.Left) addAll(c.value) + if (d is Either.Left) addAll(d.value) + if (e is Either.Left) addAll(e.value) + if (f is Either.Left) addAll(f.value) + if (g is Either.Left) addAll(g.value) + if (h is Either.Left) addAll(h.value) + if (i is Either.Left) addAll(i.value) + if (j is Either.Left) addAll(j.value) + } + Either.Left(NonEmptyList(list[0], list.drop(1))) + } diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Ior.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Ior.kt index 9983e985121..233292c80aa 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Ior.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Ior.kt @@ -1,11 +1,9 @@ package arrow.core -import arrow.core.Ior.Both -import arrow.core.Ior.Left -import arrow.core.Ior.Right +import arrow.core.Ior.* +import arrow.core.Ior.Right.Companion.unit import arrow.typeclasses.Monoid import arrow.typeclasses.Semigroup -import kotlin.experimental.ExperimentalTypeInference import kotlin.jvm.JvmStatic public typealias IorNel = Ior, B> @@ -30,7 +28,7 @@ public typealias IorNel = Ior, B> * The isomorphic Either form can be accessed via the [unwrap] method. */ public sealed class Ior { - + /** * Returns `true` if this is a [Right], `false` otherwise. * @@ -48,7 +46,7 @@ public sealed class Ior { * */ public abstract val isRight: Boolean - + /** * Returns `true` if this is a [Left], `false` otherwise. * @@ -63,10 +61,10 @@ public sealed class Ior { * Ior.Both("venus", "fly-trap").isLeft // Result: false * } * ``` - * + * */ public abstract val isLeft: Boolean - + /** * Returns `true` if this is a [Both], `false` otherwise. * @@ -80,10 +78,10 @@ public sealed class Ior { * Ior.Both("venus", "fly-trap").isBoth // Result: true * } * ``` - * + * */ public abstract val isBoth: Boolean - + public companion object { /** * Create an [Ior] from two nullables if at least one of them is defined. @@ -101,18 +99,19 @@ public sealed class Ior { true -> Both(a, b) false -> Left(a) } + false -> when (b != null) { true -> Right(b) false -> null } } - + @JvmStatic public fun leftNel(a: A): IorNel = Left(nonEmptyListOf(a)) - + @JvmStatic public fun bothNel(a: A, b: B): IorNel = Both(nonEmptyListOf(a), b) - + /** * Lifts a function `(B) -> C` to the [Ior] structure returning a polymorphic function * that can be applied over all [Ior] values in the shape of Ior @@ -133,12 +132,12 @@ public sealed class Ior { @JvmStatic public fun lift(f: (B) -> C): (Ior) -> Ior = { it.map(f) } - + @JvmStatic public fun lift(fa: (A) -> C, fb: (B) -> D): (Ior) -> Ior = { it.bimap(fa, fb) } } - + /** * Applies `fa` if this is a [Left], `fb` if this is a [Right] or `fab` if this is a [Both] * @@ -153,21 +152,21 @@ public sealed class Ior { is Right -> fb(value) is Both -> fab(leftValue, rightValue) } - + public inline fun foldLeft(c: C, f: (C, B) -> C): C = fold({ c }, { f(c, it) }, { _, b -> f(c, b) }) - + public inline fun foldMap(MN: Monoid, f: (B) -> C): C = MN.run { foldLeft(MN.empty()) { b, a -> b.combine(f(a)) } } - + public inline fun bifoldLeft(c: C, f: (C, A) -> C, g: (C, B) -> C): C = fold({ f(c, it) }, { g(c, it) }, { a, b -> g(f(c, a), b) }) - + public inline fun bifoldMap(MN: Monoid, f: (A) -> C, g: (B) -> C): C = MN.run { bifoldLeft(MN.empty(), { c, a -> c.combine(f(a)) }, { c, b -> c.combine(g(b)) }) } - + /** * The given function is applied if this is a [Right] or [Both] to `B`. * @@ -181,7 +180,7 @@ public sealed class Ior { * Ior.Both(12, "power").map { "flower $it" } // Result: Both(12, "flower power") * } * ``` - * + * */ public inline fun map(f: (B) -> D): Ior = when (this) { @@ -189,7 +188,7 @@ public sealed class Ior { is Right -> Right(f(value)) is Both -> Both(leftValue, f(rightValue)) } - + /** * Apply `fa` if this is a [Left] or [Both] to `A` * and apply `fb` if this is [Right] or [Both] to `B` @@ -204,14 +203,14 @@ public sealed class Ior { * Ior.Both(12, "power").bimap ({ it * 2 }, { b -> "flower $b" }) // Result: Both("flower power", 24) * } * ``` - * + * */ public inline fun bimap(fa: (A) -> C, fb: (B) -> D): Ior = fold( { Left(fa(it)) }, { Right(fb(it)) }, { a, b -> Both(fa(a), fb(b)) } ) - + /** * The given function is applied if this is a [Left] or [Both] to `A`. * @@ -232,7 +231,7 @@ public sealed class Ior { ::Right, { a, b -> Both(fa(a), b) } ) - + /** * If this is a [Left], then return the left value in [Right] or vice versa, * when this is [Both] , left and right values are swap @@ -247,14 +246,14 @@ public sealed class Ior { * Ior.Both("left", "right").swap() // Result: Both("right", "left") * } * ``` - * + * */ public fun swap(): Ior = fold( { Right(it) }, { Left(it) }, { a, b -> Both(b, a) } ) - + /** * Return the isomorphic [Either] of this [Ior] */ @@ -263,7 +262,7 @@ public sealed class Ior { { Either.Left(Either.Right(it)) }, { a, b -> Either.Right(Pair(a, b)) } ) - + /** * Return this [Ior] as [Pair] of nullables] * @@ -281,14 +280,14 @@ public sealed class Ior { * println("both = $both") * } * ``` - * + * */ public fun padNull(): Pair = fold( { Pair(it, null) }, { Pair(null, it) }, { a, b -> Pair(a, b) } ) - + /** * Returns a [Either.Right] containing the [Right] value or `B` if this is [Right] or [Both] * and [Either.Left] if this is a [Left]. @@ -303,11 +302,11 @@ public sealed class Ior { * Ior.Both("power", 12).toEither() // Result: Either.Right(12) * } * ``` - * + * */ public fun toEither(): Either = fold({ Either.Left(it) }, { Either.Right(it) }, { _, b -> Either.Right(b) }) - + /** * Returns the [Right] value or `B` if this is [Right] or [Both] * and [null] if this is a [Left]. @@ -326,11 +325,11 @@ public sealed class Ior { * println("both = $both") * } * ``` - * + * */ public fun orNull(): B? = fold({ null }, { it }, { _, b -> b }) - + /** * Returns the [Left] value or `A` if this is [Left] or [Both] * and [null] if this is a [Right]. @@ -348,170 +347,103 @@ public sealed class Ior { * println("both = $both") * } * ``` - * + * */ public fun leftOrNull(): A? = fold({ it }, { null }, { a, _ -> a }) - - /** - * Returns a [Validated.Valid] containing the [Right] value or `B` if this is [Right] or [Both] - * and [Validated.Invalid] if this is a [Left]. - * - * Example: - * ```kotlin - * import arrow.core.Ior - * - * fun main() { - * Ior.Right(12).toValidated() // Result: Valid(12) - * Ior.Left(12).toValidated() // Result: Invalid(12) - * Ior.Both(12, "power").toValidated() // Result: Valid("power") - * } - * ``` - * - */ - public fun toValidated(): Validated = - fold({ Invalid(it) }, { Valid(it) }, { _, b -> Valid(b) }) - + public data class Left(val value: A) : Ior() { override val isRight: Boolean get() = false override val isLeft: Boolean get() = true override val isBoth: Boolean get() = false - + override fun toString(): String = "Ior.Left($value)" - + public companion object } - + public data class Right(val value: B) : Ior() { override val isRight: Boolean get() = true override val isLeft: Boolean get() = false override val isBoth: Boolean get() = false - + override fun toString(): String = "Ior.Right($value)" - + public companion object { @PublishedApi internal val unit: Ior = Right(Unit) } } - + public data class Both(val leftValue: A, val rightValue: B) : Ior() { override val isRight: Boolean get() = false override val isLeft: Boolean get() = false override val isBoth: Boolean get() = true - + override fun toString(): String = "Ior.Both($leftValue, $rightValue)" } - + override fun toString(): String = fold( { "Ior.Left($it" }, { "Ior.Right($it)" }, { a, b -> "Ior.Both($a, $b)" } ) - + public inline fun bicrosswalk( fa: (A) -> Iterable, - fb: (B) -> Iterable + fb: (B) -> Iterable, ): List> = fold( { a -> fa(a).map { it.leftIor() } }, { b -> fb(b).map { it.rightIor() } }, { a, b -> fa(a).align(fb(b)) } ) - + public inline fun bicrosswalkMap( fa: (A) -> Map, - fb: (B) -> Map + fb: (B) -> Map, ): Map> = fold( { a -> fa(a).mapValues { it.value.leftIor() } }, { b -> fb(b).mapValues { it.value.rightIor() } }, { a, b -> fa(a).align(fb(b)) } ) - + public inline fun bicrosswalkNull( fa: (A) -> C?, - fb: (B) -> D? + fb: (B) -> D?, ): Ior? = fold( { a -> fa(a)?.let { Left(it) } }, { b -> fb(b)?.let { Right(it) } }, { a, b -> fromNullables(fa(a), fb(b)) } ) - - public inline fun bitraverse(fa: (A) -> Iterable, fb: (B) -> Iterable): List> = - fold( - { a -> fa(a).map { Left(it) } }, - { b -> fb(b).map { Right(it) } }, - { a, b -> fa(a).zip(fb(b)) { aa, c -> Both(aa, c) } } - ) - - public inline fun bitraverseEither( - fa: (A) -> Either, - fb: (B) -> Either - ): Either> = - fold( - { a -> fa(a).map { Left(it) } }, - { b -> fb(b).map { Right(it) } }, - { a, b -> fa(a).zip(fb(b)) { aa, c -> Both(aa, c) } } - ) - - public inline fun bitraverseOption( - fa: (A) -> Option, - fb: (B) -> Option - ): Option> = - fold( - { fa(it).map { Left(it) } }, - { fb(it).map { Right(it) } }, - { a, b -> fa(a).zip(fb(b)) { aa, c -> Both(aa, c) } } - ) - - public inline fun bitraverseNullable( - fa: (A) -> C?, - fb: (B) -> D? - ): Ior? = - fold( - { a -> fa(a)?.let { Left(it) } }, - { b -> fb(b)?.let { Right(it) } }, - { a, b -> Nullable.zip(fa(a), fb(b)) { aa, c -> Both(aa, c) } } - ) - - public inline fun bitraverseValidated( - SA: Semigroup, - fa: (A) -> Validated, - fb: (B) -> Validated - ): Validated> = - fold( - { a -> fa(a).map { Left(it) } }, - { b -> fb(b).map { Right(it) } }, - { a, b -> fa(a).zip(SA, fb(b)) { aa, c -> Both(aa, c) } } - ) - + public inline fun crosswalk(fa: (B) -> Iterable): List> = fold( { emptyList() }, { b -> fa(b).map { Right(it) } }, { a, b -> fa(b).map { Both(a, it) } } ) - + public inline fun crosswalkMap(fa: (B) -> Map): Map> = fold( { emptyMap() }, { b -> fa(b).mapValues { Right(it.value) } }, { a, b -> fa(b).mapValues { Both(a, it.value) } } ) - + public inline fun crosswalkNull(ior: Ior, fa: (B) -> C?): Ior? = ior.fold( { a -> Left(a) }, { b -> fa(b)?.let { Right(it) } }, { a, b -> fa(b)?.let { Both(a, it) } } ) - + public inline fun all(predicate: (B) -> Boolean): Boolean = fold({ true }, predicate, { _, b -> predicate(b) }) - + /** * Returns `false` if [Left] or returns the result of the application of * the given predicate to the [Right] value. @@ -528,77 +460,22 @@ public sealed class Ior { * left.exists { it > 10 } // Result: false * } * ``` - * + * */ public inline fun exists(predicate: (B) -> Boolean): Boolean = fold({ false }, predicate, { _, b -> predicate(b) }) - + public inline fun findOrNull(predicate: (B) -> Boolean): B? = when (this) { is Left -> null is Right -> if (predicate(this.value)) this.value else null is Both -> if (predicate(this.rightValue)) this.rightValue else null } - + public fun isEmpty(): Boolean = isLeft - + public fun isNotEmpty(): Boolean = !isLeft - - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (B) -> Iterable): List> = - fold( - { a -> listOf(Left(a)) }, - { b -> fa(b).map { Right(it) } }, - { a, b -> fa(b).map { Both(a, it) } } - ) - - @Deprecated("traverseEither is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(fa)")) - public inline fun traverseEither(fa: (B) -> Either): Either> = - traverse(fa) - - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (B) -> Either): Either> = - fold( - { a -> Either.Right(Left(a)) }, - { b -> fa(b).map { Right(it) } }, - { a, b -> fa(b).map { Both(a, it) } } - ) - - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (B) -> Option): Option> = - fold( - { a -> Some(Left(a)) }, - { b -> fa(b).map { Right(it) } }, - { a, b -> fa(b).map { Both(a, it) } } - ) - - @Deprecated("traverseOption is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(fa)")) - public inline fun traverseOption(fa: (B) -> Option): Option> = - traverse(fa) - - public inline fun traverseNullable(fa: (B) -> C?): Ior? = - fold( - { a -> Left(a) }, - { b -> fa(b)?.let { Right(it) } }, - { a, b -> fa(b)?.let { Both(a, it) } } - ) - - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (B) -> Validated): Validated> = - fold( - { a -> Valid(Left(a)) }, - { b -> fa(b).map { Right(it) } }, - { a, b -> fa(b).map { Both(a, it) } } - ) - - @Deprecated("traverseValidated is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(fa)")) - public inline fun traverseValidated(fa: (B) -> Validated): Validated> = - traverse(fa) - + public fun void(): Ior = map { Unit } } @@ -630,21 +507,6 @@ public fun A.leftIor(): Ior = Ior.Left(this) public fun A.rightIor(): Ior = Ior.Right(this) -public fun Ior, Iterable>.bisequence(): List> = - bitraverse(::identity, ::identity) - -public fun Ior, Either>.bisequenceEither(): Either> = - bitraverseEither(::identity, ::identity) - -public fun Ior, Option>.bisequenceOption(): Option> = - bitraverseOption(::identity, ::identity) - -public fun Ior.bisequenceNullable(): Ior? = - bitraverseNullable(::identity, ::identity) - -public fun Ior, Validated>.bisequenceValidated(SA: Semigroup): Validated> = - bitraverseValidated(SA, ::identity, ::identity) - public fun Ior.combine(SA: Semigroup, SB: Semigroup, other: Ior): Ior = with(SA) { with(SB) { @@ -654,11 +516,13 @@ public fun Ior.combine(SA: Semigroup, SB: Semigroup, other: I is Ior.Right -> Ior.Both(a.value, other.value) is Ior.Both -> Ior.Both(a.value + other.leftValue, other.rightValue) } + is Ior.Right -> when (other) { is Ior.Left -> Ior.Both(other.value, a.value) is Ior.Right -> Ior.Right(a.value + other.value) is Ior.Both -> Ior.Both(other.leftValue, a.value + other.rightValue) } + is Ior.Both -> when (other) { is Ior.Left -> Ior.Both(a.leftValue + other.value, a.rightValue) is Ior.Right -> Ior.Both(a.leftValue, a.rightValue + other.value) @@ -694,37 +558,6 @@ public fun Ior.replicate(SA: Semigroup, n: Int, MB: Monoid): ) } -public fun Ior>.sequence(): List> = - traverse(::identity) - -@Deprecated("sequenceEither is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Ior>.sequenceEither(): Either> = - sequence() - -public fun Ior>.sequence(): Either> = - traverse(::identity) - -@Deprecated("sequenceOption is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Ior>.sequenceOption(): Option> = - sequence() - -public fun Ior>.sequence(): Option> = - traverse(::identity) - -@Deprecated("sequenceOption is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Ior.sequenceNullable(): Ior? = - sequence() - -public fun Ior.sequence(): Ior? = - traverseNullable(::identity) - -@Deprecated("sequenceValidated is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Ior>.sequenceValidated(): Validated> = - sequence() - -public fun Ior>.sequence(): Validated> = - traverse(::identity) - /** * Given [B] is a sub type of [C], re-type this value from Ior to Ior * @@ -740,7 +573,7 @@ public fun Ior>.sequence(): Validated> * println(chars) * } * ``` - * + * */ public fun Ior.widen(): Ior = this @@ -754,26 +587,28 @@ public fun Ior.zip(SA: Semigroup, fb: Ior): Ior Ior.zip( SA: Semigroup, c: Ior, - map: (B, C) -> D + map: (B, C) -> D, ): Ior = - zip(SA, c, Right.unit, Right.unit, Right.unit, Right.unit, Right.unit, Right.unit, Right.unit, Right.unit) { b, c, _, _, _, _, _, _, _, _ -> map(b, c) } + zip(SA, c, unit, unit, unit, unit, unit, unit, unit, unit) { b, c, _, _, _, _, _, _, _, _ -> + map(b, c) + } public inline fun Ior.zip( SA: Semigroup, c: Ior, d: Ior, - map: (B, C, D) -> E + map: (B, C, D) -> E, ): Ior = - zip(SA, c, d, Right.unit, Right.unit, Right.unit, Right.unit, Right.unit, Right.unit, Right.unit) { b, c, d, _, _, _, _, _, _, _ -> map(b, c, d) } + zip(SA, c, d, unit, unit, unit, unit, unit, unit, unit) { b, c, d, _, _, _, _, _, _, _ -> map(b, c, d) } public inline fun Ior.zip( SA: Semigroup, c: Ior, d: Ior, e: Ior, - map: (B, C, D, E) -> F + map: (B, C, D, E) -> F, ): Ior = - zip(SA, c, d, e, Right.unit, Right.unit, Right.unit, Right.unit, Right.unit, Right.unit) { b, c, d, e, _, _, _, _, _, _ -> map(b, c, d, e) } + zip(SA, c, d, e, unit, unit, unit, unit, unit, unit) { b, c, d, e, _, _, _, _, _, _ -> map(b, c, d, e) } public inline fun Ior.zip( SA: Semigroup, @@ -781,9 +616,9 @@ public inline fun Ior.zip( d: Ior, e: Ior, f: Ior, - map: (B, C, D, E, F) -> G + map: (B, C, D, E, F) -> G, ): Ior = - zip(SA, c, d, e, f, Right.unit, Right.unit, Right.unit, Right.unit, Right.unit) { b, c, d, e, f, _, _, _, _, _ -> map(b, c, d, e, f) } + zip(SA, c, d, e, f, unit, unit, unit, unit, unit) { b, c, d, e, f, _, _, _, _, _ -> map(b, c, d, e, f) } public inline fun Ior.zip( SA: Semigroup, @@ -792,9 +627,9 @@ public inline fun Ior.zip( e: Ior, f: Ior, g: Ior, - map: (B, C, D, E, F, G) -> H + map: (B, C, D, E, F, G) -> H, ): Ior = - zip(SA, c, d, e, f, g, Right.unit, Right.unit, Right.unit, Right.unit) { b, c, d, e, f, g, _, _, _, _ -> map(b, c, d, e, f, g) } + zip(SA, c, d, e, f, g, unit, unit, unit, unit) { b, c, d, e, f, g, _, _, _, _ -> map(b, c, d, e, f, g) } public inline fun Ior.zip( SA: Semigroup, @@ -804,9 +639,9 @@ public inline fun Ior.zip( f: Ior, g: Ior, h: Ior, - map: (B, C, D, E, F, G, H) -> I + map: (B, C, D, E, F, G, H) -> I, ): Ior = - zip(SA, c, d, e, f, g, h, Right.unit, Right.unit, Right.unit) { b, c, d, e, f, g, h, _, _, _ -> map(b, c, d, e, f, g, h) } + zip(SA, c, d, e, f, g, h, unit, unit, unit) { b, c, d, e, f, g, h, _, _, _ -> map(b, c, d, e, f, g, h) } public inline fun Ior.zip( SA: Semigroup, @@ -817,9 +652,9 @@ public inline fun Ior.zip( g: Ior, h: Ior, i: Ior, - map: (B, C, D, E, F, G, H, I) -> J + map: (B, C, D, E, F, G, H, I) -> J, ): Ior = - zip(SA, c, d, e, f, g, h, i, Right.unit, Right.unit) { b, c, d, e, f, g, h, i, _, _ -> map(b, c, d, e, f, g, h, i) } + zip(SA, c, d, e, f, g, h, i, unit, unit) { b, c, d, e, f, g, h, i, _, _ -> map(b, c, d, e, f, g, h, i) } public inline fun Ior.zip( SA: Semigroup, @@ -831,9 +666,9 @@ public inline fun Ior.zip( h: Ior, i: Ior, j: Ior, - map: (B, C, D, E, F, G, H, I, J) -> K + map: (B, C, D, E, F, G, H, I, J) -> K, ): Ior = - zip(SA, c, d, e, f, g, h, i, j, Right.unit) { b, c, d, e, f, g, h, i, j, _ -> map(b, c, d, e, f, g, h, i, j) } + zip(SA, c, d, e, f, g, h, i, j, unit) { b, c, d, e, f, g, h, i, j, _ -> map(b, c, d, e, f, g, h, i, j) } public inline fun Ior.zip( SA: Semigroup, @@ -846,7 +681,7 @@ public inline fun Ior.zip( i: Ior, j: Ior, k: Ior, - map: (B, C, D, E, F, G, H, I, J, K) -> L + map: (B, C, D, E, F, G, H, I, J, K) -> L, ): Ior { // If any of the values is Right or Both then we can calculate L otherwise it results in MY_NULL val rightValue: Any? = if ( @@ -874,44 +709,44 @@ public inline fun Ior.zip( k.orNull() as K ) } else EmptyValue - + val leftValue: Any? = SA.run { var accumulatedLeft: Any? = EmptyValue - + if (this@zip is Left) return@zip Left(this@zip.value) accumulatedLeft = if (this@zip is Both) this@zip.leftValue else accumulatedLeft - + if (c is Left) return@zip Left(emptyCombine(accumulatedLeft, c.value)) accumulatedLeft = if (c is Both) emptyCombine(accumulatedLeft, c.leftValue) else accumulatedLeft - + if (d is Left) return@zip Left(emptyCombine(accumulatedLeft, d.value)) accumulatedLeft = if (d is Both) emptyCombine(accumulatedLeft, d.leftValue) else accumulatedLeft - + if (e is Left) return@zip Left(emptyCombine(accumulatedLeft, e.value)) accumulatedLeft = if (e is Both) emptyCombine(accumulatedLeft, e.leftValue) else accumulatedLeft - + if (f is Left) return@zip Left(emptyCombine(accumulatedLeft, f.value)) accumulatedLeft = if (f is Both) emptyCombine(accumulatedLeft, f.leftValue) else accumulatedLeft - + if (g is Left) return@zip Left(emptyCombine(accumulatedLeft, g.value)) accumulatedLeft = if (g is Both) emptyCombine(accumulatedLeft, g.leftValue) else accumulatedLeft - + if (h is Left) return@zip Left(emptyCombine(accumulatedLeft, h.value)) accumulatedLeft = if (h is Both) emptyCombine(accumulatedLeft, h.leftValue) else accumulatedLeft - + if (i is Left) return@zip Left(emptyCombine(accumulatedLeft, i.value)) accumulatedLeft = if (i is Both) emptyCombine(accumulatedLeft, i.leftValue) else accumulatedLeft - + if (j is Left) return@zip Left(emptyCombine(accumulatedLeft, j.value)) accumulatedLeft = if (j is Both) emptyCombine(accumulatedLeft, j.leftValue) else accumulatedLeft - + if (k is Left) return@zip Left(emptyCombine(accumulatedLeft, k.value)) accumulatedLeft = if (k is Both) emptyCombine(accumulatedLeft, k.leftValue) else accumulatedLeft - + accumulatedLeft } - + return when { rightValue != EmptyValue && leftValue == EmptyValue -> Right(rightValue as L) rightValue != EmptyValue && leftValue != EmptyValue -> Both(leftValue as A, rightValue as L) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt index c3bd1d2f16d..2326ace09bf 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Iterable.kt @@ -4,9 +4,10 @@ package arrow.core import arrow.core.Either.Left import arrow.core.Either.Right +import arrow.core.continuations.Raise +import arrow.core.continuations.either import arrow.typeclasses.Monoid import arrow.typeclasses.Semigroup -import kotlin.Result.Companion.success import kotlin.experimental.ExperimentalTypeInference public inline fun Iterable.zip( @@ -283,154 +284,57 @@ public inline fun Iterable.zip( internal fun Iterable.collectionSizeOrDefault(default: Int): Int = if (this is Collection<*>) this.size else default -@Deprecated("traverseEither is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse")) -public inline fun Iterable.traverseEither(f: (A) -> Either): Either> = - traverse(f) - -@OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public inline fun Iterable.traverse(f: (A) -> Either): Either> { - val destination = ArrayList(collectionSizeOrDefault(10)) - for (item in this) { - when (val res = f(item)) { - is Right -> destination.add(res.value) - is Left -> return res - } - } - return destination.right() -} - -@Deprecated("sequenceEither is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Iterable>.sequenceEither(): Either> = - traverse(::identity) - -public fun Iterable>.sequence(): Either> = - traverse(::identity) - -@OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public inline fun Iterable.traverse(f: (A) -> Result): Result> { - val destination = ArrayList(collectionSizeOrDefault(10)) - for (item in this) { - f(item).fold(destination::add) { throwable -> - return@traverse Result.failure(throwable) - } - } - return success(destination) -} - -@Deprecated("traverseResult is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse")) -public inline fun Iterable.traverseResult(f: (A) -> Result): Result> = - traverse(f) - -@Deprecated("sequenceResult is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Iterable>.sequenceResult(): Result> = - sequence() - -public fun Iterable>.sequence(): Result> = - traverse(::identity) - -@Deprecated("traverseValidated is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(semigroup, f)", "arrow.core.traverse")) -public inline fun Iterable.traverseValidated( - semigroup: Semigroup, - f: (A) -> Validated -): Validated> = - traverse(semigroup, f) - +/** + * Returns [Either] a [List] containing the results of applying the given [transform] function + * to each element in the original collection, + * **or** accumulate all the _logical errors_ that were _raised_ while transforming the collection. + * The [semigroup] is used to accumulate all the _logical errors_. + */ @OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public inline fun Iterable.traverse( - semigroup: Semigroup, - f: (A) -> Validated -): Validated> = - semigroup.run { - fold(Valid(ArrayList(collectionSizeOrDefault(10))) as Validated>) { acc, a -> - when (val res = f(a)) { - is Validated.Valid -> when (acc) { - is Valid -> acc.also { it.value.add(res.value) } - is Invalid -> acc - } - is Validated.Invalid -> when (acc) { - is Valid -> res - is Invalid -> Invalid(acc.value.combine(res.value)) - } +public inline fun Iterable.mapOrAccumulate( + semigroup: Semigroup, + @BuilderInference transform: Raise.(A) -> B, +): Either> = + fold>>(Right(ArrayList(collectionSizeOrDefault(10)))) { acc, a -> + when (val res = either { transform(a) }) { + is Right -> when (acc) { + is Right -> acc.also { acc.value.add(res.value) } + is Left -> acc + } + + is Left -> when (acc) { + is Right -> res + is Left -> Left(semigroup.append(acc.value, res.value)) } } } -@Deprecated("traverseValidated is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse")) -public inline fun Iterable.traverseValidated(f: (A) -> ValidatedNel): ValidatedNel> = - traverse(f) - -@OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public inline fun Iterable.traverse(f: (A) -> ValidatedNel): ValidatedNel> = - traverse(Semigroup.nonEmptyList(), f) - -@Deprecated("sequenceValidated is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence(semigroup)", "arrow.core.sequence")) -public fun Iterable>.sequenceValidated(semigroup: Semigroup): Validated> = - sequence(semigroup) - -public fun Iterable>.sequence(semigroup: Semigroup): Validated> = - traverse(semigroup, ::identity) - -@Deprecated("sequenceValidated is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Iterable>.sequenceValidated(): ValidatedNel> = - sequence() - -public fun Iterable>.sequence(): ValidatedNel> = - traverse(Semigroup.nonEmptyList(), ::identity) - -@Deprecated("traverseOption is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse")) -public inline fun Iterable.traverseOption(f: (A) -> Option): Option> = - traverse(f) - -@OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public inline fun Iterable.traverse(f: (A) -> Option): Option> { - val destination = ArrayList(collectionSizeOrDefault(10)) - for (item in this) { - when (val res = f(item)) { - is Some -> destination.add(res.value) - is None -> return res - } - } - return destination.some() -} - -@Deprecated("sequenceOption is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Iterable>.sequenceOption(): Option> = - sequence() - -public fun Iterable>.sequence(): Option> = - traverse(::identity) - -@Deprecated("traverseNullable is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse")) -public inline fun Iterable.traverseNullable(f: (A) -> B?): List? = - traverse(f) - +/** + * Returns [Either] a [List] containing the results of applying the given [transform] function + * to each element in the original collection, + * **or** accumulate all the _logical errors_ into a [NonEmptyList] that were _raised_ while applying the [transform] function. + */ @OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public inline fun Iterable.traverse(f: (A) -> B?): List? { - val acc = mutableListOf() - forEach { a -> - val res = f(a) - if (res != null) { - acc.add(res) - } else { - return res +public inline fun Iterable.mapOrAccumulate( + @BuilderInference transform: Raise.(A) -> B, +): Either, List> { + val buffer = mutableListOf() + val res = fold, ArrayList>>(Right(ArrayList(collectionSizeOrDefault(10)))) { acc, a -> + when (val res = either { transform(a) }) { + is Right -> when (acc) { + is Right -> acc.also { acc.value.add(res.value) } + is Left -> acc + } + + is Left -> when (acc) { + is Right -> Left(buffer.also { it.add(res.value) }) + is Left -> Left(buffer.also { it.add(res.value) }) + } } } - return acc.toList() + return res.mapLeft { NonEmptyList(it[0], it.drop(1)) } } -@Deprecated("sequenceNullable is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Iterable.sequenceNullable(): List? = - sequence() - -public fun Iterable.sequence(): List? = - traverse(::identity) - public fun Iterable.void(): List = map { } @@ -665,11 +569,11 @@ private fun alignRec(ls: Iterable, rs: Iterable): List> { } /** - * aligns two structures and combine them with the given [Semigroup.combine] + * aligns two structures and combine them with the given [Semigroup.append] */ public fun Iterable.salign( SG: Semigroup, - other: Iterable + other: Iterable, ): Iterable = SG.run { align(other) { it.fold(::identity, ::identity) { a, b -> @@ -783,6 +687,7 @@ public fun Iterable.firstOrNone(): Option = } else { None } + else -> { iterator().nextOrNone() } @@ -816,6 +721,7 @@ public fun Iterable.singleOrNone(): Option = 1 -> firstOrNone() else -> None } + else -> { iterator().run { nextOrNone().filter { !hasNext() } } } @@ -847,6 +753,7 @@ public fun Iterable.lastOrNone(): Option = } else { None } + else -> iterator().run { if (hasNext()) { var last: T @@ -881,6 +788,7 @@ public fun Iterable.elementAtOrNone(index: Int): Option = in indices -> Some(elementAt(index)) else -> None } + else -> iterator().skip(index).nextOrNone() } @@ -890,6 +798,7 @@ private tailrec fun Iterator.skip(count: Int): Iterator = next() skip(count - 1) } + else -> this } @@ -987,48 +896,25 @@ public inline fun Iterable.ifThen(fb: Iterable, ffa: (A) -> Iterabl public fun Iterable>.uniteEither(): List = mapNotNull { it.orNull() } -@Deprecated("Use mapNotNull and orNull instead.", ReplaceWith("mapNotNull { it.orNull() }", "arrow.core.orNull")) -public fun Iterable>.uniteValidated(): List = - mapNotNull { it.orNull() } - /** * Separate the inner [Either] values into the [Either.Left] and [Either.Right]. * - * @receiver Iterable of Validated + * @receiver Iterable of Either * @return a tuple containing List with [Either.Left] and another List with its [Either.Right] values. */ public fun Iterable>.separateEither(): Pair, List> { val left = ArrayList(collectionSizeOrDefault(10)) val right = ArrayList(collectionSizeOrDefault(10)) - + for (either in this) when (either) { is Left -> left.add(either.value) is Right -> right.add(either.value) } - + return Pair(left, right) } -/** - * Separate the inner [Validated] values into the [Validated.Invalid] and [Validated.Valid]. - * - * @receiver Iterable of Validated - * @return a tuple containing List with [Validated.Invalid] and another List with its [Validated.Valid] values. - */ -public fun Iterable>.separateValidated(): Pair, List> { - val invalids = ArrayList(collectionSizeOrDefault(10)) - val valids = ArrayList(collectionSizeOrDefault(10)) - - for (validated in this) - when (validated) { - is Invalid -> invalids.add(validated.value) - is Valid -> valids.add(validated.value) - } - - return Pair(invalids, valids) -} - public fun Iterable>.flatten(): List = flatMap(::identity) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyList.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyList.kt index 41ea03aced8..4f10a35ba14 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyList.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/NonEmptyList.kt @@ -1,9 +1,6 @@ package arrow.core -import arrow.core.Either.Left -import arrow.core.Either.Right import arrow.typeclasses.Semigroup -import kotlin.experimental.ExperimentalTypeInference import kotlin.jvm.JvmStatic public typealias Nel = NonEmptyList @@ -409,98 +406,6 @@ public fun NonEmptyList.unzip(f: (C) -> Pair): Pair NonEmptyList.traverseEither(f: (A) -> Either): Either> = - traverse(f) - -@OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public inline fun NonEmptyList.traverse(f: (A) -> Either): Either> = - f(head).map { newHead -> - val acc = mutableListOf() - tail.forEach { a -> - when (val res = f(a)) { - is Right -> acc.add(res.value) - is Left -> return@traverse res - } - } - NonEmptyList(newHead, acc) - } - -@Deprecated("sequenceEither is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun NonEmptyList>.sequenceEither(): Either> = - sequence() - -public fun NonEmptyList>.sequence(): Either> = - traverse(::identity) - -@Deprecated( - "traverseValidated is being renamed to traverse to simplify the Arrow API", - ReplaceWith("traverse(semigroup, f)", "arrow.core.traverse") -) -public inline fun NonEmptyList.traverseValidated( - semigroup: Semigroup, - f: (A) -> Validated -): Validated> = - traverse(semigroup, f) - -@OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public inline fun NonEmptyList.traverse( - semigroup: Semigroup, - f: (A) -> Validated -): Validated> = - fold>>(mutableListOf().valid()) { acc, a -> - when (val res = f(a)) { - is Valid -> when (acc) { - is Valid -> acc.also { it.value.add(res.value) } - is Invalid -> acc - } - is Invalid -> when (acc) { - is Valid -> res - is Invalid -> semigroup.run { Invalid(acc.value.combine(res.value)) } - } - } - }.map { requireNotNull(it.toNonEmptyListOrNull()) } - -@Deprecated("sequenceValidated is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun NonEmptyList>.sequenceValidated(semigroup: Semigroup): Validated> = - sequence(semigroup) - -public fun NonEmptyList>.sequence(semigroup: Semigroup): Validated> = - traverse(semigroup, ::identity) - -@Deprecated( - "traverseOption is being renamed to traverse to simplify the Arrow API", - ReplaceWith("traverse(f)", "arrow.core.traverse") -) -public inline fun NonEmptyList.traverseOption(f: (A) -> Option): Option> = - traverse(f) - -@OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public inline fun NonEmptyList.traverse(f: (A) -> Option): Option> = - f(head).map { newHead -> - val acc = mutableListOf() - tail.forEach { a -> - when (val res = f(a)) { - is Some -> acc.add(res.value) - is None -> return@traverse res - } - } - NonEmptyList(newHead, acc) - } - -@Deprecated("sequenceOption is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun NonEmptyList>.sequenceOption(): Option> = - sequence() - -public fun NonEmptyList>.sequence(): Option> = - traverse(::identity) - public fun Iterable.toNonEmptyListOrNull(): NonEmptyList? = firstOrNull()?.let { NonEmptyList(it, drop(1)) } diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Option.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Option.kt index 0c86bd2ccbe..6fe6dbaaf87 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Option.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Option.kt @@ -1,9 +1,7 @@ package arrow.core -import arrow.core.Either.Right import arrow.typeclasses.Monoid import arrow.typeclasses.Semigroup -import kotlin.experimental.ExperimentalTypeInference import kotlin.jvm.JvmName import kotlin.jvm.JvmStatic @@ -813,35 +811,6 @@ public sealed class Option { public fun replicate(n: Int): Option> = if (n <= 0) Some(emptyList()) else map { a -> List(n) { a } } - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (A) -> Iterable): List> = - fold({ emptyList() }, { a -> fa(a).map { Some(it) } }) - - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (A) -> Either): Either> = - when (this) { - is Some -> fa(value).map { Some(it) } - is None -> Right(this) - } - - @Deprecated("traverseEither is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(fa)")) - public inline fun traverseEither(fa: (A) -> Either): Either> = - traverse(fa) - - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (A) -> Validated): Validated> = - when (this) { - is Some -> fa(value).map { Some(it) } - is None -> Valid(this) - } - - @Deprecated("traverseValidated is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(fa)")) - public inline fun traverseValidated(fa: (A) -> Validated): Validated> = - traverse(fa) - public inline fun toEither(ifEmpty: () -> L): Either = fold({ ifEmpty().left() }, { it.right() }) @@ -991,35 +960,6 @@ public fun Option>.separateEither(): Pair, Option< return asep to bsep } -/** - * Separate the inner [Validated] value into the [Validated.Invalid] and [Validated.Valid]. - * - * @receiver Option of Either - * @return a tuple containing Option of [Validated.Invalid] and another Option of its [Validated.Valid] value. - */ -public fun Option>.separateValidated(): Pair, Option> { - val asep = flatMap { gab -> gab.fold({ Some(it) }, { None }) } - val bsep = flatMap { gab -> gab.fold({ None }, { Some(it) }) } - return asep to bsep -} - -public fun Option>.sequence(): List> = - traverse(::identity) - -@Deprecated("sequenceEither is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Option>.sequenceEither(): Either> = - sequence() - -public fun Option>.sequence(): Either> = - traverse(::identity) - -@Deprecated("sequenceValidated is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Option>.sequenceValidated(): Validated> = - sequence() - -public fun Option>.sequence(): Validated> = - traverse(::identity) - public fun Option>.unalign(): Pair, Option> = unalign(::identity) @@ -1043,11 +983,6 @@ public fun Option>.uniteEither(): Option = either.fold({ None }, { b -> Some(b) }) } -public fun Option>.uniteValidated(): Option = - flatMap { validated -> - validated.fold({ None }, { b -> Some(b) }) - } - public fun Option>.unzip(): Pair, Option> = unzip(::identity) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Sequence.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Sequence.kt index 7f67780684d..fc2ffe650b8 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Sequence.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Sequence.kt @@ -4,7 +4,6 @@ import arrow.core.Either.Left import arrow.core.Either.Right import arrow.typeclasses.Monoid import arrow.typeclasses.Semigroup -import kotlin.experimental.ExperimentalTypeInference public fun Sequence.zip( c: Sequence, @@ -574,7 +573,7 @@ public fun Sequence.rightPadZip(other: Sequence): Sequence a to b } /** - * aligns two structures and combine them with the given [Semigroup.combine] + * aligns two structures and combine them with the given [Semigroup.append] */ public fun Sequence.salign( SG: Semigroup, @@ -590,7 +589,7 @@ public fun Sequence.salign( /** * Separate the inner [Either] values into the [Either.Left] and [Either.Right]. * - * @receiver Iterable of Validated + * @receiver Iterable of Either * @return a tuple containing Sequence with [Either.Left] and another Sequence with its [Either.Right] values. */ public fun Sequence>.separateEither(): Pair, Sequence> = @@ -601,49 +600,6 @@ public fun Sequence>.separateEither(): Pair, Seq } } -/** - * Separate the inner [Validated] values into the [Validated.Invalid] and [Validated.Valid]. - * - * @receiver Iterable of Validated - * @return a tuple containing Sequence with [Validated.Invalid] and another Sequence with its [Validated.Valid] values. - */ -public fun Sequence>.separateValidated(): Pair, Sequence> = - fold(sequenceOf() to sequenceOf()) { (invalids, valids), validated -> - when (validated) { - is Valid -> invalids to valids + validated.value - is Invalid -> invalids + validated.value to valids - } - } - -public fun Sequence>.sequence(): Either> = - traverse(::identity) - -@Deprecated( - "sequenceEither is being renamed to sequence to simplify the Arrow API", - ReplaceWith("sequence().map { it.asSequence() }", "arrow.core.sequence") -) -public fun Sequence>.sequenceEither(): Either> = - sequence().map { it.asSequence() } - -public fun Sequence>.sequence(): Option> = - traverse(::identity) - -@Deprecated( - "sequenceOption is being renamed to sequence to simplify the Arrow API", - ReplaceWith("sequence().map { it.asSequence() }", "arrow.core.sequence") -) -public fun Sequence>.sequenceOption(): Option> = - sequence().map { it.asSequence() } - -public fun Sequence>.sequence(semigroup: Semigroup): Validated> = - traverse(semigroup, ::identity) - -@Deprecated( - "sequenceValidated is being renamed to sequence to simplify the Arrow API", - ReplaceWith("sequence(semigroup).map { it.asSequence() }", "arrow.core.sequence") -) -public fun Sequence>.sequenceValidated(semigroup: Semigroup): Validated> = - sequence(semigroup).map { it.asSequence() } @Deprecated("some is being deprecated in favor of map", ReplaceWith("map { generateSequence { this } }")) public fun Sequence.some(): Sequence> = @@ -673,81 +629,6 @@ public fun Sequence.split(): Pair, A>? = public fun Sequence.tail(): Sequence = drop(1) -@OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public fun Sequence.traverse(f: (A) -> Either): Either> { - // Note: Using a mutable list here avoids the stackoverflows one can accidentally create when using - // Sequence.plus instead. But we don't convert the sequence to a list beforehand to avoid - // forcing too much of the sequence to be evaluated. - val acc = mutableListOf() - forEach { a -> - when (val res = f(a)) { - is Right -> acc.add(res.value) - is Left -> return@traverse res - } - } - return acc.toList().right() -} - -@Deprecated( - "traverseEither is being renamed to traverse to simplify the Arrow API", - ReplaceWith("traverse(f).map { it.asSequence() }", "arrow.core.traverse") -) -public fun Sequence.traverseEither(f: (A) -> Either): Either> = - traverse(f).map { it.asSequence() } - -@OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public fun Sequence.traverse(f: (A) -> Option): Option> { - // Note: Using a mutable list here avoids the stackoverflows one can accidentally create when using - // Sequence.plus instead. But we don't convert the sequence to a list beforehand to avoid - // forcing too much of the sequence to be evaluated. - val acc = mutableListOf() - forEach { a -> - when (val res = f(a)) { - is Some -> acc.add(res.value) - is None -> return@traverse res - } - } - return Some(acc) -} - -@Deprecated( - "traverseOption is being renamed to traverse to simplify the Arrow API", - ReplaceWith("traverse(f).map { it.asSequence() }", "arrow.core.traverse") -) -public fun Sequence.traverseOption(f: (A) -> Option): Option> = - traverse(f).map { it.asSequence() } - -@OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public fun Sequence.traverse( - semigroup: Semigroup, - f: (A) -> Validated -): Validated> = - fold(mutableListOf().valid() as Validated>) { acc, a -> - when (val res = f(a)) { - is Valid -> when (acc) { - is Valid -> acc.also { it.value.add(res.value) } - is Invalid -> acc - } - is Invalid -> when (acc) { - is Valid -> res - is Invalid -> semigroup.run { acc.value.combine(res.value).invalid() } - } - } - } - -@Deprecated( - "traverseValidated is being renamed to traverse to simplify the Arrow API", - ReplaceWith("traverse(semigroup, f).map { it.asSequence() }", "arrow.core.traverse") -) -public fun Sequence.traverseValidated( - semigroup: Semigroup, - f: (A) -> Validated -): Validated> = - traverse(semigroup, f).map { it.asSequence() } - /** * splits an union into its component parts. * @@ -798,11 +679,6 @@ public fun Sequence>.uniteEither(): Sequence = either.fold({ emptySequence() }, { b -> sequenceOf(b) }) } -public fun Sequence>.uniteValidated(): Sequence = - flatMap { validated -> - validated.fold({ emptySequence() }, { b -> sequenceOf(b) }) - } - /** * Fair conjunction. Similarly to interleave * diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Validated.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Validated.kt deleted file mode 100644 index cf668335f19..00000000000 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Validated.kt +++ /dev/null @@ -1,856 +0,0 @@ -package arrow.core - -import arrow.typeclasses.Monoid -import arrow.typeclasses.Semigroup -import arrow.core.Either.Left -import arrow.core.Either.Right -import kotlin.experimental.ExperimentalTypeInference -import kotlin.jvm.JvmName -import kotlin.jvm.JvmStatic - -public typealias ValidatedNel = Validated, A> -public typealias Valid = Validated.Valid -public typealias Invalid = Validated.Invalid - -public sealed class Validated { - - public companion object { - - @JvmStatic - public fun invalidNel(e: E): ValidatedNel = Invalid(nonEmptyListOf(e)) - - @JvmStatic - public fun validNel(a: A): ValidatedNel = Valid(a) - - /** - * Converts an `Either` to a `Validated`. - */ - @JvmStatic - public fun fromEither(e: Either): Validated = e.fold({ Invalid(it) }, { Valid(it) }) - - /** - * Converts an `Option` to a `Validated`, where the provided `ifNone` output value is returned as [Invalid] - * when the specified `Option` is `None`. - */ - @JvmStatic - public inline fun fromOption(o: Option, ifNone: () -> E): Validated = - o.fold( - { Invalid(ifNone()) }, - { Valid(it) } - ) - - /** - * Converts a nullable `A?` to a `Validated`, where the provided `ifNull` output value is returned as [Invalid] - * when the specified value is null. - */ - @JvmStatic - public inline fun fromNullable(value: A?, ifNull: () -> E): Validated = - value?.let(::Valid) ?: Invalid(ifNull()) - - @JvmStatic - @JvmName("tryCatch") - public inline fun catch(f: () -> A): Validated = - try { - f().valid() - } catch (e: Throwable) { - e.nonFatalOrThrow().invalid() - } - - @JvmStatic - @JvmName("tryCatch") - public inline fun catch(recover: (Throwable) -> E, f: () -> A): Validated = - catch(f).mapLeft(recover) - - @JvmStatic - public inline fun catchNel(f: () -> A): ValidatedNel = - try { - f().validNel() - } catch (e: Throwable) { - e.nonFatalOrThrow().invalidNel() - } - - @JvmStatic - public inline fun lift(crossinline f: (A) -> B): (Validated) -> Validated = - { fa -> fa.map(f) } - - /** - * Lifts two functions to the Bifunctor type. - * - * ```kotlin - * import arrow.core.* - * - * fun main(args: Array) { - * //sampleStart - * val f = Validated.lift(String::toUpperCase, Int::inc) - * val res1 = f("test".invalid()) - * val res2 = f(1.valid()) - * //sampleEnd - * println("res1: $res1") - * println("res2: $res2") - * } - * ``` - * - */ - @JvmStatic - public inline fun lift( - crossinline fl: (A) -> C, - crossinline fr: (B) -> D - ): (Validated) -> Validated = - { fa -> fa.bimap(fl, fr) } - } - - /** - * Discards the [A] value inside [Validated] signaling this container may be pointing to a noop - * or an effect whose return value is deliberately ignored. The singleton value [Unit] serves as signal. - * - * ```kotlin - * import arrow.core.* - * - * fun main(args: Array) { - * val result = - * //sampleStart - * "Hello World".valid().void() - * //sampleEnd - * println(result) - * } - * ``` - * - */ - public fun void(): Validated = - map { Unit } - - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (A) -> Iterable): List> = - fold({ emptyList() }, { a -> fa(a).map { Valid(it) } }) - - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (A) -> Either): Either> = - when (this) { - is Valid -> fa(this.value).map { Valid(it) } - is Invalid -> this.right() - } - - @Deprecated("traverseEither is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(fa)")) - public inline fun traverseEither(fa: (A) -> Either): Either> = - traverse(fa) - - @OptIn(ExperimentalTypeInference::class) - @OverloadResolutionByLambdaReturnType - public inline fun traverse(fa: (A) -> Option): Option> = - when (this) { - is Valid -> fa(this.value).map { Valid(it) } - is Invalid -> None - } - - @Deprecated("traverseOption is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(fa)")) - public inline fun traverseOption(fa: (A) -> Option): Option> = - traverse(fa) - - public inline fun traverseNullable(fa: (A) -> B?): Validated? = - when (this) { - is Valid -> fa(this.value)?.let { Valid(it) } - is Invalid -> null - } - - public inline fun bifoldLeft( - c: B, - fe: (B, E) -> B, - fa: (B, A) -> B - ): B = - fold({ fe(c, it) }, { fa(c, it) }) - - public inline fun bifoldMap(MN: Monoid, g: (E) -> B, f: (A) -> B): B = MN.run { - bifoldLeft(MN.empty(), { c, b -> c.combine(g(b)) }) { c, a -> c.combine(f(a)) } - } - - public inline fun bitraverse(fe: (E) -> Iterable, fa: (A) -> Iterable): List> = - fold({ fe(it).map { Invalid(it) } }, { fa(it).map { Valid(it) } }) - - public inline fun bitraverseEither( - fe: (E) -> Either, - fa: (A) -> Either - ): Either> = - fold({ fe(it).map { Invalid(it) } }, { fa(it).map { Valid(it) } }) - - public inline fun bitraverseOption( - fe: (E) -> Option, - fa: (A) -> Option - ): Option> = - fold({ fe(it).map(::Invalid) }, { fa(it).map(::Valid) }) - - public inline fun bitraverseNullable( - fe: (E) -> B?, - fa: (A) -> C? - ): Validated? = - fold({ fe(it)?.let(::Invalid) }, { fa(it)?.let(::Valid) }) - - public inline fun foldMap(MB: Monoid, f: (A) -> B): B = - fold({ MB.empty() }, f) - - override fun toString(): String = fold( - { "Validated.Invalid($it)" }, - { "Validated.Valid($it)" } - ) - - public data class Valid(val value: A) : Validated() { - override fun toString(): String = "Validated.Valid($value)" - - public companion object { - @PublishedApi - internal val unit: Validated = - Validated.Valid(Unit) - } - } - - public data class Invalid(val value: E) : Validated() { - override fun toString(): String = "Validated.Invalid($value)" - } - - public inline fun fold(fe: (E) -> B, fa: (A) -> B): B = - when (this) { - is Valid -> fa(value) - is Invalid -> (fe(value)) - } - - public val isValid: Boolean = - fold({ false }, { true }) - public val isInvalid: Boolean = - fold({ true }, { false }) - - /** - * Is this Valid and matching the given predicate - */ - public inline fun exist(predicate: (A) -> Boolean): Boolean = - fold({ false }, predicate) - - public inline fun findOrNull(predicate: (A) -> Boolean): A? = - when (this) { - is Valid -> if (predicate(this.value)) this.value else null - is Invalid -> null - } - - public inline fun all(predicate: (A) -> Boolean): Boolean = - fold({ true }, predicate) - - public fun isEmpty(): Boolean = isInvalid - - public fun isNotEmpty(): Boolean = isValid - - /** - * Converts the value to an Either - */ - public fun toEither(): Either = - fold(::Left, ::Right) - - /** - * Returns Valid values wrapped in Some, and None for Invalid values - */ - public fun toOption(): Option = - fold({ None }, ::Some) - - /** - * Convert this value to a single element List if it is Valid, - * otherwise return an empty List - */ - public fun toList(): List = - fold({ listOf() }, ::listOf) - - /** Lift the Invalid value into a NonEmptyList. */ - public fun toValidatedNel(): ValidatedNel = - fold({ invalidNel(it) }, ::Valid) - - /** - * Convert to an Either, apply a function, convert back. This is handy - * when you want to use the Monadic properties of the Either type. - */ - public inline fun withEither(f: (Either) -> Either): Validated = - fromEither(f(toEither())) - - /** - * From [arrow.typeclasses.Bifunctor], maps both types of this Validated. - * - * Apply a function to an Invalid or Valid value, returning a new Invalid or Valid value respectively. - */ - public inline fun bimap(fe: (E) -> EE, fa: (A) -> B): Validated = - fold({ Invalid(fe(it)) }, { Valid(fa(it)) }) - - /** - * Apply a function to a Valid value, returning a new Valid value - */ - public inline fun map(f: (A) -> B): Validated = - bimap(::identity, f) - - /** - * Apply a function to an Invalid value, returning a new Invalid value. - * Or, if the original valid was Valid, return it. - */ - public inline fun mapLeft(f: (E) -> EE): Validated = - bimap(f, ::identity) - - /** - * The given function is applied as a fire and forget effect - * if this is `Invalid`. - * When applied the result is ignored and the original - * Validated value is returned - * - * Example: - * ```kotlin - * import arrow.core.Validated - * - * fun main() { - * Validated.Valid(12).tapInvalid { println("flower") } // Result: Valid(12) - * Validated.Invalid(12).tapInvalid { println("flower") } // Result: prints "flower" and returns: Invalid(12) - * } - * ``` - * - */ - public inline fun tapInvalid(f: (E) -> Unit): Validated = - when (this) { - is Invalid -> { - f(this.value) - this - } - is Valid -> this - } - - /** - * The given function is applied as a fire and forget effect - * if this is `Valid`. - * When applied the result is ignored and the original - * Validated value is returned - * - * Example: - * ```kotlin - * import arrow.core.Validated - * - * fun main() { - * Validated.Valid(12).tap { println("flower") } // Result: prints "flower" and returns: Valid(12) - * Validated.Invalid(12).tap { println("flower") } // Result: Invalid(12) - * } - * ``` - * - */ - public inline fun tap(f: (A) -> Unit): Validated = - when (this) { - is Invalid -> this - is Valid -> { - f(this.value) - this - } - } - - /** - * apply the given function to the value with the given B when - * valid, otherwise return the given B - */ - public inline fun foldLeft(b: B, f: (B, A) -> B): B = - fold({ b }, { f(b, it) }) - - public fun swap(): Validated = - fold(::Valid, ::Invalid) -} - -public fun Validated.zip(SE: Semigroup, fb: Validated): Validated> = - zip(SE, fb, ::Pair) - -public inline fun Validated.zip( - SE: Semigroup, - b: Validated, - f: (A, B) -> Z -): Validated = - zip( - SE, - b, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit - ) { a, b, _, _, _, _, _, _, _, _ -> - f(a, b) - } - -public inline fun Validated.zip( - SE: Semigroup, - b: Validated, - c: Validated, - f: (A, B, C) -> Z -): Validated = - zip( - SE, - b, - c, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit - ) { a, b, c, _, _, _, _, _, _, _ -> - f(a, b, c) - } - -public inline fun Validated.zip( - SE: Semigroup, - b: Validated, - c: Validated, - d: Validated, - f: (A, B, C, D) -> Z -): Validated = - zip( - SE, - b, - c, - d, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit - ) { a, b, c, d, _, _, _, _, _, _ -> - f(a, b, c, d) - } - -public inline fun Validated.zip( - SE: Semigroup, - b: Validated, - c: Validated, - d: Validated, - e: Validated, - f: (A, B, C, D, EE) -> Z -): Validated = - zip( - SE, - b, - c, - d, - e, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit - ) { a, b, c, d, e, _, _, _, _, _ -> - f(a, b, c, d, e) - } - -public inline fun Validated.zip( - SE: Semigroup, - b: Validated, - c: Validated, - d: Validated, - e: Validated, - ff: Validated, - f: (A, B, C, D, EE, FF) -> Z -): Validated = - zip( - SE, - b, - c, - d, - e, - ff, - Valid.unit, - Valid.unit, - Valid.unit, - Valid.unit - ) { a, b, c, d, e, ff, _, _, _, _ -> - f(a, b, c, d, e, ff) - } - -public inline fun Validated.zip( - SE: Semigroup, - b: Validated, - c: Validated, - d: Validated, - e: Validated, - ff: Validated, - g: Validated, - f: (A, B, C, D, EE, F, G) -> Z -): Validated = - zip(SE, b, c, d, e, ff, g, Valid.unit, Valid.unit, Valid.unit) { a, b, c, d, e, ff, g, _, _, _ -> - f(a, b, c, d, e, ff, g) - } - -public inline fun Validated.zip( - SE: Semigroup, - b: Validated, - c: Validated, - d: Validated, - e: Validated, - ff: Validated, - g: Validated, - h: Validated, - f: (A, B, C, D, EE, F, G, H) -> Z -): Validated = - zip(SE, b, c, d, e, ff, g, h, Valid.unit, Valid.unit) { a, b, c, d, e, ff, g, h, _, _ -> - f(a, b, c, d, e, ff, g, h) - } - -public inline fun Validated.zip( - SE: Semigroup, - b: Validated, - c: Validated, - d: Validated, - e: Validated, - ff: Validated, - g: Validated, - h: Validated, - i: Validated, - f: (A, B, C, D, EE, F, G, H, I) -> Z -): Validated = - zip(SE, b, c, d, e, ff, g, h, i, Valid.unit) { a, b, c, d, e, ff, g, h, i, _ -> - f(a, b, c, d, e, ff, g, h, i) - } - -public inline fun Validated.zip( - SE: Semigroup, - b: Validated, - c: Validated, - d: Validated, - e: Validated, - ff: Validated, - g: Validated, - h: Validated, - i: Validated, - j: Validated, - f: (A, B, C, D, EE, F, G, H, I, J) -> Z -): Validated = - if (this is Validated.Valid && b is Validated.Valid && c is Validated.Valid && d is Validated.Valid && e is Validated.Valid && ff is Validated.Valid && g is Validated.Valid && h is Validated.Valid && i is Validated.Valid && j is Validated.Valid) { - Validated.Valid(f(this.value, b.value, c.value, d.value, e.value, ff.value, g.value, h.value, i.value, j.value)) - } else SE.run { - var accumulatedError: Any? = EmptyValue - accumulatedError = - if (this@zip is Validated.Invalid) this@zip.value else accumulatedError - accumulatedError = - if (b is Validated.Invalid) emptyCombine(accumulatedError, b.value) else accumulatedError - accumulatedError = - if (c is Validated.Invalid) emptyCombine(accumulatedError, c.value) else accumulatedError - accumulatedError = - if (d is Validated.Invalid) emptyCombine(accumulatedError, d.value) else accumulatedError - accumulatedError = - if (e is Validated.Invalid) emptyCombine(accumulatedError, e.value) else accumulatedError - accumulatedError = - if (ff is Validated.Invalid) emptyCombine(accumulatedError, ff.value) else accumulatedError - accumulatedError = - if (g is Validated.Invalid) emptyCombine(accumulatedError, g.value) else accumulatedError - accumulatedError = - if (h is Validated.Invalid) emptyCombine(accumulatedError, h.value) else accumulatedError - accumulatedError = - if (i is Validated.Invalid) emptyCombine(accumulatedError, i.value) else accumulatedError - accumulatedError = - if (j is Validated.Invalid) emptyCombine(accumulatedError, j.value) else accumulatedError - - Validated.Invalid(accumulatedError as E) - } - -public inline fun ValidatedNel.zip( - b: ValidatedNel, - f: (A, B) -> Z -): ValidatedNel = - zip(Semigroup.nonEmptyList(), b, f) - -public inline fun ValidatedNel.zip( - b: ValidatedNel, - c: ValidatedNel, - f: (A, B, C) -> Z -): ValidatedNel = - zip(Semigroup.nonEmptyList(), b, c, f) - -public inline fun ValidatedNel.zip( - b: ValidatedNel, - c: ValidatedNel, - d: ValidatedNel, - f: (A, B, C, D) -> Z -): ValidatedNel = - zip(Semigroup.nonEmptyList(), b, c, d, f) - -public inline fun ValidatedNel.zip( - b: ValidatedNel, - c: ValidatedNel, - d: ValidatedNel, - e: ValidatedNel, - f: (A, B, C, D, EE) -> Z -): ValidatedNel = - zip(Semigroup.nonEmptyList(), b, c, d, e, f) - -public inline fun ValidatedNel.zip( - b: ValidatedNel, - c: ValidatedNel, - d: ValidatedNel, - e: ValidatedNel, - ff: ValidatedNel, - f: (A, B, C, D, EE, FF) -> Z -): ValidatedNel = - zip(Semigroup.nonEmptyList(), b, c, d, e, ff, f) - -public inline fun ValidatedNel.zip( - b: ValidatedNel, - c: ValidatedNel, - d: ValidatedNel, - e: ValidatedNel, - ff: ValidatedNel, - g: ValidatedNel, - f: (A, B, C, D, EE, F, G) -> Z -): ValidatedNel = - zip(Semigroup.nonEmptyList(), b, c, d, e, ff, g, f) - -public inline fun ValidatedNel.zip( - b: ValidatedNel, - c: ValidatedNel, - d: ValidatedNel, - e: ValidatedNel, - ff: ValidatedNel, - g: ValidatedNel, - h: ValidatedNel, - f: (A, B, C, D, EE, F, G, H) -> Z -): ValidatedNel = - zip(Semigroup.nonEmptyList(), b, c, d, e, ff, g, h, f) - -public inline fun ValidatedNel.zip( - b: ValidatedNel, - c: ValidatedNel, - d: ValidatedNel, - e: ValidatedNel, - ff: ValidatedNel, - g: ValidatedNel, - h: ValidatedNel, - i: ValidatedNel, - f: (A, B, C, D, EE, F, G, H, I) -> Z -): ValidatedNel = - zip(Semigroup.nonEmptyList(), b, c, d, e, ff, g, h, i, f) - -public inline fun ValidatedNel.zip( - b: ValidatedNel, - c: ValidatedNel, - d: ValidatedNel, - e: ValidatedNel, - ff: ValidatedNel, - g: ValidatedNel, - h: ValidatedNel, - i: ValidatedNel, - j: ValidatedNel, - f: (A, B, C, D, EE, F, G, H, I, J) -> Z -): ValidatedNel = - zip(Semigroup.nonEmptyList(), b, c, d, e, ff, g, h, i, j, f) - -/** - * Given [A] is a sub type of [B], re-type this value from Validated to Validated - * - * ```kotlin - * import arrow.core.* - * - * fun main(args: Array) { - * //sampleStart - * val string: Validated = "Hello".valid() - * val chars: Validated = - * string.widen() - * //sampleEnd - * println(chars) - * } - * ``` - * - */ -public fun Validated.widen(): Validated = - this - -public fun Validated.leftWiden(): Validated = - this - -public fun Validated.replicate(SE: Semigroup, n: Int): Validated> = - if (n <= 0) emptyList().valid() - else this.zip(SE, replicate(SE, n - 1)) { a, xs -> listOf(a) + xs } - -public fun Validated.replicate(SE: Semigroup, n: Int, MA: Monoid): Validated = - if (n <= 0) MA.empty().valid() - else this@replicate.zip(SE, replicate(SE, n - 1, MA)) { a, xs -> MA.run { a + xs } } - -public fun Validated, Iterable>.bisequence(): List> = - bitraverse(::identity, ::identity) - -public fun Validated, Either>.bisequenceEither(): Either> = - bitraverseEither(::identity, ::identity) - -public fun Validated, Option>.bisequenceOption(): Option> = - bitraverseOption(::identity, ::identity) - -public fun Validated.bisequenceNullable(): Validated? = - bitraverseNullable(::identity, ::identity) - -public fun Validated.fold(MA: Monoid): A = MA.run { - foldLeft(empty()) { acc, a -> acc.combine(a) } -} - -@Deprecated("use fold instead", ReplaceWith("fold(MA)", "arrow.core.fold")) -public fun Validated.combineAll(MA: Monoid): A = - fold(MA) - -public fun Validated>.sequence(): List> = - traverse(::identity) - -@Deprecated("sequenceEither is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Validated>.sequenceEither(): Either> = - sequence() - -public fun Validated>.sequence(): Either> = - traverse(::identity) - -@Deprecated("sequenceOption is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Validated>.sequenceOption(): Option> = - sequence() - -public fun Validated>.sequence(): Option> = - traverse(::identity) - -@Deprecated("sequenceNullable is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Validated.sequenceNullable(): Validated? = - sequence() - -public fun Validated.sequence(): Validated? = - traverseNullable(::identity) - -public operator fun , A : Comparable> Validated.compareTo(other: Validated): Int = - fold( - { l1 -> other.fold({ l2 -> l1.compareTo(l2) }, { -1 }) }, - { r1 -> other.fold({ 1 }, { r2 -> r1.compareTo(r2) }) } - ) - -/** - * Return the Valid value, or the default if Invalid - */ -public inline fun Validated.getOrElse(default: () -> A): A = - fold({ default() }, ::identity) - -/** - * Return the Valid value, or null if Invalid - */ -public fun Validated.orNull(): A? = - getOrElse { null } - -public fun Validated.orNone(): Option = - fold({ None }, { Some(it) }) - -/** - * Return the Valid value, or the result of f if Invalid - */ -public inline fun Validated.valueOr(f: (E) -> A): A = - fold({ f(it) }, ::identity) - -/** - * If `this` is valid return `this`, otherwise if `that` is valid return `that`, otherwise combine the failures. - * This is similar to [orElse] except that here failures are accumulated. - */ -public inline fun Validated.findValid(SE: Semigroup, that: () -> Validated): Validated = - fold( - { e -> - that().fold( - { ee -> Invalid(SE.run { e.combine(ee) }) }, - { Valid(it) } - ) - }, - { Valid(it) } - ) - -/** - * Apply a function to a Valid value, returning a new Validation that may be valid or invalid - * - * Example: - * ```kotlin - * import arrow.core.Validated - * import arrow.core.andThen - * - * fun main() { - * Validated.Valid(5).andThen { Validated.Valid(10) } // Result: Valid(10) - * Validated.Valid(5).andThen { Validated.Invalid(10) } // Result: Invalid(10) - * Validated.Invalid(5).andThen { Validated.Valid(10) } // Result: Invalid(5) - * } - * ``` - * - */ -public inline fun Validated.andThen(f: (A) -> Validated): Validated = - when (this) { - is Validated.Valid -> f(value) - is Validated.Invalid -> this - } - -/** - * Return this if it is Valid, or else fall back to the given default. - * The functionality is similar to that of [findValid] except for failure accumulation, - * where here only the error on the right is preserved and the error on the left is ignored. - */ -public inline fun Validated.orElse(default: () -> Validated): Validated = - fold( - { default() }, - { Valid(it) } - ) - -public inline fun Validated.handleErrorWith(f: (E) -> Validated): Validated = - when (this) { - is Validated.Valid -> this - is Validated.Invalid -> f(this.value) - } - -public inline fun Validated.handleError(f: (E) -> A): Validated = - when (this) { - is Validated.Valid -> this - is Validated.Invalid -> Valid(f(this.value)) - } - -public inline fun Validated.redeem(fe: (E) -> B, fa: (A) -> B): Validated = - when (this) { - is Validated.Valid -> map(fa) - is Validated.Invalid -> Valid(fe(this.value)) - } - -public fun Validated.attempt(): Validated> = - map { Right(it) }.handleError { Left(it) } - -public inline fun Validated.merge(): A = - fold(::identity, ::identity) - -public fun Validated.combine( - SE: Semigroup, - SA: Semigroup, - y: Validated -): Validated = - when { - this is Valid && y is Valid -> Valid(SA.run { value.combine(y.value) }) - this is Invalid && y is Invalid -> Invalid(SE.run { value.combine(y.value) }) - this is Invalid -> this - else -> y - } - -public fun Validated.combineK(SE: Semigroup, y: Validated): Validated { - return when (this) { - is Valid -> this - is Invalid -> when (y) { - is Invalid -> Invalid(SE.run { this@combineK.value.combine(y.value) }) - is Valid -> y - } - } -} - -/** - * Converts the value to an Ior - */ -public fun Validated.toIor(): Ior = - fold({ Ior.Left(it) }, { Ior.Right(it) }) - -public inline fun A.valid(): Validated = - Valid(this) - -public inline fun E.invalid(): Validated = - Invalid(this) - -public inline fun A.validNel(): ValidatedNel = - Validated.validNel(this) - -public inline fun E.invalidNel(): ValidatedNel = - Validated.invalidNel(this) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/computations/either.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/computations/either.kt index ffeaccf5db9..4939b08d7ad 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/computations/either.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/computations/either.kt @@ -3,7 +3,6 @@ package arrow.core.computations import arrow.continuations.Effect import arrow.core.Either import arrow.core.Either.Left -import arrow.core.Validated import arrow.core.identity import arrow.core.left import arrow.core.right @@ -20,12 +19,6 @@ public fun interface EitherEffect : Effect> { is Left -> control().shift(this@bind) } - public suspend fun Validated.bind(): B = - when (this) { - is Validated.Valid -> value - is Validated.Invalid -> control().shift(Left(value)) - } - public suspend fun Result.bind(transform: (Throwable) -> E): B = fold(::identity) { throwable -> control().shift(transform(throwable).left()) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/computations/result.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/computations/result.kt index 68061797952..f2893377b91 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/computations/result.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/computations/result.kt @@ -1,7 +1,6 @@ package arrow.core.computations import arrow.core.Either -import arrow.core.Validated import arrow.core.identity /** @@ -18,43 +17,39 @@ public object ResultEffect { public fun Either.bind(): A = fold({ throw it }, ::identity) - @Deprecated("$deprecatedInFavorOfEagerEffectScope\nThis object introduces dangerous behavior and will be removed in the next version: https://github.com/arrow-kt/arrow/issues/2547") - public fun Validated.bind(): A = - fold({ throw it }, ::identity) -} - -@Deprecated(deprecateInFavorOfEffectOrEagerEffect, ReplaceWith("result", "arrow.core.continuations.result")) -@Suppress("ClassName") -public object result { + @Deprecated(deprecateInFavorOfEffectOrEagerEffect, ReplaceWith("result", "arrow.core.continuations.result")) + @Suppress("ClassName") + public object result { - /** - * Provides a computation block for [Result] which is build on top of Kotlin's Result Std operations. - * - * ```kotlin - * import arrow.core.* - * import arrow.core.computations.result - * - * fun main() { - * result { // We can safely use assertion based operation inside blocks - * kotlin.require(false) { "Boom" } - * } // Result.Failure(IllegalArgumentException("Boom")) - * - * result { - * Result.failure(RuntimeException("Boom")) - * .recover { 1 } - * .bind() - * } // Result.Success(1) - * - * result { - * val x = Result.success(1).bind() - * val y = Result.success(x + 1).bind() - * x + y - * } // Result.Success(3) - * } - * ``` - * - */ - @Deprecated(deprecateInFavorOfEffect, ReplaceWith("result.eager(block)", "arrow.core.continuations.result")) - public inline operator fun invoke(block: ResultEffect.() -> A): Result = - kotlin.runCatching { block(ResultEffect) } + /** + * Provides a computation block for [Result] which is build on top of Kotlin's Result Std operations. + * + * ```kotlin + * import arrow.core.* + * import arrow.core.computations.ResultEffect.result + * + * fun main() { + * result { // We can safely use assertion based operation inside blocks + * kotlin.require(false) { "Boom" } + * } // Result.Failure(IllegalArgumentException("Boom")) + * + * result { + * Result.failure(RuntimeException("Boom")) + * .recover { 1 } + * .bind() + * } // Result.Success(1) + * + * result { + * val x = Result.success(1).bind() + * val y = Result.success(x + 1).bind() + * x + y + * } // Result.Success(3) + * } + * ``` + * + */ + @Deprecated(deprecateInFavorOfEffect, ReplaceWith("result.eager(block)", "arrow.core.continuations.result")) + public inline operator fun invoke(block: ResultEffect.() -> A): Result = + kotlin.runCatching { block(ResultEffect) } + } } diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffect.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffect.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Effect.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Effect.kt index 3130b5cd28c..915179cc561 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Effect.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Effect.kt @@ -21,7 +21,7 @@ import kotlin.jvm.JvmMultifileClass * [Structured Concurrency](#structured-concurrency) * [Arrow Fx Coroutines](#arrow-fx-coroutines) * [parZip](#parzip) - * [parTraverse](#partraverse) + * [parMap](#parmap) * [raceN](#racen) * [bracketCase / Resource](#bracketcase--resource) * [KotlinX](#kotlinx) @@ -78,12 +78,10 @@ import kotlin.jvm.JvmMultifileClass * import arrow.core.Either * import arrow.core.Ior * import arrow.core.None - * import arrow.core.Validated * import arrow.core.continuations.Effect * import arrow.core.continuations.effect * import arrow.core.continuations.fold * import arrow.core.continuations.toEither - * import arrow.core.continuations.toValidated * import arrow.core.continuations.toIor * import arrow.core.continuations.toOption * import arrow.core.continuations.ensureNotNull @@ -134,7 +132,6 @@ import kotlin.jvm.JvmMultifileClass * ```kotlin * suspend fun main() { * readFile("").toEither() shouldBe Either.Left(EmptyPath) - * readFile("knit.properties").toValidated() shouldBe Validated.Invalid(FileNotFound("knit.properties")) * readFile("gradle.properties").toIor() shouldBe Ior.Left(FileNotFound("gradle.properties")) * readFile("README.MD").toOption { None } shouldBe None * @@ -362,7 +359,7 @@ import kotlin.jvm.JvmMultifileClass * ``` * * - * #### parTraverse + * #### parMap * * - * `parTraverse` will launch 5 tasks, for every element in `1..5`. + * `parMap` will launch 5 tasks, for every element in `1..5`. * The last task to get scheduled will `raise` with "error", and it will cancel the other launched tasks before returning. * * #### raceN diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Mappers.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Mappers.kt index 19bd59d0fd9..3d816c315dd 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Mappers.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Mappers.kt @@ -8,7 +8,6 @@ import arrow.core.Ior import arrow.core.None import arrow.core.Option import arrow.core.Some -import arrow.core.Validated import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmName @@ -16,10 +15,6 @@ import kotlin.jvm.JvmName public suspend fun Effect.toEither(): Either = either { invoke() } public fun EagerEffect.toEither(): Either = either { invoke() } -/** Run the [Effect] by returning [Validated.Valid] of [A], or [Validated.Invalid] of [E]. */ -public suspend fun Effect.toValidated(): Validated = fold({ Validated.Invalid(it) }) { Validated.Valid(it) } -public fun EagerEffect.toValidated(): Validated = fold({ Validated.Invalid(it) }) { Validated.Valid(it) } - /** Run the [Effect] by returning [Ior.Right] of [A], or [Ior.Left] of [E]. */ public suspend fun Effect.toIor(): Ior = fold({ Ior.Left(it) }) { Ior.Right(it) } public fun EagerEffect.toIor(): Ior = fold({ Ior.Left(it) }) { Ior.Right(it) } diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Raise.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Raise.kt index e72e8e5df3b..999d6f995d6 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Raise.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Raise.kt @@ -6,7 +6,6 @@ import arrow.core.Either import arrow.core.None import arrow.core.Option import arrow.core.Some -import arrow.core.Validated import arrow.core.identity import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract @@ -106,12 +105,6 @@ public interface Raise { is Either.Right -> value } - /* Will be removed in subsequent PRs for Arrow 2.x.x */ - public fun Validated.bind(): A = when (this) { - is Validated.Invalid -> raise(value) - is Validated.Valid -> value - } - /** * Extract the [Result.success] value out of [Result], * because [Result] works with [Throwable] as its error type you need to [transform] [Throwable] to [R]. diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/map.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/map.kt index 1265ec598c6..2dadbc549a7 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/map.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/map.kt @@ -1,10 +1,7 @@ package arrow.core -import arrow.core.Either.Left -import arrow.core.Either.Right import arrow.typeclasses.Monoid import arrow.typeclasses.Semigroup -import kotlin.experimental.ExperimentalTypeInference import kotlin.collections.flatMap as _flatMap /** @@ -235,85 +232,6 @@ public fun Map.flatMap(f: (Map.Entry) -> Map): Map Map.traverse(f: (A) -> Either): Either> { - val acc = mutableMapOf() - forEach { (k, v) -> - when (val res = f(v)) { - is Right -> acc[k] = res.value - is Left -> return@traverse res - } - } - return acc.right() -} - -@Deprecated("traverseEither is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse")) -public inline fun Map.traverseEither(f: (A) -> Either): Either> = - traverse(f) - -public fun Map>.sequence(): Either> = - traverse(::identity) - -@Deprecated("sequenceEither is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Map>.sequenceEither(): Either> = - sequence() - -@Deprecated("traverseValidated is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(semigroup, f)", "arrow.core.traverse")) -public inline fun Map.traverseValidated( - semigroup: Semigroup, - f: (A) -> Validated -): Validated> = - traverse(semigroup, f) - -public inline fun Map.traverse( - semigroup: Semigroup, - f: (A) -> Validated -): Validated> = - foldLeft(mutableMapOf().valid() as Validated>) { acc, (k, v) -> - when (val res = f(v)) { - is Valid -> when (acc) { - is Valid -> acc.also { it.value[k] = res.value } - is Invalid -> acc - } - is Invalid -> when (acc) { - is Valid -> res - is Invalid -> semigroup.run { acc.value.combine(res.value).invalid() } - } - } - } - -@Deprecated("sequenceValidated is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence(semigroup)", "arrow.core.sequence")) -public fun Map>.sequenceValidated(semigroup: Semigroup): Validated> = - sequence(semigroup) - -public fun Map>.sequence(semigroup: Semigroup): Validated> = - traverse(semigroup, ::identity) - -@OptIn(ExperimentalTypeInference::class) -@OverloadResolutionByLambdaReturnType -public inline fun Map.traverse(f: (A) -> Option): Option> { - val acc = mutableMapOf() - forEach { (k, v) -> - when (val res = f(v)) { - is Some -> acc[k] = res.value - is None -> return@traverse res - } - } - return acc.some() -} - -@Deprecated("traverseOption is being renamed to traverse to simplify the Arrow API", ReplaceWith("traverse(f)", "arrow.core.traverse")) -public inline fun Map.traverseOption(f: (A) -> Option): Option> = - traverse(f) - -@Deprecated("sequenceOption is being renamed to sequence to simplify the Arrow API", ReplaceWith("sequence()", "arrow.core.sequence")) -public fun Map>.sequenceOption(): Option> = - sequence() - -public fun Map>.sequence(): Option> = - traverse(::identity) - public fun Map.void(): Map = mapValues { Unit } diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/predef.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/predef.kt index dfb8be55ccc..f1f1ceb2a6e 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/predef.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/predef.kt @@ -13,8 +13,11 @@ public inline fun identity(a: A): A = a @PublishedApi internal object EmptyValue { @Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE") - public inline fun unbox(value: Any?): A = + inline fun unbox(value: Any?): A = if (value === this) null as A else value as A + + inline fun combine(first: Any?, second: T, s: Semigroup): T = + if (first === EmptyValue) second else s.append(first as T, second) } /** @@ -22,4 +25,5 @@ internal object EmptyValue { */ @PublishedApi internal fun Semigroup.emptyCombine(first: Any?, second: T): T = - if (first == EmptyValue) second else (first as T).combine(second) + if (first === EmptyValue) second else (first as T).combine(second) + diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/typeclasses/Monoid.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/typeclasses/Monoid.kt index 6b88f4152c7..f875cf919e1 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/typeclasses/Monoid.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/typeclasses/Monoid.kt @@ -5,7 +5,6 @@ import arrow.core.Either import arrow.core.Endo import arrow.core.None import arrow.core.Option -import arrow.core.Validated import arrow.core.combine import arrow.core.compose import arrow.core.flatten @@ -83,7 +82,7 @@ public interface Monoid : Semigroup { public fun endo(): Monoid> = object : Monoid> { override fun empty(): Endo = Endo(::identity) - override fun Endo.combine(g: Endo): Endo = Endo(f.compose(g.f)) + override fun append(a: Endo, b: Endo): Endo = Endo(a.f.compose(b.f)) } @JvmStatic @@ -91,7 +90,8 @@ public interface Monoid : Semigroup { public fun const(MA: Monoid): Monoid> = object : Monoid> { override fun empty(): Const = Const(MA.empty()) - override fun Const.combine(b: Const): Const = this.combine(MA, b) + override fun append(a: Const, b: Const): Const = + a.combine(MA, b) } @JvmStatic @@ -102,31 +102,17 @@ public interface Monoid : Semigroup { public fun option(MA: Semigroup): Monoid> = OptionMonoid(MA) - @JvmStatic - public fun validated(SE: Semigroup, MA: Monoid): Monoid> = - ValidatedMonoid(SE, MA) - @JvmStatic public fun pair(MA: Monoid, MB: Monoid): Monoid> = PairMonoid(MA, MB) - private class ValidatedMonoid( - private val SA: Semigroup, - private val MB: Monoid - ) : Monoid> { - private val empty = Validated.Valid(MB.empty()) - override fun empty(): Validated = empty - override fun Validated.combine(b: Validated): Validated = - combine(SA, MB, b) - } - private class OptionMonoid( private val MA: Semigroup ) : Monoid> { - - override fun Option.combine(b: Option): Option = - combine(MA, b) - + + override fun append(a: Option, b: Option): Option = + a.combine(MA, b) + override fun Option.maybeCombine(b: Option?): Option = b?.let { combine(MA, it) } ?: this @@ -135,59 +121,59 @@ public interface Monoid : Semigroup { private class MapMonoid(private val SG: Semigroup) : Monoid> { override fun empty(): Map = emptyMap() - - override fun Map.combine(b: Map): Map = - combine(SG, b) + + override fun append(a: Map, b: Map): Map = + a.combine(SG, b) } private object AndMonoid : Monoid { - override fun Boolean.combine(b: Boolean): Boolean = this && b + override fun append(a: Boolean, b: Boolean): Boolean = a && b override fun empty(): Boolean = true } private object ByteMonoid : Monoid { override fun empty(): Byte = 0 - override fun Byte.combine(b: Byte): Byte = (this + b).toByte() + override fun append(a: Byte, b: Byte): Byte = (a + b).toByte() } private object DoubleMonoid : Monoid { override fun empty(): Double = .0 - override fun Double.combine(b: Double): Double = this + b + override fun append(a: Double, b: Double): Double = a + b } private object IntMonoid : Monoid { override fun empty(): Int = 0 - override fun Int.combine(b: Int): Int = this + b + override fun append(a: Int, b: Int): Int = a + b } private object LongMonoid : Monoid { override fun empty(): Long = 0L - override fun Long.combine(b: Long): Long = this + b + override fun append(a: Long, b: Long): Long = a + b } private object ShortMonoid : Monoid { override fun empty(): Short = 0 - override fun Short.combine(b: Short): Short = (this + b).toShort() + override fun append(a: Short, b: Short): Short = (a + b).toShort() } private object FloatMonoid : Monoid { override fun empty(): Float = 0f - override fun Float.combine(b: Float): Float = this + b + override fun append(a: Float, b: Float): Float = a + b } private object StringMonoid : Monoid { - override fun String.combine(b: String): String = "${this}$b" + override fun append(a: String, b: String): String = "${a}$b" override fun empty(): String = "" } private object ListMonoid : Monoid> { override fun empty(): List = emptyList() - override fun List.combine(b: List): List = this._plus(b) + override fun append(a: List, b: List): List = a._plus(b) } private object SequenceMonoid : Monoid> { override fun empty(): Sequence = emptySequence() - override fun Sequence.combine(b: Sequence): Sequence = sequenceOf(this, b).flatten() + override fun append(a: Sequence, b: Sequence): Sequence = sequenceOf(a, b).flatten() } private class EitherMonoid( @@ -195,9 +181,9 @@ public interface Monoid : Semigroup { private val MOR: Monoid ) : Monoid> { override fun empty(): Either = Either.Right(MOR.empty()) - - override fun Either.combine(b: Either): Either = - combine(SGOL, MOR, b) + + override fun append(a: Either, b: Either): Either = + a.combine(SGOL, MOR, b) override fun Collection>.fold(): Either = fold(either(SGOL, MOR)) @@ -214,7 +200,8 @@ public interface Monoid : Semigroup { private val MB: Monoid ) : Monoid> { override fun empty(): Pair = Pair(MA.empty(), MB.empty()) - override fun Pair.combine(b: Pair): Pair = combine(MA, MB, b) + override fun append(a: Pair, b: Pair): Pair = + a.combine(MA, MB, b) } } } diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/typeclasses/Semigroup.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/typeclasses/Semigroup.kt index 2de78ae1f4d..dbaa26d1c72 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/typeclasses/Semigroup.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/typeclasses/Semigroup.kt @@ -6,23 +6,27 @@ import arrow.core.Endo import arrow.core.Ior import arrow.core.NonEmptyList import arrow.core.Option -import arrow.core.Validated import arrow.core.combine import arrow.core.compose import kotlin.jvm.JvmName import kotlin.jvm.JvmStatic public fun interface Semigroup { + + // TODO: think of better name + public fun append(a: A, b: A): A + /** * Combine two [A] values. */ - public fun A.combine(b: A): A + public fun A.combine(b: A): A = + append(this, b) public operator fun A.plus(b: A): A = - this.combine(b) + append(this, b) public fun A.maybeCombine(b: A?): A = - b?.let { combine(it) } ?: this + b?.let { append(this, it) } ?: this public companion object { @JvmStatic @@ -64,17 +68,12 @@ public fun interface Semigroup { @JvmStatic public fun endo(): Semigroup> = - object : Semigroup> { - override fun Endo.combine(g: Endo): Endo = Endo(f.compose(g.f)) - } + Semigroup { f, g -> Endo(f.f.compose(g.f)) } @JvmStatic @JvmName("constant") public fun const(SA: Semigroup): Semigroup> = - object : Semigroup> { - override fun Const.combine(b: Const): Const = - this.combine(SA, b) - } + Semigroup { a, b -> a.combine(SA, b) } @JvmStatic public fun map(SG: Semigroup): Semigroup> = @@ -84,10 +83,6 @@ public fun interface Semigroup { public fun option(SGA: Semigroup): Semigroup> = OptionSemigroup(SGA) - @JvmStatic - public fun validated(SE: Semigroup, SA: Semigroup): Semigroup> = - ValidatedSemigroup(SE, SA) - @Suppress("UNCHECKED_CAST") @JvmStatic public fun nonEmptyList(): Semigroup> = @@ -101,36 +96,28 @@ public fun interface Semigroup { private val SA: Semigroup, private val SB: Semigroup ) : Semigroup> { - override fun Pair.combine(b: Pair): Pair = combine(SA, SB, b) + override fun append(a: Pair, b: Pair): Pair = a.combine(SA, SB, b) } public object NonEmptyListSemigroup : Semigroup> { - override fun NonEmptyList.combine(b: NonEmptyList): NonEmptyList = - NonEmptyList(this.head, this.tail.plus(b)) - } - - private open class ValidatedSemigroup( - private val SA: Semigroup, - private val SB: Semigroup - ) : Semigroup> { - override fun Validated.combine(b: Validated): Validated = - combine(SA, SB, b) + override fun append(a: NonEmptyList, b: NonEmptyList): NonEmptyList = + NonEmptyList(a.head, a.tail.plus(b)) } private class OptionSemigroup( private val SGA: Semigroup ) : Semigroup> { - override fun Option.combine(b: Option): Option = - combine(SGA, b) + override fun append(a: Option, b: Option): Option = + a.combine(SGA, b) override fun Option.maybeCombine(b: Option?): Option = b?.let { combine(SGA, it) } ?: this } private class MapSemigroup(private val SG: Semigroup) : Semigroup> { - override fun Map.combine(b: Map): Map = - combine(SG, b) + override fun append(a: Map, b: Map): Map = + a.combine(SG, b) } private open class EitherSemigroup( @@ -138,8 +125,8 @@ public fun interface Semigroup { private val SGR: Semigroup ) : Semigroup> { - override fun Either.combine(b: Either): Either = - combine(SGL, SGR, b) + override fun append(a: Either, b: Either): Either = + a.combine(SGL, SGR, b) override fun Either.maybeCombine(b: Either?): Either = b?.let { combine(SGL, SGR, it) } ?: this @@ -150,8 +137,8 @@ public fun interface Semigroup { private val SGB: Semigroup ) : Semigroup> { - override fun Ior.combine(b: Ior): Ior = - combine(SGA, SGB, b) + override fun append(a: Ior, b: Ior): Ior = + a.combine(SGA, SGB, b) override fun Ior.maybeCombine(b: Ior?): Ior = b?.let { combine(SGA, SGB, it) } ?: this 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 9c2c6b3b472..6665f030415 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 @@ -12,6 +12,7 @@ import arrow.core.test.generators.suspendFunThatReturnsEitherAnyOrAnyOrThrows import arrow.core.test.generators.suspendFunThatThrows import arrow.core.test.laws.MonoidLaws import arrow.typeclasses.Monoid +import arrow.typeclasses.Semigroup import io.kotest.assertions.fail import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.shouldBe @@ -321,8 +322,6 @@ class EitherTest : UnitSpec() { val expected: Either> = Right(emptyList()) Right(a).replicate(n) shouldBe expected - - Left(a).replicate(n) shouldBe expected } } @@ -337,18 +336,6 @@ class EitherTest : UnitSpec() { } } - "traverse should return list of Right when Right and empty list when Left" { - checkAll( - Arb.int(), - Arb.int(), - Arb.int() - ) { a: Int, b: Int, c: Int -> - Right(a).traverse { emptyList() } shouldBe emptyList() - Right(a).traverse { listOf(b, c) } shouldBe listOf(Right(b), Right(c)) - Left(a).traverse { listOf(b, c) } shouldBe emptyList() - } - } - "flatMap should map right instance only" { checkAll(Arb.intSmall(), Arb.intSmall()) { a, b -> val right: Either = Right(a) @@ -458,129 +445,6 @@ class EitherTest : UnitSpec() { } } } - - "traverse should return list if either is right" { - val right: Either = Right(1) - val left: Either = Left("foo") - - right.traverse { listOf(it, 2, 3) } shouldBe listOf(Right(1), Right(2), Right(3)) - left.traverse { listOf(it, 2, 3) } shouldBe emptyList() - } - - "sequence should be consistent with traverse" { - checkAll(Arb.either(Arb.string(), Arb.int())) { either -> - either.map { listOf(it) }.sequence() shouldBe either.traverse { listOf(it) } - } - } - - "traverseNullable should return non-nullable if either is right" { - val right: Either = Right(1) - val left: Either = Left("foo") - - right.traverseNullable { it } shouldBe Right(1) - right.traverseNullable { null } shouldBe null - left.traverseNullable { it } shouldBe null - } - - "sequence for Nullable should be consistent with traverseNullable" { - checkAll(Arb.either(Arb.string(), Arb.int())) { either -> - either.map { it }.sequence() shouldBe either.traverseNullable { it } - either.map { null }.sequence() shouldBe null - } - } - - "traverse for Option should return option if either is right" { - val right: Either = Right(1) - val left: Either = Left("foo") - - right.traverse { Some(it) } shouldBe Some(Right(1)) - left.traverse { Some(it) } shouldBe None - } - - "sequence for Option should be consistent with traverseOption" { - checkAll(Arb.either(Arb.string(), Arb.int())) { either -> - either.map { Some(it) }.sequence() shouldBe either.traverse { Some(it) } - } - } - - "traverse for Validated should return validated of either" { - val right: Either = Right(1) - val left: Either = Left("foo") - - right.traverse { it.valid() } shouldBe Valid(Right(1)) - left.traverse { it.valid() } shouldBe Valid(Left("foo")) - } - - "sequence for Validated should be consistent with traverseValidated" { - checkAll(Arb.either(Arb.string(), Arb.int())) { either -> - either.map { it.valid() }.sequence() shouldBe either.traverse { it.valid() } - } - } - - "bitraverse should wrap either in a list" { - val right: Either = Right(1) - val left: Either = Left("foo") - - right.bitraverse({ listOf(it, "bar", "baz") }, { listOf(it, 2, 3) }) shouldBe listOf(Right(1), Right(2), Right(3)) - left.bitraverse({ listOf(it, "bar", "baz") }, { listOf(it, 2, 3) }) shouldBe - listOf(Left("foo"), Left("bar"), Left("baz")) - } - - "bisequence should be consistent with bitraverse" { - checkAll(Arb.either(Arb.string(), Arb.int())) { either -> - either.bimap({ listOf(it) }, { listOf(it) }).bisequence() shouldBe either.bitraverse( - { listOf(it) }, - { listOf(it) }) - } - } - - "bitraverseNullable should wrap either in a nullable" { - val right: Either = Right(1) - val left: Either = Left("foo") - - right.bitraverseNullable({ it }, { it.toString() }) shouldBe Right("1") - left.bitraverseNullable({ it }, { it.toString() }) shouldBe Left("foo") - - right.bitraverseNullable({ it }, { null }) shouldBe null - left.bitraverseNullable({ null }, { it.toString() }) shouldBe null - } - - "bisequenceNullable should be consistent with bitraverseNullable" { - checkAll(Arb.either(Arb.string(), Arb.int())) { either -> - either.bimap({ it }, { it }).bisequenceNullable() shouldBe - either.bitraverseNullable({ it }, { it }) - } - } - - "bitraverseOption should wrap either in an option" { - val right: Either = Right(1) - val left: Either = Left("foo") - - right.bitraverseOption({ Some(it) }, { Some(it.toString()) }) shouldBe Some(Right("1")) - left.bitraverseOption({ Some(it) }, { Some(it.toString()) }) shouldBe Some(Left("foo")) - } - - "bisequenceOption should be consistent with bitraverseOption" { - checkAll(Arb.either(Arb.string(), Arb.int())) { either -> - either.bimap({ Some(it) }, { Some(it) }).bisequenceOption() shouldBe - either.bitraverseOption({ Some(it) }, { Some(it) }) - } - } - - "bitraverseValidated should return validated of either" { - val right: Either = Right(1) - val left: Either = Left("foo") - - right.bitraverseValidated({ it.invalid() }, { it.valid() }) shouldBe Valid(Right(1)) - left.bitraverseValidated({ it.invalid() }, { it.valid() }) shouldBe Invalid("foo") - } - - "bisequenceValidated should be consistent with bitraverseValidated" { - checkAll(Arb.either(Arb.string(), Arb.int())) { either -> - either.bimap({ it.invalid() }, { it.valid() }).bisequenceValidated() shouldBe - either.bitraverseValidated({ it.invalid() }, { it.valid() }) - } - } } } diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherZipTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherZipTest.kt new file mode 100644 index 00000000000..1c2f4b29367 --- /dev/null +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherZipTest.kt @@ -0,0 +1,117 @@ +package arrow.core + +import arrow.core.test.generators.either +import arrow.typeclasses.Semigroup +import io.kotest.core.spec.style.StringSpec +import io.kotest.matchers.shouldBe +import io.kotest.property.Arb +import io.kotest.property.arbitrary.boolean +import io.kotest.property.arbitrary.byte +import io.kotest.property.arbitrary.char +import io.kotest.property.arbitrary.double +import io.kotest.property.arbitrary.float +import io.kotest.property.arbitrary.int +import io.kotest.property.arbitrary.list +import io.kotest.property.arbitrary.long +import io.kotest.property.arbitrary.map +import io.kotest.property.arbitrary.short +import io.kotest.property.arbitrary.string +import io.kotest.property.checkAll + +class EitherZipTest : StringSpec({ + "zip results in all Right transformed, or all Left combined according to combine" { + 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()), + Arb.either(Arb.string(), Arb.boolean()) + ) { a, b, c, d, e, f, g, h, i, j -> + val res = a.zip({ e1, e2 -> "$e1$e2" }, b, c, d, e, f, g, h, i, j, ::Tuple10) + val all = listOf(a, b, c, d, e, f, g, h, i, j) + + val expected = if (all.any { it.isLeft() }) { + all.filterIsInstance>().fold("") { acc, t -> "$acc${t.value}" }.left() + } else { + all.filterIsInstance>().map { it.value }.let { + Tuple10(it[0], it[1], it[2], it[3], it[4], it[5], it[6], it[7], it[8], it[9]).right() + } + } + + res shouldBe expected + } + } + + "zip 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()), + Arb.either(Arb.string(), Arb.boolean()) + ) { a, b, c, d, e, f, g, h, i, j -> + val res = a.zip(b, c, d, e, f, g, h, i, j, ::Tuple10) + val all = listOf(a, b, c, d, e, f, g, h, i, j) + + val expected = if (all.any { it.isLeft() }) { + all.filterIsInstance>().map { it.value }.toNonEmptyListOrNull()!!.left() + } else { + all.filterIsInstance>().map { it.value }.let { + Tuple10(it[0], it[1], it[2], it[3], it[4], it[5], it[6], it[7], it[8], it[9]).right() + } + } + + res shouldBe expected + } + } + + "zipping 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.nonEmptyList(Arb.string()), Arb.long()), + Arb.either(Arb.nonEmptyList(Arb.string()), Arb.float()), + Arb.either(Arb.nonEmptyList(Arb.string()), Arb.double()), + Arb.either(Arb.nonEmptyList(Arb.string()), Arb.char()), + Arb.either(Arb.nonEmptyList(Arb.string()), Arb.string()), + Arb.either(Arb.nonEmptyList(Arb.string()), Arb.boolean()), + Arb.either(Arb.nonEmptyList(Arb.string()), Arb.boolean()) + ) { a, b, c, d, e, f, g, h, i, j -> + val res = a.zip(b, c, d, e, f, g, h, i, j, ::Tuple10) + val all = listOf(a, b, c, d, e, f, g, h, i, j) + + val expected = if (all.any { it.isLeft() }) { + all.filterIsInstance>>() + .flatMap { it.value } + .toNonEmptyListOrNull()!!.left() + } else { + all.filterIsInstance>().map { it.value }.let { + Tuple10(it[0], it[1], it[2], it[3], it[4], it[5], it[6], it[7], it[8], it[9]).right() + } + } + + res shouldBe expected + } + } + + "Can use Semigroup as combine function" { + Either.Left(10).zip( + Semigroup.int(), + Either.Right(5) + ) { a, b -> a + b } shouldBe Either.Left(10) + } +}) \ No newline at end of file diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IorTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IorTest.kt index 4b83bc15750..70d25d9c74b 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IorTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IorTest.kt @@ -23,10 +23,8 @@ class IorTest : UnitSpec() { SemigroupLaws.laws(Semigroup.ior(Semigroup.string(), Semigroup.int()), ARB) ) - val nullableLongSemigroup = object : Semigroup { - override fun Long?.combine(b: Long?): Long? = - Nullable.zip(this, b) { a, bb -> a + bb } - } + val nullableLongSemigroup = + Semigroup { a, b -> Nullable.zip(a, b) { aa, bb -> aa + bb } } "zip identity" { checkAll(Arb.ior(Arb.long().orNull(), Arb.int().orNull())) { ior -> @@ -153,14 +151,6 @@ class IorTest : UnitSpec() { } } - "toValidated() should convert values into a valid Validated" { - checkAll(Arb.int(), Arb.string()) { a: Int, b: String -> - Ior.Left(a).toValidated() shouldBe Invalid(a) - Ior.Right(b).toValidated() shouldBe Valid(b) - Ior.Both(a, b).toValidated() shouldBe Valid(b) - } - } - "fromNullables() should build a correct Ior" { checkAll(Arb.int(), Arb.string()) { a: Int, b: String -> Ior.fromNullables(a, null) shouldBe Ior.Left(a) @@ -202,139 +192,5 @@ class IorTest : UnitSpec() { } } - "traverse should wrap ior in a list" { - checkAll(Arb.int(), Arb.string()) { a: Int, b: String -> - val iorL: Ior = a.leftIor() - val iorR: Ior = b.rightIor() - val iorBoth: Ior = (a to b).bothIor() - - iorL.traverse { listOf(it) } shouldBe listOf(Ior.Left(a)) - iorR.traverse { listOf(it) } shouldBe listOf(Ior.Right(b)) - iorBoth.traverse { listOf(it) } shouldBe listOf(Ior.Both(a, b)) - } - } - - "sequence should be consistent with traverse" { - checkAll(Arb.ior(Arb.int(), Arb.string())) { ior -> - ior.map { listOf(it) }.sequence() shouldBe ior.traverse { listOf(it) } - } - } - - "traverseNullable should wrap ior in a nullable" { - checkAll(Arb.int(), Arb.string()) { a: Int, b: String -> - val iorL: Ior = a.leftIor() - val iorR: Ior = b.rightIor() - val iorBoth: Ior = (a to b).bothIor() - - iorL.traverseNullable { it } shouldBe Ior.Left(a) - iorR.traverseNullable { it } shouldBe Ior.Right(b) - iorBoth.traverseNullable { it } shouldBe Ior.Both(a, b) - - iorL.traverseNullable { null } shouldBe Ior.Left(a) - iorR.traverseNullable { null } shouldBe null - iorBoth.traverseNullable { null } shouldBe null - } - } - - "sequence for Nullable should be consistent with traverseNullable" { - checkAll(Arb.ior(Arb.int(), Arb.string())) { ior -> - ior.map { it }.sequence() shouldBe ior.traverseNullable { it } - ior.map { null }.sequence() shouldBe ior.traverseNullable { null } - } - } - - "traverseOption should wrap ior in an Option" { - checkAll(Arb.int(), Arb.string()) { a: Int, b: String -> - val iorL: Ior = a.leftIor() - val iorR: Ior = b.rightIor() - val iorBoth: Ior = (a to b).bothIor() - - iorL.traverse { Some(it) } shouldBe Some(Ior.Left(a)) - iorR.traverse { Some(it) } shouldBe Some(Ior.Right(b)) - iorBoth.traverse { Some(it) } shouldBe Some(Ior.Both(a, b)) - } - } - - "sequenceOption should be consistent with traverseOption" { - checkAll(Arb.ior(Arb.int(), Arb.string())) { ior -> - ior.map { Some(it) }.sequence() shouldBe ior.traverse { Some(it) } - } - } - - "traverseEither should wrap ior in an Option" { - checkAll(Arb.int(), Arb.string()) { a: Int, b: String -> - val iorL: Ior = a.leftIor() - val iorR: Ior = b.rightIor() - val iorBoth: Ior = (a to b).bothIor() - - iorL.traverse { it.right() } shouldBe Either.Right(Ior.Left(a)) - iorR.traverse { it.right() } shouldBe Either.Right(Ior.Right(b)) - iorBoth.traverse { it.right() } shouldBe Either.Right(Ior.Both(a, b)) - } - } - - "sequenceEither should be consistent with traverseEither" { - checkAll(Arb.ior(Arb.int(), Arb.string())) { ior -> - ior.map { it.right() }.sequence() shouldBe ior.traverse { it.right() } - } - } - - "bitraverse should wrap ior in a list" { - checkAll(Arb.int(), Arb.string()) { a: Int, b: String -> - val iorL: Ior = a.leftIor() - val iorR: Ior = b.rightIor() - val iorBoth: Ior = (a to b).bothIor() - - iorL.bitraverse({ listOf(it, 2, 3) }, { listOf(it) }) shouldBe listOf(Ior.Left(a), Ior.Left(2), Ior.Left(3)) - iorR.bitraverse({ listOf(it, 2, 3) }, { listOf(it) }) shouldBe listOf(Ior.Right(b)) - iorBoth.bitraverse({ listOf(it, 2, 3) }, { listOf(it, 4, 5) }) shouldBe - listOf(Ior.Both(a, b), Ior.Both(2, 4), Ior.Both(3, 5)) - } - } - - "bisequence should be consistent with bitraverse" { - checkAll(Arb.ior(Arb.int(), Arb.string())) { ior -> - ior.bimap({ listOf(it) }, { listOf(it) }).bisequence() shouldBe - ior.bitraverse({ listOf(it) }, { listOf(it) }) - } - } - - "bitraverseOption should wrap ior in an Option" { - checkAll(Arb.int(), Arb.string()) { a: Int, b: String -> - val iorL: Ior = a.leftIor() - val iorR: Ior = b.rightIor() - val iorBoth: Ior = (a to b).bothIor() - - iorL.bitraverseOption({ None }, { Some(it) }) shouldBe None - iorR.bitraverseOption({ None }, { Some(it) }) shouldBe Some(Ior.Right(b)) - iorBoth.bitraverseOption({ None }, { Some(it) }) shouldBe None - } - } - - "bisequenceOption should be consistent with bitraverseOption" { - checkAll(Arb.ior(Arb.int(), Arb.string())) { ior -> - ior.bimap({ None }, { Some(it) }).bisequenceOption() shouldBe - ior.bitraverseOption({ None }, { Some(it) }) - } - } - - "bitraverseEither should wrap ior in an Either" { - checkAll(Arb.int(), Arb.string()) { a: Int, b: String -> - val iorL: Ior = a.leftIor() - val iorR: Ior = b.rightIor() - val iorBoth: Ior = (a to b).bothIor() - - iorL.bitraverseEither({ it.left() }, { it.right() }) shouldBe Either.Left(a) - iorR.bitraverseEither({ it.left() }, { it.right() }) shouldBe Either.Right(Ior.Right(b)) - iorBoth.bitraverseEither({ it.left() }, { it.right() }) shouldBe Either.Left(a) - } - } - - "bisequenceEither should be consistent with bitraverseEither" { - checkAll(Arb.ior(Arb.int(), Arb.string())) { ior -> - ior.bimap({ it.left() }, { it.right() }).bisequenceEither() shouldBe - ior.bitraverseEither({ it.left() }, { it.right() }) - } - } } } diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt index 02b1d88edd3..5e6b43c3a19 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/IterableTest.kt @@ -1,229 +1,43 @@ package arrow.core import arrow.core.test.UnitSpec -import arrow.core.test.generators.either -import arrow.core.test.generators.functionAToB import arrow.core.test.generators.option import arrow.typeclasses.Semigroup -import io.kotest.matchers.collections.shouldBeEmpty -import io.kotest.matchers.collections.shouldContainExactly -import io.kotest.matchers.nulls.shouldBeNull -import io.kotest.matchers.nulls.shouldNotBeNull -import io.kotest.matchers.should -import io.kotest.property.Arb import io.kotest.matchers.shouldBe +import io.kotest.property.Arb import io.kotest.property.arbitrary.boolean import io.kotest.property.arbitrary.int -import io.kotest.property.arbitrary.orNull -import io.kotest.property.arbitrary.string import kotlin.math.max import kotlin.math.min class IterableTest : UnitSpec() { init { - "traverse Either stack-safe" { - // also verifies result order and execution order (l to r) - val acc = mutableListOf() - val res = (0..20_000).traverse { a -> - acc.add(a) - Either.Right(a) - } - res shouldBe Either.Right(acc) - res shouldBe Either.Right((0..20_000).toList()) - } - - "traverse Either short-circuit" { - checkAll(Arb.list(Arb.int())) { ints -> - val acc = mutableListOf() - val evens = ints.traverse { - if (it % 2 == 0) { - acc.add(it) - Either.Right(it) - } else Either.Left(it) - } - acc shouldBe ints.takeWhile { it % 2 == 0 } - when (evens) { - is Either.Right -> evens.value shouldBe ints - is Either.Left -> evens.value shouldBe ints.first { it % 2 != 0 } - } - } - } - - "sequenceEither should be consistent with traverse Either" { - checkAll(Arb.list(Arb.int())) { ints -> - ints.map { it.right() }.sequence() shouldBe ints.traverse { it.right() } - } - } - - "traverse Result stack-safe" { - // also verifies result order and execution order (l to r) - val acc = mutableListOf() - val res = (0..20_000).traverse { a -> - acc.add(a) - Result.success(a) - } - res shouldBe Result.success(acc) - res shouldBe Result.success((0..20_000).toList()) - } - - "traverse Result short-circuit" { - checkAll(Arb.list(Arb.int())) { ints -> - val acc = mutableListOf() - val evens = ints.traverse { - if (it % 2 == 0) { - acc.add(it) - Result.success(it) - } else Result.failure(RuntimeException()) - } - acc shouldBe ints.takeWhile { it % 2 == 0 } - evens.fold( - { it shouldBe ints }, - { } - ) - } - } - - "sequence Result should be consistent with traverse Result" { - checkAll(Arb.list(Arb.int())) { ints -> - ints.map { Result.success(it) }.sequence() shouldBe ints.traverse { Result.success(it) } - } - } - - "traverse Option is stack-safe" { - // also verifies result order and execution order (l to r) + "mapAccumulating stack-safe, and runs in original order" { val acc = mutableListOf() - val res = (0..20_000).traverse { a: Int -> - acc.add(a) - Some(a) - } - res shouldBe Some(acc) - res shouldBe Some((0..20_000).toList()) - } - - "traverse Option short-circuits" { - checkAll(Arb.list(Arb.int())) { ints -> - val acc = mutableListOf() - val evens = ints.traverse { - (it % 2 == 0).maybe { - acc.add(it) - it - } - } - acc shouldBe ints.takeWhile { it % 2 == 0 } - evens.fold({ Unit }) { it shouldBe ints } - } - } - - "sequence Option yields some when all entries in the list are some" { - checkAll(Arb.list(Arb.int())) { ints -> - val evens = ints.map { (it % 2 == 0).maybe { it } }.sequence() - evens.fold({ Unit }) { it shouldBe ints } - } - } - - "sequence Option should be consistent with traverse Option" { - checkAll(Arb.list(Arb.int())) { ints -> - ints.map { Some(it) }.sequence() shouldBe ints.traverse { Some(it) } - } - } - - "traverse Nullable is stack-safe" { - // also verifies result order and execution order (l to r) - val acc = mutableListOf() - val res = (0..20_000).traverse { a: Int -> - acc.add(a) - a - } - res.shouldNotBeNull() shouldBe acc - res.shouldNotBeNull() shouldBe (0..20_000).toList() - } - - "traverse Nullable short-circuits" { - checkAll(Arb.list(Arb.int())) { ints -> - val acc = mutableListOf() - val evens = ints.traverse { - if (it % 2 == 0) { - acc.add(it) - it - } else { - null - } - } - - val expected = ints.takeWhile { it % 2 == 0 } - acc shouldBe expected - - if (ints.any { it % 2 != 0 }) { - evens.shouldBeNull() - } else { - evens.shouldNotBeNull() shouldContainExactly expected - } - } - } - - "sequence Nullable yields some when all entries in the list are not null" { - checkAll(Arb.list(Arb.int())) { ints -> - val evens = ints.map { if (it % 2 == 0) it else null }.sequence() - - if (ints.any { it % 2 != 0 }) { - evens.shouldBeNull() - } else { - evens.shouldNotBeNull() shouldContainExactly ints.takeWhile { it % 2 == 0 } - } - } - } - - "sequence Nullable should be consistent with travers Nullable" { - checkAll(Arb.list(Arb.int())) { ints -> - ints.map { it as Int? }.sequence() shouldBe ints.traverse { it as Int? } - } - } - - "traverse Validated stack-safe" { - // also verifies result order and execution order (l to r) - val acc = mutableListOf() - val res = (0..20_000).traverse(Semigroup.string()) { + val res = (0..20_000).mapOrAccumulate(Semigroup.string()) { acc.add(it) - Validated.Valid(it) + it } - res shouldBe Validated.Valid(acc) - res shouldBe Validated.Valid((0..20_000).toList()) + res shouldBe acc.right() + res shouldBe (0..20_000).toList().right() } - - "traverse Validated acumulates" { + + "mapAccumulating accumulates" { checkAll(Arb.list(Arb.int())) { ints -> - val res: ValidatedNel> = - ints.map { i -> if (i % 2 == 0) Valid(i) else Invalid(nonEmptyListOf(i)) } - .sequence() - - val expected: ValidatedNel> = ints.filterNot { it % 2 == 0 } - .toNonEmptyListOrNull()?.invalid() ?: Valid(ints.filter { it % 2 == 0 }) - + val res: Either, List> = + ints.mapOrAccumulate { i -> if (i % 2 == 0) i else raise(i) } + + val expected: Either, List> = ints.filterNot { it % 2 == 0 } + .toNonEmptyListOrNull()?.left() ?: ints.filter { it % 2 == 0 }.right() + res shouldBe expected } } - - "sequence Validated should be consistent with traverse Validated" { - checkAll(Arb.list(Arb.int())) { ints -> - ints.map { it.valid() }.sequence(Semigroup.string()) shouldBe - ints.traverse(Semigroup.string()) { it.valid() } - } - } - - "sequence Either traverse Nullable interoperate - and proof map + sequence equality with traverse" { - checkAll( - Arb.list(Arb.int()), - Arb.functionAToB?>(Arb.either(Arb.string(), Arb.int()).orNull()) - ) { ints, f -> - - val res: Either>? = - ints.traverse(f)?.sequence() - - val expected: Either>? = - ints.map(f).sequence()?.sequence() - - res shouldBe expected - } + + "mapAccumulating with String::plus" { + listOf(1, 2, 3).mapOrAccumulate(String::plus) { i -> + raise("fail") + } shouldBe Either.Left("failfailfail") } "zip3" { @@ -489,15 +303,5 @@ class IterableTest : UnitSpec() { list.separateEither() shouldBe ints.partition { it % 2 == 0 } } } - - "separateValidated" { - checkAll(Arb.list(Arb.int())) { ints -> - val list = ints.map { - if (it % 2 == 0) it.invalid() - else it.valid() - } - list.separateValidated() shouldBe ints.partition { it % 2 == 0 } - } - } } } diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/MapKTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/MapKTest.kt index 478062cae4b..c744c808536 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/MapKTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/MapKTest.kt @@ -6,10 +6,9 @@ import arrow.core.test.generators.longSmall import arrow.core.test.laws.MonoidLaws import arrow.typeclasses.Monoid import arrow.typeclasses.Semigroup -import io.kotest.property.Arb import io.kotest.matchers.shouldBe +import io.kotest.property.Arb import io.kotest.property.arbitrary.boolean -import io.kotest.property.arbitrary.int import io.kotest.property.arbitrary.long import io.kotest.property.arbitrary.string @@ -23,90 +22,6 @@ class MapKTest : UnitSpec() { ) ) - "traverseEither is stacksafe" { - val acc = mutableListOf() - val res = (0..20_000).map { it to it }.toMap().traverse { v -> - acc.add(v) - Either.Right(v) - } - res shouldBe acc.map { it to it }.toMap().right() - res shouldBe (0..20_000).map { it to it }.toMap().right() - } - - "traverseEither short-circuit" { - checkAll(Arb.map(Arb.int(), Arb.int())) { ints -> - val acc = mutableListOf() - val evens = ints.traverse { - if (it % 2 == 0) { - acc.add(it) - Either.Right(it) - } else Either.Left(it) - } - acc shouldBe ints.values.takeWhile { it % 2 == 0 } - when (evens) { - is Either.Right -> evens.value shouldBe ints - is Either.Left -> evens.value shouldBe ints.values.first { it % 2 != 0 } - } - } - } - - "traverseOption is stack-safe" { - // also verifies result order and execution order (l to r) - val acc = mutableListOf() - val res = (0..20_000).map { it to it }.toMap().traverse { a -> - acc.add(a) - Some(a) - } - res shouldBe Some(acc.map { it to it }.toMap()) - res shouldBe Some((0..20_000).map { it to it }.toMap()) - } - - "traverseOption short-circuits" { - checkAll(Arb.nonEmptyList(Arb.int())) { ints -> - val acc = mutableListOf() - val evens = ints.traverse { - (it % 2 == 0).maybe { - acc.add(it) - it - } - } - acc shouldBe ints.takeWhile { it % 2 == 0 } - evens.fold({ Unit }) { it shouldBe ints } - } - } - - "sequenceOption yields some when all entries in the list are some" { - checkAll(Arb.list(Arb.int())) { ints -> - val evens = ints.map { (it % 2 == 0).maybe { it } }.sequence() - evens.fold({ Unit }) { it shouldBe ints } - } - } - - "traverseValidated is stacksafe" { - val acc = mutableListOf() - val res = (0..20_000).map { it to it }.toMap().traverse(Semigroup.string()) { v -> - acc.add(v) - Validated.Valid(v) - } - res shouldBe acc.map { it to it }.toMap().valid() - res shouldBe (0..20_000).map { it to it }.toMap().valid() - } - - "traverseValidated acummulates" { - checkAll(Arb.map(Arb.int(), Arb.int())) { ints -> - val res: ValidatedNel> = - ints.traverse(Semigroup.nonEmptyList()) { i -> if (i % 2 == 0) i.validNel() else i.invalidNel() } - - val expected: ValidatedNel> = - Option.fromNullable(ints.values.filterNot { it % 2 == 0 }.toNonEmptyListOrNull()) - .fold( - { ints.entries.filter { (_, v) -> v % 2 == 0 }.map { (k, v) -> k to v }.toMap().validNel() }, - { it.invalid() }) - - res shouldBe expected - } - } - "can align maps" { // aligned keySet is union of a's and b's keys checkAll(Arb.map(Arb.long(), Arb.boolean()), Arb.map(Arb.long(), Arb.boolean())) { a, b -> diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt index 67b1c14ddf5..e989f8d40dd 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/NonEmptyListTest.kt @@ -17,7 +17,7 @@ class NonEmptyListTest : UnitSpec() { init { testLaws(SemigroupLaws.laws(Semigroup.nonEmptyList(), Arb.nonEmptyList(Arb.int()))) - + "iterable.toNonEmptyListOrNull should round trip" { checkAll(Arb.nonEmptyList(Arb.int())) { nonEmptyList -> nonEmptyList.all.toNonEmptyListOrNull().shouldNotBeNull() shouldBe nonEmptyList @@ -29,110 +29,36 @@ class NonEmptyListTest : UnitSpec() { nonEmptyList.all.toNonEmptyListOrNone() shouldBe nonEmptyList.some() } } - - "traverse for Either stack-safe" { - // also verifies result order and execution order (l to r) - val acc = mutableListOf() - val res = (0..20_000).toNonEmptyListOrNull()?.traverse { a -> - acc.add(a) - Either.Right(a) - } - res shouldBe Either.Right(acc.toNonEmptyListOrNull()) - res shouldBe Either.Right((0..20_000).toNonEmptyListOrNull()) - } - - "traverse for Either short-circuit" { - checkAll(Arb.nonEmptyList(Arb.int())) { ints -> - val acc = mutableListOf() - val evens = ints.traverse { - if (it % 2 == 0) { - acc.add(it) - Either.Right(it) - } else Either.Left(it) - } - acc shouldBe ints.takeWhile { it % 2 == 0 } - when (evens) { - is Either.Right -> evens.value shouldBe ints - is Either.Left -> evens.value shouldBe ints.first { it % 2 != 0 } - } - } - } - - "sequence for Either should be consistent with traverseEither" { - checkAll(Arb.nonEmptyList(Arb.int())) { ints -> - ints.map { Either.conditionally(it % 2 == 0, { it }, { it }) }.sequence() shouldBe - ints.traverse { Either.conditionally(it % 2 == 0, { it }, { it }) } - } - } - - "traverse for Option is stack-safe" { - // also verifies result order and execution order (l to r) - val acc = mutableListOf() - val res = (0..20_000).toNonEmptyListOrNull()?.traverse { a -> - acc.add(a) - Some(a) - } - res shouldBe Some(acc.toNonEmptyListOrNull()) - res shouldBe Some((0..20_000).toNonEmptyListOrNull()) - } - - "traverse for Option short-circuits" { - checkAll(Arb.nonEmptyList(Arb.int())) { ints -> - val acc = mutableListOf() - val evens = ints.traverse { - (it % 2 == 0).maybe { - acc.add(it) - it - } - } - acc shouldBe ints.takeWhile { it % 2 == 0 } - evens.fold({ Unit }) { it shouldBe ints } - } - } - - "sequence for Option yields some when all entries in the list are some" { - checkAll(Arb.nonEmptyList(Arb.int())) { ints -> - val evens = ints.map { (it % 2 == 0).maybe { it } }.sequence() - evens.fold({ Unit }) { it shouldBe ints } - } - } - - "sequence for Option should be consistent with traverseOption" { - checkAll(Arb.nonEmptyList(Arb.int())) { ints -> - ints.map { (it % 2 == 0).maybe { it } }.sequence() shouldBe - ints.traverse { (it % 2 == 0).maybe { it } } - } - } - - "traverse for Validated stack-safe" { - // also verifies result order and execution order (l to r) - val acc = mutableListOf() - val res = (0..20_000).traverse(Semigroup.string()) { - acc.add(it) - Validated.Valid(it) - } - res shouldBe Validated.Valid(acc) - res shouldBe Validated.Valid((0..20_000).toList()) - } - - "traverse for Validated acummulates" { - checkAll(Arb.nonEmptyList(Arb.int())) { ints -> - val res: ValidatedNel> = - ints.traverse(Semigroup.nonEmptyList()) { i: Int -> if (i % 2 == 0) i.validNel() else i.invalidNel() } - - val expected: ValidatedNel> = - ints.filterNot { it % 2 == 0 }.toNonEmptyListOrNull()?.invalid() ?: ints.filter { it % 2 == 0 }.toNonEmptyListOrNull()!!.valid() - - res shouldBe expected - } - } - - "sequence for Validated should be consistent with traverseValidated" { - checkAll(Arb.nonEmptyList(Arb.int())) { ints -> - ints.map { if (it % 2 == 0) Valid(it) else Invalid(it) }.sequence(Semigroup.int()) shouldBe - ints.traverse(Semigroup.int()) { if (it % 2 == 0) Valid(it) else Invalid(it) } - } - } + + // "traverse for Validated stack-safe" { + // // also verifies result order and execution order (l to r) + // val acc = mutableListOf() + // val res = (0..20_000).traverse(Semigroup.string()) { + // acc.add(it) + // Validated.Valid(it) + // } + // res shouldBe Validated.Valid(acc) + // res shouldBe Validated.Valid((0..20_000).toList()) + // } + // + // "traverse for Validated acummulates" { + // checkAll(Arb.nonEmptyList(Arb.int())) { ints -> + // val res: ValidatedNel> = + // ints.traverse(Semigroup.nonEmptyList()) { i: Int -> if (i % 2 == 0) i.validNel() else i.invalidNel() } + // + // val expected: ValidatedNel> = + // ints.filterNot { it % 2 == 0 }.toNonEmptyListOrNull()?.invalid() ?: ints.filter { it % 2 == 0 }.toNonEmptyListOrNull()!!.valid() + // + // res shouldBe expected + // } + // } + // + // "sequence for Validated should be consistent with traverseValidated" { + // checkAll(Arb.nonEmptyList(Arb.int())) { ints -> + // ints.map { if (it % 2 == 0) Valid(it) else Invalid(it) }.sequence(Semigroup.int()) shouldBe + // ints.traverse(Semigroup.int()) { if (it % 2 == 0) Valid(it) else Invalid(it) } + // } + // } "can align lists with different lengths" { checkAll(Arb.nonEmptyList(Arb.boolean()), Arb.nonEmptyList(Arb.boolean())) { a, b -> diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/OptionTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/OptionTest.kt index d01efef505f..5ba149a4d84 100755 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/OptionTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/OptionTest.kt @@ -365,45 +365,6 @@ class OptionTest : UnitSpec() { none.toMap() shouldBe emptyMap() } - "traverse should yield list of option" { - val some: Option = Some("value") - val none: Option = None - some.traverse { listOf(it) } shouldBe listOf(Some("value")) - none.traverse { listOf(it) } shouldBe emptyList() - } - - "sequence should be consistent with traverse" { - checkAll(Arb.option(Arb.int())) { option -> - option.map { listOf(it) }.sequence() shouldBe option.traverse { listOf(it) } - } - } - - "traverseEither should yield either of option" { - val some: Option = Some("value") - val none: Option = None - some.traverse { it.right() } shouldBe some.right() - none.traverse { it.right() } shouldBe none.right() - } - - "sequenceEither should be consistent with traverseEither" { - checkAll(Arb.option(Arb.int())) { option -> - option.map { it.right() }.sequence() shouldBe option.traverse{ it.right() } - } - } - - "traverseValidated should yield validated of option" { - val some: Option = Some("value") - val none: Option = None - some.traverse { it.valid() } shouldBe some.valid() - none.traverse { it.valid() } shouldBe none.valid() - } - - "sequenceValidated should be consistent with traverseValidated" { - checkAll(Arb.option(Arb.int())) { option -> - option.map { it.valid() }.sequence() shouldBe option.traverse { it.valid() } - } - } - "catch should return Some(result) when f does not throw" { val recover: (Throwable) -> Option = { _ -> None} Option.catch(recover) { 1 } shouldBe Some(1) diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/SequenceKTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/SequenceKTest.kt index 8e77cffad6f..d85f0b0e998 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/SequenceKTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/SequenceKTest.kt @@ -21,58 +21,6 @@ class SequenceKTest : UnitSpec() { testLaws(MonoidLaws.laws(Monoid.sequence(), Arb.sequence(Arb.int())) { s1, s2 -> s1.toList() == s2.toList() }) - "traverse for Either stack-safe" { - // also verifies result order and execution order (l to r) - val acc = mutableListOf() - val res = generateSequence(0) { it + 1 }.traverse { a -> - if (a > 20_000) { - Either.Left(Unit) - } else { - acc.add(a) - Either.Right(a) - } - } - acc shouldBe (0..20_000).toList() - res shouldBe Either.Left(Unit) - } - - "traverse for Option stack-safe" { - // also verifies result order and execution order (l to r) - val acc = mutableListOf() - val res = generateSequence(0) { it + 1 }.traverse { a -> - (a <= 20_000).maybe { - acc.add(a) - a - } - } - acc shouldBe (0..20_000).toList() - res shouldBe None - } - - "traverse for Validated stack-safe" { - // also verifies result order and execution order (l to r) - val acc = mutableListOf() - val res = (0..20_000).asSequence().traverse(Semigroup.string()) { - acc.add(it) - Validated.Valid(it) - }.map { it.toList() } - res shouldBe Validated.Valid(acc) - res shouldBe Validated.Valid((0..20_000).toList()) - } - - "traverse for Validated acummulates" { - checkAll(Arb.sequence(Arb.int())) { ints -> - val res: ValidatedNel> = ints.map { i -> if (i % 2 == 0) i.validNel() else i.invalidNel() } - .sequence(Semigroup.nonEmptyList()) - - val expected: ValidatedNel> = - ints.filterNot { it % 2 == 0 }.toList() - .toNonEmptyListOrNull()?.invalid() ?: ints.filter { it % 2 == 0 }.validNel() - - res.map { it.toList() } shouldBe expected.map { it.toList() } - } - } - "zip3" { checkAll(Arb.sequence(Arb.int()), Arb.sequence(Arb.int()), Arb.sequence(Arb.int())) { a, b, c -> val result = a.zip(b, c, ::Triple) @@ -320,18 +268,5 @@ class SequenceKTest : UnitSpec() { lefts.toList() to rights.toList() shouldBe ints.partition { it % 2 == 0 } } } - - "separateValidated" { - checkAll(Arb.sequence(Arb.int())) { ints -> - val sequence = ints.map { - if (it % 2 == 0) it.invalid() - else it.valid() - } - - val (invalids, valids) = sequence.separateValidated() - - invalids.toList() to valids.toList() shouldBe ints.partition { it % 2 == 0 } - } - } } } diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ValidatedTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ValidatedTest.kt deleted file mode 100644 index 0dca116a255..00000000000 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ValidatedTest.kt +++ /dev/null @@ -1,519 +0,0 @@ -package arrow.core - -import arrow.core.Either.Left -import arrow.core.Either.Right -import arrow.core.test.UnitSpec -import arrow.typeclasses.Monoid -import arrow.typeclasses.Semigroup -import arrow.core.test.generators.validated -import io.kotest.assertions.fail -import io.kotest.matchers.nulls.shouldBeNull -import io.kotest.property.Arb -import io.kotest.matchers.shouldBe -import io.kotest.property.arbitrary.int -import io.kotest.property.arbitrary.long -import io.kotest.property.arbitrary.orNull -import io.kotest.property.arbitrary.string - -@Suppress("RedundantSuspendModifier") -class ValidatedTest : UnitSpec() { - - init { - - "fold should call function on Invalid" { - val exception = Exception("My Exception") - val result: Validated = Invalid(exception) - result.fold( - { e -> e.message + " Checked" }, - { fail("Some should not be called") } - ) shouldBe "My Exception Checked" - } - - "fold should call function on Valid" { - val value = "Some value" - val result: Validated = Valid(value) - result.fold( - { fail("None should not be called") }, - { a -> "$a processed" } - ) shouldBe "$value processed" - } - - "leftMap should modify error" { - Valid(10).mapLeft { fail("None should not be called") } shouldBe Valid(10) - Invalid(13).mapLeft { i -> "$i is Coming soon!" } shouldBe Invalid("13 is Coming soon!") - } - - "exist should return false if is Invalid" { - Invalid(13).exist { fail("None should not be called") } shouldBe false - } - - "exist should return the value of predicate if is Valid" { - Valid(13).exist { v -> v > 10 } shouldBe true - Valid(13).exist { v -> v < 10 } shouldBe false - } - - "swap should return Valid(e) if is Invalid and Invalid(v) otherwise" { - Valid(13).swap() shouldBe Invalid(13) - Invalid(13).swap() shouldBe Valid(13) - } - - "getOrElse should return value if is Valid or default otherwise" { - Valid(13).getOrElse { fail("None should not be called") } shouldBe 13 - Invalid(13).getOrElse { "defaultValue" } shouldBe "defaultValue" - } - - "orNull should return value if is Valid or null otherwise" { - Valid(13).orNull() shouldBe 13 - val invalid: Validated = Invalid(13) - invalid.orNull() shouldBe null - } - - "orNone should return value if is Valid or None otherwise" { - Valid(13).orNone() shouldBe Some(13) - val invalid: Validated = Invalid(13) - invalid.orNone() shouldBe None - } - - "valueOr should return value if is Valid or the the result of f otherwise" { - Valid(13).valueOr { fail("None should not be called") } shouldBe 13 - Invalid(13).valueOr { e -> "$e is the defaultValue" } shouldBe "13 is the defaultValue" - } - - "orElse should return Valid(value) if is Valid or the result of default otherwise" { - Valid(13).orElse { fail("None should not be called") } shouldBe Valid(13) - Invalid(13).orElse { Valid("defaultValue") } shouldBe Valid("defaultValue") - Invalid(13).orElse { Invalid("defaultValue") } shouldBe Invalid("defaultValue") - } - - "foldLeft should return b when is Invalid" { - Invalid(13).foldLeft("Coming soon!") { _, _ -> fail("None should not be called") } shouldBe "Coming soon!" - } - - "foldLeft should return f processed when is Valid" { - Valid(10).foldLeft("Tennant") { b, a -> "$a is $b" } shouldBe "10 is Tennant" - } - - "toEither should return Either.Right(value) if is Valid or Either.Left(error) otherwise" { - Valid(10).toEither() shouldBe Right(10) - Invalid(13).toEither() shouldBe Left(13) - } - - "toIor should return Ior.Right(value) if is Valid or Ior.Left(error) otherwise" { - Valid(10).toIor() shouldBe Ior.Right(10) - Invalid(13).toIor() shouldBe Ior.Left(13) - } - - "toOption should return Some(value) if is Valid or None otherwise" { - Valid(10).toOption() shouldBe Some(10) - Invalid(13).toOption() shouldBe None - } - - "toList should return listOf(value) if is Valid or empty list otherwise" { - Valid(10).toList() shouldBe listOf(10) - Invalid(13).toList() shouldBe listOf() - } - - "toValidatedNel should return Valid(value) if is Valid or Invalid, A>(error) otherwise" { - Valid(10).toValidatedNel() shouldBe Valid(10) - Invalid(13).toValidatedNel() shouldBe Invalid(NonEmptyList(13, listOf())) - } - - "findValid should return the first Valid value or combine or Invalid values otherwise" { - Valid(10).findValid(Semigroup.int()) { fail("None should not be called") } shouldBe Valid(10) - Invalid(10).findValid(Semigroup.int()) { Valid(5) } shouldBe Valid(5) - Invalid(10).findValid(Semigroup.int()) { Invalid(5) } shouldBe Invalid(15) - } - - val nullableLongSemigroup = object : Monoid { - override fun empty(): Long? = 0 - override fun Long?.combine(b: Long?): Long? = - Nullable.zip(this@combine, b) { a, bb -> a + bb } - } - - "zip identity" { - checkAll(Arb.validated(Arb.long().orNull(), Arb.int().orNull())) { validated -> - val res = validated.zip(nullableLongSemigroup, Valid(Unit)) { a, _ -> a } - res shouldBe validated - } - } - - "tap applies effects returning the original value" { - checkAll(Arb.validated(Arb.long(), Arb.int())) { validated -> - var effect = 0 - val res = validated.tap { effect += 1 } - val expected = when (validated) { - is Validated.Valid -> 1 - is Validated.Invalid -> 0 - } - effect shouldBe expected - res shouldBe validated - } - } - - "tapInvalid applies effects returning the original value" { - checkAll(Arb.validated(Arb.long(), Arb.int())) { validated -> - var effect = 0 - val res = validated.tapInvalid { effect += 1 } - val expected = when (validated) { - is Validated.Valid -> 0 - is Validated.Invalid -> 1 - } - effect shouldBe expected - res shouldBe validated - } - } - - "zip is derived from flatMap" { - checkAll( - Arb.validated(Arb.long().orNull(), Arb.int().orNull()), - Arb.validated(Arb.long().orNull(), Arb.int().orNull()), - Arb.validated(Arb.long().orNull(), Arb.int().orNull()), - Arb.validated(Arb.long().orNull(), Arb.int().orNull()), - Arb.validated(Arb.long().orNull(), Arb.int().orNull()), - Arb.validated(Arb.long().orNull(), Arb.int().orNull()), - Arb.validated(Arb.long().orNull(), Arb.int().orNull()), - Arb.validated(Arb.long().orNull(), Arb.int().orNull()), - Arb.validated(Arb.long().orNull(), Arb.int().orNull()), - Arb.validated(Arb.long().orNull(), Arb.int().orNull()) - ) { a, b, c, d, e, f, g, h, i, j -> - val res = a.zip( - nullableLongSemigroup, - b, c, d, e, f, g, h, i, j - ) { a, b, c, d, e, f, g, h, i, j -> - Nullable.zip( - a, - b, - c, - d, - e, - f, - g, - h, - i, - j - ) { a, b, c, d, e, f, g, h, i, j -> a + b + c + d + e + f + g + h + i + j } - } - - val all = listOf(a, b, c, d, e, f, g, h, i, j) - val isValid = all.all { it.isValid } - val expected: Validated = - if (isValid) Valid(all.fold, Int?>(0) { acc, validated -> - Nullable.zip( - acc, - validated.orNull() - ) { a, b -> a + b } - }) - else Invalid( - all.filterIsInstance>().map { it.value }.fold(nullableLongSemigroup) - ) - - res shouldBe expected - } - } - - "zip should return Valid(f(a)) if both are Valid" { - Valid(10).zip(Semigroup.int(), Valid { a: Int -> a + 5 }) { a, ff -> ff(a) } shouldBe Valid(15) - } - - "zip should return first Invalid found if is unique or combine both otherwise" { - Invalid(10).zip(Semigroup.int(), Valid { a: Int -> a + 5 }) { a, ff -> ff(a) } shouldBe Invalid(10) - Valid(10).zip Int, Int>(Semigroup.int(), Invalid(5)) { a, ff -> ff(a) } shouldBe Invalid(5) - Invalid(10).zip Int, Int>(Semigroup.int(), Invalid(5)) { a, ff -> ff(a) } shouldBe Invalid(15) - } - - data class MyException(val msg: String) : Exception() - - "fromEither should return Valid if is Either.Right or Failure otherwise" { - Validated.fromEither(Right(10)) shouldBe Valid(10) - Validated.fromEither(Left(10)) shouldBe Invalid(10) - } - - "fromOption should return Valid if is Some or Invalid otherwise" { - Validated.fromOption(Some(10)) { fail("should not be called") } shouldBe Valid(10) - Validated.fromOption(None) { 5 } shouldBe Invalid(5) - } - - "fromNullable should return Valid if is not-null or Invalid otherwise" { - Validated.fromNullable(10) { fail("should not be called") } shouldBe Valid(10) - Validated.fromNullable(null) { 5 } shouldBe Invalid(5) - } - - "invalidNel should return a Invalid>" { - Validated.invalidNel(10) shouldBe Invalid(NonEmptyList(10, listOf())) - } - - "withEither should return Valid(result) if f return Right" { - Valid(10).withEither { it.map { it + 5 } } shouldBe Valid(15) - Invalid(10).withEither { Right(5) } shouldBe Valid(5) - } - - "withEither should return Invalid(result) if f return Left" { - Valid(10).withEither { Left(5) } shouldBe Invalid(5) - Invalid(10).withEither(::identity) shouldBe Invalid(10) - } - - "catch should return Valid(result) when f does not throw" { - suspend fun loadFromNetwork(): Int = 1 - Validated.catch { loadFromNetwork() } shouldBe Valid(1) - } - - "catch should return Invalid(result) when f throws" { - val exception = MyException("Boom!") - suspend fun loadFromNetwork(): Int = throw exception - Validated.catch { loadFromNetwork() } shouldBe Invalid(exception) - } - - "catchNel should return Valid(result) when f does not throw" { - suspend fun loadFromNetwork(): Int = 1 - Validated.catchNel { loadFromNetwork() } shouldBe Valid(1) - } - - "catchNel should return Invalid(Nel(result)) when f throws" { - val exception = MyException("Boom!") - suspend fun loadFromNetwork(): Int = throw exception - Validated.catchNel { loadFromNetwork() } shouldBe Invalid(nonEmptyListOf(exception)) - } - - "Cartesian builder should build products over homogeneous Validated" { - Valid("11th").zip( - Semigroup.string(), - Valid("Doctor"), - Valid("Who") - ) { a, b, c -> "$a $b $c" } shouldBe Valid("11th Doctor Who") - } - - "Cartesian builder should build products over heterogeneous Validated" { - Valid(13).zip( - Semigroup.string(), - Valid("Doctor"), - Valid(false) - ) { a, b, c -> "${a}th $b is $c" } shouldBe Valid("13th Doctor is false") - } - - "Cartesian builder should build products over Invalid Validated" { - Invalid("fail1").zip( - Semigroup.string(), - Invalid("fail2"), - Valid("Who") - ) { _, _, _ -> "success!" } shouldBe Invalid("fail1fail2") - } - - "Cartesian builder for nel doesn't need semigroup parameter" { - "fail1".invalidNel().zip( - "fail2".invalidNel() - ) { _, _ -> "success!" } shouldBe Invalid(nonEmptyListOf("fail1", "fail2")) - } - - "CombineK should combine Valid Validated" { - val valid = Valid("Who") - - valid.combineK(Semigroup.string(), valid) shouldBe (Valid("Who")) - } - - "CombineK should combine Valid and Invalid Validated" { - val valid = Valid("Who") - val invalid = Invalid("Nope") - - valid.combineK(Semigroup.string(), invalid) shouldBe (Valid("Who")) - } - - "CombineK should combine Invalid Validated" { - val invalid = Invalid("Nope") - - invalid.combineK(Semigroup.string(), invalid) shouldBe (Invalid("NopeNope")) - } - - "Combine should combine Valid Validated" { - val valid: Validated = Valid("Who") - - valid.combine(Monoid.string(), Monoid.string(), valid) shouldBe (Valid("WhoWho")) - } - - "Combine should combine Valid and Invalid Validated" { - val valid = Valid("Who") - val invalid = Invalid("Nope") - - valid.combine(Monoid.string(), Monoid.string(), invalid) shouldBe (Invalid("Nope")) - } - - "Combine should combine Invalid Validated" { - val invalid: Validated = Invalid("Nope") - - invalid.combine(Monoid.string(), Monoid.string(), invalid) shouldBe (Invalid("NopeNope")) - } - - "traverse should yield list when validated is valid" { - val valid = Valid("Who") - val invalid = Invalid("Nope") - - valid.traverse { listOf(it) } shouldBe listOf(Valid("Who")) - invalid.traverse { listOf(it) } shouldBe emptyList() - } - - "sequence should yield consistent result with traverse" { - checkAll(Arb.string(), Arb.string()) { a: String, b: String -> - val valid = Valid(a) - val invalid = Invalid(b) - - valid.traverse { listOf(it) } shouldBe valid.map { listOf(it) }.sequence() - invalid.traverse { listOf(it) } shouldBe invalid.map { listOf(it) }.sequence() - } - } - - "traverse for Option should yield option when validated is valid" { - val valid = Valid("Who") - val invalid = Invalid("Nope") - - valid.traverse { Some(it) } shouldBe Some(Valid("Who")) - invalid.traverse { Some(it) } shouldBe None - } - - "sequence for Option should yield consistent result with traverseOption" { - checkAll(Arb.string(), Arb.string()) { a: String, b: String -> - val valid = Valid(a) - val invalid = Invalid(b) - - valid.traverse { Some(it) } shouldBe valid.map { Some(it) }.sequence() - invalid.traverse { Some(it) } shouldBe invalid.map { Some(it) }.sequence() - } - } - - "traverseNullable should yield non-null object when validated is valid" { - val valid = Valid("Who") - val invalid = Invalid("Nope") - - valid.traverseNullable { it } shouldBe Valid("Who") - valid.traverseNullable { null }.shouldBeNull() - invalid.traverseNullable { it }.shouldBeNull() - } - - "sequence for Nullable should yield consistent result with traverseNullable" { - checkAll(Arb.string(), Arb.string()) { a: String, b: String -> - val valid = Valid(a) - val invalid = Invalid(b) - - valid.traverseNullable { it } shouldBe valid.map { it }.sequence() - valid.traverseNullable { null } shouldBe valid.map { null }.sequence() - invalid.traverseNullable { it } shouldBe invalid.map { it }.sequence() - } - } - - "traverse for Either should wrap validated in either" { - val valid = Valid("Who") - val invalid = Invalid("Nope") - - valid.traverse { it.right() } shouldBe Valid("Who").right() - invalid.traverse { it.right() } shouldBe Invalid("Nope").right() - } - - "sequence for Either should yield consistent result with traverseEither" { - checkAll(Arb.string(), Arb.string()) { a: String, b: String -> - val valid = Valid(a) - val invalid = Invalid(b) - - valid.traverse { Right(it) } shouldBe valid.map { Right(it) }.sequence() - invalid.traverse { Right(it) } shouldBe invalid.map { Right(it) }.sequence() - } - } - - "bitraverse should wrap valid or invalid in a list" { - val valid = Valid("Who") - val invalid = Invalid("Nope") - - valid.bitraverse({ listOf(it) }, { listOf(it) }) shouldBe listOf(Valid("Who")) - invalid.bitraverse({ listOf(it) }, { listOf(it) }) shouldBe listOf(Invalid("Nope")) - } - - "bisequence should yield consistent result with bitraverse" { - checkAll(Arb.string(), Arb.string()) { a: String, b: String -> - val valid: Validated = Valid(a) - val invalid: Validated = Invalid(b) - - valid.bimap({ listOf(it) }, { listOf(it) }).bisequence() shouldBe valid.bitraverse( - { listOf(it) }, - { listOf(it) }) - invalid.bimap({ listOf(it) }, { listOf(it) }).bisequence() shouldBe invalid.bitraverse( - { listOf(it) }, - { listOf(it) }) - } - } - - "bitraverseOption should wrap valid or invalid in an option" { - val valid = Valid("Who") - val invalid = Invalid("Nope") - - valid.bitraverseOption({ Some(it) }, { Some(it) }) shouldBe Some(Valid("Who")) - invalid.bitraverseOption({ Some(it) }, { Some(it) }) shouldBe Some(Invalid("Nope")) - } - - "bisequenceOption should yield consistent result with bitraverseOption" { - checkAll(Arb.string(), Arb.string()) { a: String, b: String -> - val valid: Validated = Valid(a) - val invalid: Validated = Invalid(b) - - valid.bimap({ Some(it) }, { Some(it) }).bisequenceOption() shouldBe - valid.bitraverseOption({ Some(it) }, { Some(it) }) - invalid.bimap({ Some(it) }, { Some(it) }).bisequenceOption() shouldBe - invalid.bitraverseOption({ Some(it) }, { Some(it) }) - } - } - - "bisequenceNullable should yield consistent result with bitraverseNullable" { - checkAll(Arb.string().orNull(), Arb.string().orNull()) { a: String?, b: String? -> - val valid: Validated = Valid(a) - val invalid: Validated = Invalid(b) - - valid.bimap({ it }, { it }).bisequenceNullable() shouldBe - valid.bitraverseNullable({ it }, { it }) - invalid.bimap({ it }, { it }).bisequenceNullable() shouldBe - invalid.bitraverseNullable({ it }, { it }) - } - } - - "bitraverseNullable should wrap valid or invalid in a nullable" { - val valid = Valid("Who") - val invalid = Invalid("Nope") - - valid.bitraverseNullable({ it }, { it }) shouldBe Valid("Who") - invalid.bitraverseNullable({ it }, { it }) shouldBe Invalid("Nope") - } - - "bitraverseEither should wrap valid or invalid in an either" { - val valid = Valid("Who") - val invalid = Invalid("Nope") - - valid.bitraverseEither({ it.left() }, { it.right() }) shouldBe Valid("Who").right() - invalid.bitraverseEither({ it.left() }, { it.right() }) shouldBe "Nope".left() - } - - "bisequenceEither should yield consistent result with bitraverseEither" { - checkAll(Arb.string(), Arb.string()) { a: String, b: String -> - val valid: Validated = Valid(a) - val invalid: Validated = Invalid(b) - - valid.bimap({ it.left() }, { it.right() }).bisequenceEither() shouldBe - valid.bitraverseEither({ it.left() }, { it.right() }) - invalid.bimap({ it.left() }, { it.right() }).bisequenceEither() shouldBe - invalid.bitraverseEither({ it.left() }, { it.right() }) - } - } - - "andThen should return Valid(result) if f return Valid" { - checkAll(Arb.int(), Arb.int()) { x, y -> - Valid(x).andThen { Valid(it + y) } shouldBe Valid(x + y) - } - } - - "andThen should only run f on valid instances " { - checkAll(Arb.int(), Arb.int()) { x, y -> - Invalid(x).andThen { Valid(y) } shouldBe Invalid(x) - } - } - - "andThen should return Invalid(result) if f return Invalid " { - checkAll(Arb.int(), Arb.int()) { x, y -> - Valid(x).andThen { Invalid(it + y) } shouldBe Invalid(x + y) - } - } - } -} diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/computations/ResultTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/computations/ResultTest.kt index 301ffb7a5d9..ca710afcac0 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/computations/ResultTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/computations/ResultTest.kt @@ -3,6 +3,7 @@ package arrow.core.computations import arrow.core.Eval import arrow.core.Tuple10 import arrow.core.composeErrors +import arrow.core.computations.ResultEffect.result import arrow.core.flatMap import arrow.core.handleErrorWith import arrow.core.redeemWith diff --git a/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/DeadlockTest.kt b/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/DeadlockTest.kt index b55d4d20084..c6fd971e03d 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/DeadlockTest.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/DeadlockTest.kt @@ -10,20 +10,6 @@ class DeadlockTest : UnitSpec() { init { - "classloader should not deadlock Validated initialization" { - runBlocking { - (0..10).map { i -> - GlobalScope.launch { - if (i % 2 == 0) { - Validated.Invalid(Unit) - } else { - Validated.Valid(null) - } - } - }.joinAll() - } - } - "classloader should not deadlock Either initialization" { runBlocking { (0..10).map { i -> diff --git a/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/ValidatedUsage.java b/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/ValidatedUsage.java deleted file mode 100644 index 26b63fdb4b4..00000000000 --- a/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/ValidatedUsage.java +++ /dev/null @@ -1,19 +0,0 @@ -package arrow.core; - -import kotlin.Unit; -import kotlin.jvm.functions.Function1; - -public class ValidatedUsage { - - public void testUsage() { - Validated throwableIntegerValidated = Validated.tryCatch(() -> 1); - Validated stringIntegerValidated = Validated.tryCatch((throwable) -> throwable.getMessage(), () -> 1); - Function1, Validated> lift = Validated.lift((b) -> b + 1); - Function1, Validated> lift1 = Validated.lift((a) -> a.toUpperCase(), (b) -> b + 1); - Validated unitIntegerValidated = Validated.fromNullable(1, () -> Unit.INSTANCE); - Validated unitIntegerValidated1 = Validated.fromOption(Option.invoke(1), () -> Unit.INSTANCE); - Validated unitIntegerValidated2 = Validated.fromEither(Either.fromNullable(1)); - Validated, Integer> nonEmptyListIntegerValidated = Validated.validNel(1); - Validated, Integer> nonEmptyListObjectValidated = Validated.invalidNel("1"); - } -} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/typeclasses/MonoidUsageTest.java b/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/typeclasses/MonoidUsageTest.java index 13bdafaea2c..41821542af6 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/typeclasses/MonoidUsageTest.java +++ b/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/typeclasses/MonoidUsageTest.java @@ -3,7 +3,6 @@ import arrow.core.Either; import arrow.core.Endo; import arrow.core.Option; -import arrow.core.Validated; import kotlin.Pair; import kotlin.sequences.Sequence; @@ -17,7 +16,6 @@ public void testUsage() { Monoid aShort = Monoid.Short(); Monoid bool = Monoid.Boolean(); Monoid integer = Monoid.Integer(); - Monoid string = Monoid.string(); Monoid> list = Monoid.list(); Monoid> sequence = Monoid.sequence(); @@ -25,7 +23,6 @@ public void testUsage() { Monoid> endo = Monoid.endo(); Monoid> map = Monoid.map(Semigroup.Integer()); Monoid> option = Monoid.option(Semigroup.Integer()); - Monoid> validated = Monoid.validated(Semigroup.Integer(), Monoid.Boolean()); Monoid> pair = Monoid.pair(Monoid.Boolean(), Monoid.Integer()); Monoid.constant(Monoid.Integer()); diff --git a/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/typeclasses/SemigroupUsageTest.java b/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/typeclasses/SemigroupUsageTest.java index 57d4320f09c..3485ee812ec 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/typeclasses/SemigroupUsageTest.java +++ b/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/typeclasses/SemigroupUsageTest.java @@ -20,7 +20,6 @@ public void testUsage() { Semigroup> endo = Semigroup.endo(); Semigroup> map = Semigroup.map(Semigroup.Integer()); Semigroup> option = Semigroup.option(Semigroup.Integer()); - Semigroup> validated = Semigroup.validated(Semigroup.Boolean(), Semigroup.Integer()); Semigroup> nonEmptyList = Semigroup.nonEmptyList(); Semigroup> pair = Semigroup.pair(Semigroup.Boolean(), Semigroup.Integer()); Semigroup> constant = Semigroup.constant(Semigroup.Integer()); diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-02.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-02.kt index 323e8b6fa0f..ddf5ecb4896 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-02.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-02.kt @@ -4,12 +4,10 @@ package arrow.core.examples.exampleEffect02 import arrow.core.Either import arrow.core.Ior import arrow.core.None -import arrow.core.Validated import arrow.core.continuations.Effect import arrow.core.continuations.effect import arrow.core.continuations.fold import arrow.core.continuations.toEither -import arrow.core.continuations.toValidated import arrow.core.continuations.toIor import arrow.core.continuations.toOption import arrow.core.continuations.ensureNotNull @@ -45,7 +43,6 @@ fun readFile(path: String?): Effect = effect { suspend fun main() { readFile("").toEither() shouldBe Either.Left(EmptyPath) - readFile("knit.properties").toValidated() shouldBe Validated.Invalid(FileNotFound("knit.properties")) readFile("gradle.properties").toIor() shouldBe Ior.Left(FileNotFound("gradle.properties")) readFile("README.MD").toOption { None } shouldBe None diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-02.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-02.kt index 3050e4d988b..d9f0dfa712f 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-02.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-02.kt @@ -3,8 +3,8 @@ package arrow.core.examples.exampleEither02 import arrow.core.Either -val right: Either = - Either.Right(5) +val left: Either = + Either.Left("Something went wrong") fun main() { - println(right) + println(left) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-03.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-03.kt index a30a54e9643..32c1b919271 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-03.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-03.kt @@ -2,9 +2,10 @@ package arrow.core.examples.exampleEither03 import arrow.core.Either +import arrow.core.flatMap -val left: Either = - Either.Left("Something went wrong") +val right: Either = Either.Right(5) +val value = right.flatMap{ Either.Right(it + 1) } fun main() { - println(left) + println("value = $value") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-04.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-04.kt index 86bf1302c74..002655609b2 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-04.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-04.kt @@ -4,8 +4,8 @@ package arrow.core.examples.exampleEither04 import arrow.core.Either import arrow.core.flatMap -val right: Either = Either.Right(5) -val value = right.flatMap{ Either.Right(it + 1) } +val left: Either = Either.Left("Something went wrong") +val value = left.flatMap{ Either.Right(it + 1) } fun main() { println("value = $value") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-05.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-05.kt index 28c39f3df3f..90c14927889 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-05.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-05.kt @@ -4,8 +4,12 @@ package arrow.core.examples.exampleEither05 import arrow.core.Either import arrow.core.flatMap -val left: Either = Either.Left("Something went wrong") -val value = left.flatMap{ Either.Right(it + 1) } -fun main() { - println("value = $value") -} +fun parse(s: String): Int = + if (s.matches(Regex("-?[0-9]+"))) s.toInt() + else throw NumberFormatException("$s is not a valid integer.") + +fun reciprocal(i: Int): Double = + if (i == 0) throw IllegalArgumentException("Cannot take reciprocal of 0.") + else 1.0 / i + +fun stringify(d: Double): String = d.toString() diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-06.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-06.kt index 67df2d4b8cb..3bcaf31e093 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-06.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-06.kt @@ -3,13 +3,19 @@ package arrow.core.examples.exampleEither06 import arrow.core.Either import arrow.core.flatMap +import arrow.core.left +import arrow.core.right -fun parse(s: String): Int = - if (s.matches(Regex("-?[0-9]+"))) s.toInt() - else throw NumberFormatException("$s is not a valid integer.") +// Either Style +fun parse(s: String): Either = + if (s.matches(Regex("-?[0-9]+"))) Either.Right(s.toInt()) + else Either.Left(NumberFormatException("$s is not a valid integer.")) -fun reciprocal(i: Int): Double = - if (i == 0) throw IllegalArgumentException("Cannot take reciprocal of 0.") - else 1.0 / i +fun reciprocal(i: Int): Either = + if (i == 0) Either.Left(IllegalArgumentException("Cannot take reciprocal of 0.")) + else Either.Right(1.0 / i) fun stringify(d: Double): String = d.toString() + +fun magic(s: String): Either = + parse(s).flatMap { reciprocal(it) }.map { stringify(it) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-07.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-07.kt index 6565442240c..71cf5d27d22 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-07.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-07.kt @@ -2,20 +2,14 @@ package arrow.core.examples.exampleEither07 import arrow.core.Either -import arrow.core.flatMap -import arrow.core.left -import arrow.core.right -// Either Style fun parse(s: String): Either = if (s.matches(Regex("-?[0-9]+"))) Either.Right(s.toInt()) else Either.Left(NumberFormatException("$s is not a valid integer.")) -fun reciprocal(i: Int): Either = - if (i == 0) Either.Left(IllegalArgumentException("Cannot take reciprocal of 0.")) - else Either.Right(1.0 / i) - -fun stringify(d: Double): String = d.toString() - -fun magic(s: String): Either = - parse(s).flatMap { reciprocal(it) }.map { stringify(it) } +val notANumber = parse("Not a number") +val number2 = parse("2") +fun main() { + println("notANumber = $notANumber") + println("number2 = $number2") +} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-08.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-08.kt index e25b8aaf693..67c0390ef19 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-08.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-08.kt @@ -2,14 +2,26 @@ package arrow.core.examples.exampleEither08 import arrow.core.Either +import arrow.core.flatMap fun parse(s: String): Either = if (s.matches(Regex("-?[0-9]+"))) Either.Right(s.toInt()) else Either.Left(NumberFormatException("$s is not a valid integer.")) -val notANumber = parse("Not a number") -val number2 = parse("2") +fun reciprocal(i: Int): Either = + if (i == 0) Either.Left(IllegalArgumentException("Cannot take reciprocal of 0.")) + else Either.Right(1.0 / i) + +fun stringify(d: Double): String = d.toString() + +fun magic(s: String): Either = + parse(s).flatMap{ reciprocal(it) }.map{ stringify(it) } + +val magic0 = magic("0") +val magic1 = magic("1") +val magicNotANumber = magic("Not a number") fun main() { - println("notANumber = $notANumber") - println("number2 = $number2") + println("magic0 = $magic0") + println("magic1 = $magic1") + println("magicNotANumber = $magicNotANumber") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-09.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-09.kt index 6e01423972f..824832efff8 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-09.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-09.kt @@ -17,11 +17,15 @@ fun stringify(d: Double): String = d.toString() fun magic(s: String): Either = parse(s).flatMap{ reciprocal(it) }.map{ stringify(it) } -val magic0 = magic("0") -val magic1 = magic("1") -val magicNotANumber = magic("Not a number") +val x = magic("2") +val value = when(x) { + is Either.Left -> when (x.value) { + is NumberFormatException -> "Not a number!" + is IllegalArgumentException -> "Can't take reciprocal of 0!" + else -> "Unknown error" + } + is Either.Right -> "Got reciprocal: ${x.value}" +} fun main() { - println("magic0 = $magic0") - println("magic1 = $magic1") - println("magicNotANumber = $magicNotANumber") + println("value = $value") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-10.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-10.kt index 84d23516808..fc1ae99d530 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-10.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-10.kt @@ -3,29 +3,22 @@ package arrow.core.examples.exampleEither10 import arrow.core.Either import arrow.core.flatMap +// Either with ADT Style -fun parse(s: String): Either = +sealed class Error { + object NotANumber : Error() + object NoZeroReciprocal : Error() +} + +fun parse(s: String): Either = if (s.matches(Regex("-?[0-9]+"))) Either.Right(s.toInt()) - else Either.Left(NumberFormatException("$s is not a valid integer.")) + else Either.Left(Error.NotANumber) -fun reciprocal(i: Int): Either = - if (i == 0) Either.Left(IllegalArgumentException("Cannot take reciprocal of 0.")) +fun reciprocal(i: Int): Either = + if (i == 0) Either.Left(Error.NoZeroReciprocal) else Either.Right(1.0 / i) fun stringify(d: Double): String = d.toString() -fun magic(s: String): Either = - parse(s).flatMap{ reciprocal(it) }.map{ stringify(it) } - -val x = magic("2") -val value = when(x) { - is Either.Left -> when (x.value) { - is NumberFormatException -> "Not a number!" - is IllegalArgumentException -> "Can't take reciprocal of 0!" - else -> "Unknown error" - } - is Either.Right -> "Got reciprocal: ${x.value}" -} -fun main() { - println("value = $value") -} +fun magic(s: String): Either = + parse(s).flatMap{reciprocal(it)}.map{ stringify(it) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-11.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-11.kt index 3b4172abc69..86ee196c7b6 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-11.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-11.kt @@ -3,11 +3,10 @@ package arrow.core.examples.exampleEither11 import arrow.core.Either import arrow.core.flatMap -// Either with ADT Style sealed class Error { - object NotANumber : Error() - object NoZeroReciprocal : Error() + object NotANumber : Error() + object NoZeroReciprocal : Error() } fun parse(s: String): Either = @@ -21,4 +20,16 @@ fun reciprocal(i: Int): Either = fun stringify(d: Double): String = d.toString() fun magic(s: String): Either = - parse(s).flatMap{reciprocal(it)}.map{ stringify(it) } + parse(s).flatMap{ reciprocal(it) }.map{ stringify(it) } + +val x = magic("2") +val value = when(x) { + is Either.Left -> when (x.value) { + is Error.NotANumber -> "Not a number!" + is Error.NoZeroReciprocal -> "Can't take reciprocal of 0!" + } + is Either.Right -> "Got reciprocal: ${x.value}" +} +fun main() { + println("value = $value") +} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-12.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-12.kt index bca693c137c..7dbf4740624 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-12.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-12.kt @@ -2,34 +2,15 @@ package arrow.core.examples.exampleEither12 import arrow.core.Either -import arrow.core.flatMap -sealed class Error { - object NotANumber : Error() - object NoZeroReciprocal : Error() -} - -fun parse(s: String): Either = - if (s.matches(Regex("-?[0-9]+"))) Either.Right(s.toInt()) - else Either.Left(Error.NotANumber) - -fun reciprocal(i: Int): Either = - if (i == 0) Either.Left(Error.NoZeroReciprocal) - else Either.Right(1.0 / i) +fun potentialThrowingCode(): String = throw RuntimeException("Blow up!") -fun stringify(d: Double): String = d.toString() - -fun magic(s: String): Either = - parse(s).flatMap{ reciprocal(it) }.map{ stringify(it) } - -val x = magic("2") -val value = when(x) { - is Either.Left -> when (x.value) { - is Error.NotANumber -> "Not a number!" - is Error.NoZeroReciprocal -> "Can't take reciprocal of 0!" - } - is Either.Right -> "Got reciprocal: ${x.value}" +suspend fun makeSureYourLogicDoesNotHaveSideEffects(): Either = + Either.catch { potentialThrowingCode() }.mapLeft { Error.SpecificError } +suspend fun main() { + println("makeSureYourLogicDoesNotHaveSideEffects().isLeft() = ${makeSureYourLogicDoesNotHaveSideEffects().isLeft()}") } -fun main() { - println("value = $value") + +sealed class Error { + object SpecificError : Error() } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-13.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-13.kt index 868a711873d..39facde74d0 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-13.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-13.kt @@ -2,15 +2,78 @@ package arrow.core.examples.exampleEither13 import arrow.core.Either +import arrow.core.flatMap +import arrow.core.left +import arrow.core.right -fun potentialThrowingCode(): String = throw RuntimeException("Blow up!") - -suspend fun makeSureYourLogicDoesNotHaveSideEffects(): Either = - Either.catch { potentialThrowingCode() }.mapLeft { Error.SpecificError } +suspend fun httpEndpoint(request: String = "Hello?") = + Either.resolve( + f = { + if (request == "Hello?") "HELLO WORLD!".right() + else Error.SpecificError.left() + }, + success = { a -> handleSuccess({ a: Any -> log(Level.INFO, "This is a: $a") }, a) }, + error = { e -> handleError({ e: Any -> log(Level.WARN, "This is e: $e") }, e) }, + throwable = { throwable -> handleThrowable({ throwable: Throwable -> log(Level.ERROR, "Log the throwable: $throwable.") }, throwable) }, + unrecoverableState = { _ -> Unit.right() } + ) suspend fun main() { - println("makeSureYourLogicDoesNotHaveSideEffects().isLeft() = ${makeSureYourLogicDoesNotHaveSideEffects().isLeft()}") + println("httpEndpoint().status = ${httpEndpoint().status}") +} + +@Suppress("UNUSED_PARAMETER") +suspend fun handleSuccess(log: suspend (a: A) -> Either, a: A): Either = + Either.catch { + Response.Builder(HttpStatus.OK) + .header(CONTENT_TYPE, CONTENT_TYPE_APPLICATION_JSON) + .body(a) + .build() + } + +@Suppress("UNUSED_PARAMETER") +suspend fun handleError(log: suspend (e: E) -> Either, e: E): Either = + createErrorResponse(HttpStatus.NOT_FOUND, ErrorResponse("$ERROR_MESSAGE_PREFIX $e")) + +suspend fun handleThrowable(log: suspend (throwable: Throwable) -> Either, throwable: Throwable): Either = + log(throwable) + .flatMap { createErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, ErrorResponse("$THROWABLE_MESSAGE_PREFIX $throwable")) } + +suspend fun createErrorResponse(httpStatus: HttpStatus, errorResponse: ErrorResponse): Either = + Either.catch { + Response.Builder(httpStatus) + .header(CONTENT_TYPE, CONTENT_TYPE_APPLICATION_JSON) + .body(errorResponse) + .build() + } + +suspend fun log(level: Level, message: String): Either = + Unit.right() // Should implement logging. + +enum class HttpStatus(val value: Int) { OK(200), NOT_FOUND(404), INTERNAL_SERVER_ERROR(500) } + +class Response private constructor( + val status: HttpStatus, + val headers: Map, + val body: Any? +) { + + data class Builder( + val status: HttpStatus, + var headers: Map = emptyMap(), + var body: Any? = null + ) { + fun header(key: String, value: String) = apply { this.headers = this.headers + mapOf(key to value) } + fun body(body: Any?) = apply { this.body = body } + fun build() = Response(status, headers, body) + } } +val CONTENT_TYPE = "Content-Type" +val CONTENT_TYPE_APPLICATION_JSON = "application/json" +val ERROR_MESSAGE_PREFIX = "An error has occurred. The error is:" +val THROWABLE_MESSAGE_PREFIX = "An exception was thrown. The exception is:" sealed class Error { object SpecificError : Error() } +data class ErrorResponse(val errorMessage: String) +enum class Level { INFO, WARN, ERROR } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-14.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-14.kt index e4aefdd6134..a1b3c01b74b 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-14.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-14.kt @@ -2,78 +2,12 @@ package arrow.core.examples.exampleEither14 import arrow.core.Either -import arrow.core.flatMap -import arrow.core.left -import arrow.core.right -suspend fun httpEndpoint(request: String = "Hello?") = - Either.resolve( - f = { - if (request == "Hello?") "HELLO WORLD!".right() - else Error.SpecificError.left() - }, - success = { a -> handleSuccess({ a: Any -> log(Level.INFO, "This is a: $a") }, a) }, - error = { e -> handleError({ e: Any -> log(Level.WARN, "This is e: $e") }, e) }, - throwable = { throwable -> handleThrowable({ throwable: Throwable -> log(Level.ERROR, "Log the throwable: $throwable.") }, throwable) }, - unrecoverableState = { _ -> Unit.right() } - ) -suspend fun main() { - println("httpEndpoint().status = ${httpEndpoint().status}") +val r : Either = Either.Right(7) +val rightMapLeft = r.mapLeft {it + 1} +val l: Either = Either.Left(7) +val leftMapLeft = l.mapLeft {it + 1} +fun main() { + println("rightMapLeft = $rightMapLeft") + println("leftMapLeft = $leftMapLeft") } - -@Suppress("UNUSED_PARAMETER") -suspend fun handleSuccess(log: suspend (a: A) -> Either, a: A): Either = - Either.catch { - Response.Builder(HttpStatus.OK) - .header(CONTENT_TYPE, CONTENT_TYPE_APPLICATION_JSON) - .body(a) - .build() - } - -@Suppress("UNUSED_PARAMETER") -suspend fun handleError(log: suspend (e: E) -> Either, e: E): Either = - createErrorResponse(HttpStatus.NOT_FOUND, ErrorResponse("$ERROR_MESSAGE_PREFIX $e")) - -suspend fun handleThrowable(log: suspend (throwable: Throwable) -> Either, throwable: Throwable): Either = - log(throwable) - .flatMap { createErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, ErrorResponse("$THROWABLE_MESSAGE_PREFIX $throwable")) } - -suspend fun createErrorResponse(httpStatus: HttpStatus, errorResponse: ErrorResponse): Either = - Either.catch { - Response.Builder(httpStatus) - .header(CONTENT_TYPE, CONTENT_TYPE_APPLICATION_JSON) - .body(errorResponse) - .build() - } - -suspend fun log(level: Level, message: String): Either = - Unit.right() // Should implement logging. - -enum class HttpStatus(val value: Int) { OK(200), NOT_FOUND(404), INTERNAL_SERVER_ERROR(500) } - -class Response private constructor( - val status: HttpStatus, - val headers: Map, - val body: Any? -) { - - data class Builder( - val status: HttpStatus, - var headers: Map = emptyMap(), - var body: Any? = null - ) { - fun header(key: String, value: String) = apply { this.headers = this.headers + mapOf(key to value) } - fun body(body: Any?) = apply { this.body = body } - fun build() = Response(status, headers, body) - } -} - -val CONTENT_TYPE = "Content-Type" -val CONTENT_TYPE_APPLICATION_JSON = "application/json" -val ERROR_MESSAGE_PREFIX = "An error has occurred. The error is:" -val THROWABLE_MESSAGE_PREFIX = "An exception was thrown. The exception is:" -sealed class Error { - object SpecificError : Error() -} -data class ErrorResponse(val errorMessage: String) -enum class Level { INFO, WARN, ERROR } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-15.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-15.kt index 02ba7e88a61..59aab0f8a32 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-15.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-15.kt @@ -1,13 +1,11 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither15 +import arrow.core.Either.Left import arrow.core.Either -val r : Either = Either.Right(7) -val rightMapLeft = r.mapLeft {it + 1} -val l: Either = Either.Left(7) -val leftMapLeft = l.mapLeft {it + 1} +val r: Either = Either.Right(7) +val swapped = r.swap() fun main() { - println("rightMapLeft = $rightMapLeft") - println("leftMapLeft = $leftMapLeft") + println("swapped = $swapped") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-16.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-16.kt index 20f29c59fcf..cd71592aeab 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-16.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-16.kt @@ -1,11 +1,10 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither16 -import arrow.core.Either.Left -import arrow.core.Either +import arrow.core.right -val r: Either = Either.Right(7) -val swapped = r.swap() +val right7 = + 7.right() fun main() { - println("swapped = $swapped") + println(right7) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-17.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-17.kt index 4a9e9269241..f820c3c1392 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-17.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-17.kt @@ -1,10 +1,10 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither17 -import arrow.core.right +import arrow.core.left -val right7 = - 7.right() + val leftHello = + "hello".left() fun main() { - println(right7) + println(leftHello) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-18.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-18.kt index 61b4cfa3593..42bb4561126 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-18.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-18.kt @@ -1,10 +1,11 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither18 -import arrow.core.left +import arrow.core.right +import arrow.core.contains - val leftHello = - "hello".left() +val x = 7.right() +val contains7 = x.contains(7) fun main() { - println(leftHello) + println("contains7 = $contains7") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-19.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-19.kt index 6d1ea1331b2..8aedf5ce5c5 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-19.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-19.kt @@ -1,11 +1,11 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither19 -import arrow.core.right -import arrow.core.contains +import arrow.core.left +import arrow.core.getOrElse -val x = 7.right() -val contains7 = x.contains(7) +val x = "hello".left() +val getOr7 = x.getOrElse { 7 } fun main() { - println("contains7 = $contains7") + println("getOr7 = $getOr7") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-20.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-20.kt index 2dd4aae24ad..9eb763740c5 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-20.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-20.kt @@ -2,10 +2,10 @@ package arrow.core.examples.exampleEither20 import arrow.core.left -import arrow.core.getOrElse +import arrow.core.getOrHandle val x = "hello".left() -val getOr7 = x.getOrElse { 7 } +val value = x.getOrHandle { "$it world!" } fun main() { - println("getOr7 = $getOr7") + println("value = $value") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-21.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-21.kt index 67e7eb953bf..097a73f6ebe 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-21.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-21.kt @@ -1,11 +1,10 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither21 -import arrow.core.left -import arrow.core.getOrHandle +import arrow.core.Either -val x = "hello".left() -val value = x.getOrHandle { "$it world!" } +val value = + Either.conditionally(true, { "Error" }, { 42 }) fun main() { - println("value = $value") + println(value) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-22.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-22.kt index f9cfa9ae33c..71cec73792c 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-22.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-22.kt @@ -4,7 +4,7 @@ package arrow.core.examples.exampleEither22 import arrow.core.Either val value = - Either.conditionally(true, { "Error" }, { 42 }) + Either.conditionally(false, { "Error" }, { 42 }) fun main() { println(value) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-23.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-23.kt index 177ba8a52d7..6dd2e13d6c8 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-23.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-23.kt @@ -2,9 +2,10 @@ package arrow.core.examples.exampleEither23 import arrow.core.Either +import arrow.core.right -val value = - Either.conditionally(false, { "Error" }, { 42 }) +val x : Either = 7.right() +val fold = x.fold({ 1 }, { it + 3 }) fun main() { - println(value) + println("fold = $fold") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-24.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-24.kt index 540212da3d0..13ae7406ca9 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-24.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-24.kt @@ -2,10 +2,10 @@ package arrow.core.examples.exampleEither24 import arrow.core.Either -import arrow.core.right +import arrow.core.left -val x : Either = 7.right() -val fold = x.fold({ 1 }, { it + 3 }) +val y : Either = 7.left() +val fold = y.fold({ 1 }, { it + 3 }) fun main() { println("fold = $fold") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-25.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-25.kt index f212f13b69e..afa8209d5ff 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-25.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-25.kt @@ -2,10 +2,15 @@ package arrow.core.examples.exampleEither25 import arrow.core.Either -import arrow.core.left +import arrow.core.getOrHandle -val y : Either = 7.left() -val fold = y.fold({ 1 }, { it + 3 }) +val r: Either = Either.Left(NumberFormatException()) +val httpStatusCode = r.getOrHandle { + when(it) { + is NumberFormatException -> 400 + else -> 500 + } +} fun main() { - println("fold = $fold") + println("httpStatusCode = $httpStatusCode") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-26.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-26.kt index 2efc6e305d4..44146180023 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-26.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-26.kt @@ -1,16 +1,13 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither26 -import arrow.core.Either -import arrow.core.getOrHandle +import arrow.core.Either.Right +import arrow.core.leftIfNull -val r: Either = Either.Left(NumberFormatException()) -val httpStatusCode = r.getOrHandle { - when(it) { - is NumberFormatException -> 400 - else -> 500 - } -} fun main() { - println("httpStatusCode = $httpStatusCode") + val value = + //sampleStart + Right(12).leftIfNull({ -1 }) + //sampleEnd + println(value) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-27.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-27.kt index c446a01405f..a5790b4af2e 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-27.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-27.kt @@ -4,10 +4,8 @@ package arrow.core.examples.exampleEither27 import arrow.core.Either.Right import arrow.core.leftIfNull +val value = + Right(null).leftIfNull({ -1 }) fun main() { - val value = - //sampleStart - Right(12).leftIfNull({ -1 }) - //sampleEnd - println(value) + println(value) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-28.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-28.kt index 9ce8328c1a1..b28c90bf578 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-28.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-28.kt @@ -1,11 +1,11 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither28 -import arrow.core.Either.Right +import arrow.core.Either.Left import arrow.core.leftIfNull val value = - Right(null).leftIfNull({ -1 }) + Left(12).leftIfNull({ -1 }) fun main() { println(value) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-29.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-29.kt index b260eb2681a..d26ce296458 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-29.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-29.kt @@ -1,11 +1,10 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither29 -import arrow.core.Either.Left -import arrow.core.leftIfNull +import arrow.core.rightIfNotNull val value = - Left(12).leftIfNull({ -1 }) + "value".rightIfNotNull { "left" } fun main() { println(value) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-30.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-30.kt index b68274ffcc6..41ee5901fd8 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-30.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-30.kt @@ -4,7 +4,7 @@ package arrow.core.examples.exampleEither30 import arrow.core.rightIfNotNull val value = - "value".rightIfNotNull { "left" } + null.rightIfNotNull { "left" } fun main() { println(value) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-31.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-31.kt index 2a73a11a0fd..f28c329b18a 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-31.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-31.kt @@ -1,10 +1,10 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither31 -import arrow.core.rightIfNotNull +import arrow.core.rightIfNull val value = - null.rightIfNotNull { "left" } + "value".rightIfNull { "left" } fun main() { println(value) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-32.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-32.kt index 2fe7fe4f955..5303f1e0a28 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-32.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-32.kt @@ -4,7 +4,7 @@ package arrow.core.examples.exampleEither32 import arrow.core.rightIfNull val value = - "value".rightIfNull { "left" } + null.rightIfNull { "left" } fun main() { println(value) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-33.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-33.kt index bcf492a1a31..4fdf5863ad1 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-33.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-33.kt @@ -1,10 +1,14 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither33 -import arrow.core.rightIfNull +import arrow.core.Either +import io.kotest.matchers.shouldBe +import io.kotest.assertions.fail -val value = - null.rightIfNull { "left" } -fun main() { - println(value) +fun test() { + Either.Right(1) + .fold({ fail("Cannot be left") }, { it + 1 }) shouldBe 2 + + Either.Left(RuntimeException("Boom!")) + .fold({ -1 }, { fail("Cannot be right") }) shouldBe -1 } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-34.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-34.kt index f48d72dacdd..20367ece978 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-34.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-34.kt @@ -3,12 +3,8 @@ package arrow.core.examples.exampleEither34 import arrow.core.Either import io.kotest.matchers.shouldBe -import io.kotest.assertions.fail fun test() { - Either.Right(1) - .fold({ fail("Cannot be left") }, { it + 1 }) shouldBe 2 - - Either.Left(RuntimeException("Boom!")) - .fold({ -1 }, { fail("Cannot be right") }) shouldBe -1 + Either.Left("left").swap() shouldBe Either.Right("left") + Either.Right("right").swap() shouldBe Either.Left("right") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-35.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-35.kt index 2161775ad0a..b3c57be1b56 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-35.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-35.kt @@ -5,6 +5,6 @@ import arrow.core.Either import io.kotest.matchers.shouldBe fun test() { - Either.Left("left").swap() shouldBe Either.Right("left") - Either.Right("right").swap() shouldBe Either.Left("right") + Either.Right(12).map { _: Int ->"flower" } shouldBe Either.Right("flower") + Either.Left(12).map { _: Nothing -> "flower" } shouldBe Either.Left(12) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-36.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-36.kt index f248f131e99..a6ad1b661f4 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-36.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-36.kt @@ -5,6 +5,6 @@ import arrow.core.Either import io.kotest.matchers.shouldBe fun test() { - Either.Right(12).map { _: Int ->"flower" } shouldBe Either.Right("flower") - Either.Left(12).map { _: Nothing -> "flower" } shouldBe Either.Left(12) + Either.Right(12).mapLeft { _: Nothing -> "flower" } shouldBe Either.Right(12) + Either.Left(12).mapLeft { _: Int -> "flower" } shouldBe Either.Left("flower") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-37.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-37.kt index dd86132c740..0895bcb4335 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-37.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-37.kt @@ -5,6 +5,5 @@ import arrow.core.Either import io.kotest.matchers.shouldBe fun test() { - Either.Right(12).mapLeft { _: Nothing -> "flower" } shouldBe Either.Right(12) - Either.Left(12).mapLeft { _: Int -> "flower" } shouldBe Either.Left("flower") + Either.Right(1).onRight(::println) shouldBe Either.Right(1) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-38.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-38.kt index 22f3f2e0d31..83ccbf67399 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-38.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-38.kt @@ -5,5 +5,5 @@ import arrow.core.Either import io.kotest.matchers.shouldBe fun test() { - Either.Right(1).onRight(::println) shouldBe Either.Right(1) + Either.Left(2).onLeft(::println) shouldBe Either.Left(2) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-39.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-39.kt index cce818e44c3..1c5d5a73ea5 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-39.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-39.kt @@ -2,8 +2,12 @@ package arrow.core.examples.exampleEither39 import arrow.core.Either -import io.kotest.matchers.shouldBe +import arrow.core.Either.Left -fun test() { - Either.Left(2).onLeft(::println) shouldBe Either.Left(2) +fun main() { + Either.Right(12).exists { it > 10 } // Result: true + Either.Right(7).exists { it > 10 } // Result: false + + val left: Either = Left(12) + left.exists { it > 10 } // Result: false } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-40.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-40.kt index 3ec2b39bfa5..5222f325036 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-40.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-40.kt @@ -2,12 +2,9 @@ package arrow.core.examples.exampleEither40 import arrow.core.Either -import arrow.core.Either.Left +import io.kotest.matchers.shouldBe -fun main() { - Either.Right(12).exists { it > 10 } // Result: true - Either.Right(7).exists { it > 10 } // Result: false - - val left: Either = Left(12) - left.exists { it > 10 } // Result: false +fun test() { + Either.Right(12).getOrNull() shouldBe 12 + Either.Left(12).getOrNull() shouldBe null } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-41.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-41.kt index 2343f3aecdc..9e1833e18ca 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-41.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-41.kt @@ -2,9 +2,11 @@ package arrow.core.examples.exampleEither41 import arrow.core.Either +import arrow.core.Some +import arrow.core.None import io.kotest.matchers.shouldBe fun test() { - Either.Right(12).getOrNull() shouldBe 12 - Either.Left(12).getOrNull() shouldBe null + Either.Right(12).getOrNone() shouldBe Some(12) + Either.Left(12).getOrNone() shouldBe None } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-42.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-42.kt index 49dff50b172..cd9256c06b2 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-42.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-42.kt @@ -1,12 +1,10 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither42 -import arrow.core.Either -import arrow.core.Some -import arrow.core.None -import io.kotest.matchers.shouldBe +import arrow.core.* -fun test() { - Either.Right(12).getOrNone() shouldBe Some(12) - Either.Left(12).getOrNone() shouldBe None + fun main(args: Array) { + //sampleStart + Either.Left("foo").isEmpty() // Result: true + Either.Right("foo").isEmpty() // Result: false } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-43.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-43.kt index 31d6b07320e..e98eda5328a 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-43.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-43.kt @@ -1,10 +1,11 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither43 -import arrow.core.* + import arrow.core.* fun main(args: Array) { //sampleStart - Either.Left("foo").isEmpty() // Result: true - Either.Right("foo").isEmpty() // Result: false + Either.Left("foo").isNotEmpty() // Result: false + Either.Right("foo").isNotEmpty() // Result: true + //sampleEnd } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-44.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-44.kt index 002f7f0f5a1..27ed105719f 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-44.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-44.kt @@ -1,11 +1,3 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither44 - import arrow.core.* - - fun main(args: Array) { - //sampleStart - Either.Left("foo").isNotEmpty() // Result: false - Either.Right("foo").isNotEmpty() // Result: true - //sampleEnd -} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-45.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-45.kt index 3a3f71679f4..6dc03e51b22 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-45.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-45.kt @@ -1,3 +1,15 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither45 +import arrow.core.Either +import arrow.core.left +import arrow.core.recover + +object User +object Error + +val error: Either = Error.left() + +val a: Either = error.recover { error -> User } // Either.Right(User) +val b: Either = error.recover { error -> raise("other-failure") } // Either.Left(other-failure) +val c: Either = error.recover { error -> User } // Either.Right(User) diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-46.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-46.kt index d1ab410df5d..0de140e5df0 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-46.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-46.kt @@ -1,15 +1,11 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither46 -import arrow.core.Either -import arrow.core.left -import arrow.core.recover - -object User -object Error - -val error: Either = Error.left() - -val a: Either = error.recover { error -> User } // Either.Right(User) -val b: Either = error.recover { error -> raise("other-failure") } // Either.Left(other-failure) -val c: Either = error.recover { error -> User } // Either.Right(User) +import arrow.core.Either.Right +import arrow.core.Either.Left +import arrow.core.getOrElse + +fun main() { + Right(12).getOrElse { 17 } // Result: 12 + Left(12).getOrElse { 17 } // Result: 17 +} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-47.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-47.kt index 28860545c61..46b0999a119 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-47.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-47.kt @@ -1,11 +1,10 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither47 -import arrow.core.Either.Right -import arrow.core.Either.Left +import arrow.core.Either import arrow.core.getOrElse +import io.kotest.matchers.shouldBe -fun main() { - Right(12).getOrElse { 17 } // Result: 12 - Left(12).getOrElse { 17 } // Result: 17 +fun test() { + Either.Left(12).getOrElse { it + 5 } shouldBe 17 } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-48.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-48.kt index 9ae9a4fa129..ff3e62a29c2 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-48.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-48.kt @@ -1,10 +1,10 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither48 -import arrow.core.Either -import arrow.core.getOrElse -import io.kotest.matchers.shouldBe +import arrow.core.Either.Right +import arrow.core.Either.Left -fun test() { - Either.Left(12).getOrElse { it + 5 } shouldBe 17 +fun main() { + Right(12).orNull() // Result: 12 + Left(12).orNull() // Result: null } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-49.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-49.kt index 6ce0f21c435..38db9474435 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-49.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-49.kt @@ -3,8 +3,9 @@ package arrow.core.examples.exampleEither49 import arrow.core.Either.Right import arrow.core.Either.Left +import arrow.core.getOrHandle fun main() { - Right(12).orNull() // Result: 12 - Left(12).orNull() // Result: null + Right(12).getOrHandle { 17 } // Result: 12 + Left(12).getOrHandle { it + 5 } // Result: 17 } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-50.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-50.kt index 75e9c042f2e..2b49927eb6a 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-50.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-50.kt @@ -1,11 +1,14 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither50 -import arrow.core.Either.Right -import arrow.core.Either.Left -import arrow.core.getOrHandle +import arrow.core.Either.* +import arrow.core.Either +import arrow.core.filterOrElse fun main() { - Right(12).getOrHandle { 17 } // Result: 12 - Left(12).getOrHandle { it + 5 } // Result: 17 + Right(12).filterOrElse({ it > 10 }, { -1 }) // Result: Right(12) + Right(7).filterOrElse({ it > 10 }, { -1 }) // Result: Left(-1) + + val left: Either = Left(12) + left.filterOrElse({ it > 10 }, { -1 }) // Result: Left(12) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-51.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-51.kt index bc0e11db6d6..8560381bf73 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-51.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-51.kt @@ -1,14 +1,17 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither51 -import arrow.core.Either.* -import arrow.core.Either -import arrow.core.filterOrElse +import arrow.core.* -fun main() { - Right(12).filterOrElse({ it > 10 }, { -1 }) // Result: Right(12) - Right(7).filterOrElse({ it > 10 }, { -1 }) // Result: Left(-1) +suspend fun main(): Unit { + //sampleStart + Either.Right(7).filterOrOther({ it == 10 }, { "Value '$it' is not equal to 10" }) + .let(::println) // Either.Left(Value '7' is not equal to 10") - val left: Either = Left(12) - left.filterOrElse({ it > 10 }, { -1 }) // Result: Left(12) + Either.Right(10).filterOrOther({ it == 10 }, { "Value '$it' is not equal to 10" }) + .let(::println) // Either.Right(10) + + Either.Left(12).filterOrOther({ str: String -> str.contains("impossible") }, { -1 }) + .let(::println) // Either.Left(12) + //sampleEnd } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-52.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-52.kt index cdb403a4abe..c2719fe2091 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-52.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-52.kt @@ -1,17 +1,11 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither52 -import arrow.core.* +import arrow.core.Either.Left +import arrow.core.Either.Right +import arrow.core.merge -suspend fun main(): Unit { - //sampleStart - Either.Right(7).filterOrOther({ it == 10 }, { "Value '$it' is not equal to 10" }) - .let(::println) // Either.Left(Value '7' is not equal to 10") - - Either.Right(10).filterOrOther({ it == 10 }, { "Value '$it' is not equal to 10" }) - .let(::println) // Either.Right(10) - - Either.Left(12).filterOrOther({ str: String -> str.contains("impossible") }, { -1 }) - .let(::println) // Either.Left(12) - //sampleEnd +fun test() { + Right(12).merge() // Result: 12 + Left(12).merge() // Result: 12 } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-53.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-53.kt index 2f98374614c..17db0b7f08f 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-53.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-53.kt @@ -1,11 +1,12 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither53 -import arrow.core.Either.Left -import arrow.core.Either.Right -import arrow.core.merge +import arrow.core.Either.* +import arrow.core.leftIfNull -fun test() { - Right(12).merge() // Result: 12 - Left(12).merge() // Result: 12 +fun main() { + Right(12).leftIfNull({ -1 }) // Result: Right(12) + Right(null).leftIfNull({ -1 }) // Result: Left(-1) + + Left(12).leftIfNull({ -1 }) // Result: Left(12) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-54.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-54.kt index 84f02542120..89b224ff078 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-54.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-54.kt @@ -1,12 +1,9 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither54 -import arrow.core.Either.* -import arrow.core.leftIfNull +import arrow.core.rightIfNotNull fun main() { - Right(12).leftIfNull({ -1 }) // Result: Right(12) - Right(null).leftIfNull({ -1 }) // Result: Left(-1) - - Left(12).leftIfNull({ -1 }) // Result: Left(12) + "value".rightIfNotNull { "left" } // Right(b="value") + null.rightIfNotNull { "left" } // Left(a="left") } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-55.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-55.kt index cf8307ed2fd..71b721f7906 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-55.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-55.kt @@ -1,9 +1,13 @@ // This file was automatically generated from Either.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEither55 -import arrow.core.rightIfNotNull +import arrow.core.* -fun main() { - "value".rightIfNotNull { "left" } // Right(b="value") - null.rightIfNotNull { "left" } // Left(a="left") +fun main(args: Array) { + //sampleStart + val string: Either = "Hello".right() + val chars: Either = + string.widen() + //sampleEnd + println(chars) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-56.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-56.kt deleted file mode 100644 index c461bd28af6..00000000000 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-either-56.kt +++ /dev/null @@ -1,13 +0,0 @@ -// This file was automatically generated from Either.kt by Knit tool. Do not edit. -package arrow.core.examples.exampleEither56 - -import arrow.core.* - -fun main(args: Array) { - //sampleStart - val string: Either = "Hello".right() - val chars: Either = - string.widen() - //sampleEnd - println(chars) -} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-12.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-12.kt index 036dce24083..97e7f426fa1 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-12.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-12.kt @@ -4,7 +4,9 @@ package arrow.core.examples.exampleIor12 import arrow.core.Ior fun main() { - Ior.Right(12).toValidated() // Result: Valid(12) - Ior.Left(12).toValidated() // Result: Invalid(12) - Ior.Both(12, "power").toValidated() // Result: Valid("power") + Ior.Both(5, 12).exists { it > 10 } // Result: true + Ior.Right(12).exists { it > 10 } // Result: true + Ior.Right(7).exists { it > 10 } // Result: false + val left: Ior = Ior.Left(12) + left.exists { it > 10 } // Result: false } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-13.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-13.kt index bc719ff8273..197b2a4a17e 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-13.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-13.kt @@ -1,12 +1,13 @@ // This file was automatically generated from Ior.kt by Knit tool. Do not edit. package arrow.core.examples.exampleIor13 -import arrow.core.Ior +import arrow.core.* -fun main() { - Ior.Both(5, 12).exists { it > 10 } // Result: true - Ior.Right(12).exists { it > 10 } // Result: true - Ior.Right(7).exists { it > 10 } // Result: false - val left: Ior = Ior.Left(12) - left.exists { it > 10 } // Result: false +fun main(args: Array) { + //sampleStart + val string: Ior = Ior.Right("Hello") + val chars: Ior = + string.widen() + //sampleEnd + println(chars) } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-14.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-14.kt deleted file mode 100644 index 78ff26a2ff5..00000000000 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-ior-14.kt +++ /dev/null @@ -1,13 +0,0 @@ -// This file was automatically generated from Ior.kt by Knit tool. Do not edit. -package arrow.core.examples.exampleIor14 - -import arrow.core.* - -fun main(args: Array) { - //sampleStart - val string: Ior = Ior.Right("Hello") - val chars: Ior = - string.widen() - //sampleEnd - println(chars) -} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-result-computations-01.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-result-computations-01.kt index 66f22e58f7f..20281fe4a0e 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-result-computations-01.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-result-computations-01.kt @@ -2,7 +2,7 @@ package arrow.core.examples.exampleResultComputations01 import arrow.core.* -import arrow.core.computations.result +import arrow.core.computations.ResultEffect.result fun main() { result { // We can safely use assertion based operation inside blocks diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-01.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-01.kt deleted file mode 100644 index fc02b28723c..00000000000 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-01.kt +++ /dev/null @@ -1,14 +0,0 @@ -// This file was automatically generated from Validated.kt by Knit tool. Do not edit. -package arrow.core.examples.exampleValidated01 - -import arrow.core.* - -fun main(args: Array) { - //sampleStart - val f = Validated.lift(String::toUpperCase, Int::inc) - val res1 = f("test".invalid()) - val res2 = f(1.valid()) - //sampleEnd - println("res1: $res1") - println("res2: $res2") -} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-02.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-02.kt deleted file mode 100644 index 68849d20db2..00000000000 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-02.kt +++ /dev/null @@ -1,12 +0,0 @@ -// This file was automatically generated from Validated.kt by Knit tool. Do not edit. -package arrow.core.examples.exampleValidated02 - -import arrow.core.* - -fun main(args: Array) { - val result = - //sampleStart - "Hello World".valid().void() - //sampleEnd - println(result) -} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-03.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-03.kt deleted file mode 100644 index e5b5f1336cf..00000000000 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-03.kt +++ /dev/null @@ -1,9 +0,0 @@ -// This file was automatically generated from Validated.kt by Knit tool. Do not edit. -package arrow.core.examples.exampleValidated03 - -import arrow.core.Validated - -fun main() { - Validated.Valid(12).tapInvalid { println("flower") } // Result: Valid(12) - Validated.Invalid(12).tapInvalid { println("flower") } // Result: prints "flower" and returns: Invalid(12) -} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-04.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-04.kt deleted file mode 100644 index c13fa930955..00000000000 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-04.kt +++ /dev/null @@ -1,9 +0,0 @@ -// This file was automatically generated from Validated.kt by Knit tool. Do not edit. -package arrow.core.examples.exampleValidated04 - -import arrow.core.Validated - -fun main() { - Validated.Valid(12).tap { println("flower") } // Result: prints "flower" and returns: Valid(12) - Validated.Invalid(12).tap { println("flower") } // Result: Invalid(12) -} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-05.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-05.kt deleted file mode 100644 index af73083b797..00000000000 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-05.kt +++ /dev/null @@ -1,13 +0,0 @@ -// This file was automatically generated from Validated.kt by Knit tool. Do not edit. -package arrow.core.examples.exampleValidated05 - -import arrow.core.* - -fun main(args: Array) { - //sampleStart - val string: Validated = "Hello".valid() - val chars: Validated = - string.widen() - //sampleEnd - println(chars) -} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-06.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-06.kt deleted file mode 100644 index 4cf01a61751..00000000000 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-validated-06.kt +++ /dev/null @@ -1,11 +0,0 @@ -// This file was automatically generated from Validated.kt by Knit tool. Do not edit. -package arrow.core.examples.exampleValidated06 - -import arrow.core.Validated -import arrow.core.andThen - -fun main() { - Validated.Valid(5).andThen { Validated.Valid(10) } // Result: Valid(10) - Validated.Valid(5).andThen { Validated.Invalid(10) } // Result: Invalid(10) - Validated.Invalid(5).andThen { Validated.Valid(10) } // Result: Invalid(5) -} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/test/EitherKnitTest.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/test/EitherKnitTest.kt index f95fdbfd8da..5069292af50 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/test/EitherKnitTest.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/test/EitherKnitTest.kt @@ -4,8 +4,12 @@ package arrow.core.examples.test import io.kotest.core.spec.style.StringSpec class EitherKnitTest : StringSpec({ - "ExampleEither34" { - arrow.core.examples.exampleEither34.test() + "ExampleEither33" { + arrow.core.examples.exampleEither33.test() + } + + "ExampleEither35" { + arrow.core.examples.exampleEither35.test() } "ExampleEither36" { @@ -20,24 +24,20 @@ class EitherKnitTest : StringSpec({ arrow.core.examples.exampleEither38.test() } - "ExampleEither39" { - arrow.core.examples.exampleEither39.test() + "ExampleEither40" { + arrow.core.examples.exampleEither40.test() } "ExampleEither41" { arrow.core.examples.exampleEither41.test() } - "ExampleEither42" { - arrow.core.examples.exampleEither42.test() - } - - "ExampleEither48" { - arrow.core.examples.exampleEither48.test() + "ExampleEither47" { + arrow.core.examples.exampleEither47.test() } - "ExampleEither53" { - arrow.core.examples.exampleEither53.test() + "ExampleEither52" { + arrow.core.examples.exampleEither52.test() } }) { diff --git a/arrow-libs/fx/arrow-fx-coroutines-test/api/arrow-fx-coroutines-test.api b/arrow-libs/fx/arrow-fx-coroutines-test/api/arrow-fx-coroutines-test.api index 196b492279e..e620e10fd85 100644 --- a/arrow-libs/fx/arrow-fx-coroutines-test/api/arrow-fx-coroutines-test.api +++ b/arrow-libs/fx/arrow-fx-coroutines-test/api/arrow-fx-coroutines-test.api @@ -33,8 +33,6 @@ public final class arrow/fx/coroutines/Predef_testKt { public static final fun throwable (Lio/kotest/property/Arb$Companion;)Lio/kotest/property/Arb; public static final fun toEither (Ljava/lang/Object;)Larrow/core/Either; public static final fun unit (Lio/kotest/property/Arb$Companion;)Lio/kotest/property/Arb; - public static final fun validated (Lio/kotest/property/Arb$Companion;Lio/kotest/property/Arb;Lio/kotest/property/Arb;)Lio/kotest/property/Arb; - public static final fun validatedNel (Lio/kotest/property/Arb$Companion;Lio/kotest/property/Arb;Lio/kotest/property/Arb;)Lio/kotest/property/Arb; } public final class arrow/fx/coroutines/Predef_test_jvmKt { diff --git a/arrow-libs/fx/arrow-fx-coroutines-test/src/commonMain/kotlin/arrow/fx/coroutines/predef-test.kt b/arrow-libs/fx/arrow-fx-coroutines-test/src/commonMain/kotlin/arrow/fx/coroutines/predef-test.kt index 3e38d073d2b..bf342f53fc9 100644 --- a/arrow-libs/fx/arrow-fx-coroutines-test/src/commonMain/kotlin/arrow/fx/coroutines/predef-test.kt +++ b/arrow-libs/fx/arrow-fx-coroutines-test/src/commonMain/kotlin/arrow/fx/coroutines/predef-test.kt @@ -1,16 +1,10 @@ package arrow.fx.coroutines import arrow.core.Either -import arrow.core.Validated -import arrow.core.ValidatedNel import arrow.core.identity -import arrow.core.invalid -import arrow.core.invalidNel import arrow.core.left import arrow.core.right import arrow.core.test.concurrency.deprecateArrowTestModules -import arrow.core.valid -import arrow.core.validNel import io.kotest.assertions.fail import io.kotest.matchers.Matcher import io.kotest.matchers.MatcherResult @@ -70,20 +64,6 @@ public fun Arb.Companion.either(left: Arb, right: Arb): Arb Arb.Companion.validated(left: Arb, right: Arb): Arb> { - val failure: Arb> = left.map { l -> l.invalid() } - val success: Arb> = right.map { r -> r.valid() } - return Arb.choice(failure, success) -} - -@Deprecated(deprecateArrowTestModules) -public fun Arb.Companion.validatedNel(left: Arb, right: Arb): Arb> { - val failure: Arb> = left.map { l -> l.invalidNel() } - val success: Arb> = right.map { r -> r.validNel() } - return Arb.choice(failure, success) -} - @Deprecated(deprecateArrowTestModules) public fun Arb.Companion.intRange(min: Int = Int.MIN_VALUE, max: Int = Int.MAX_VALUE): Arb = Arb.bind(Arb.int(min, max), Arb.int(min, max)) { a, b -> diff --git a/arrow-libs/fx/arrow-fx-coroutines/api/arrow-fx-coroutines.api b/arrow-libs/fx/arrow-fx-coroutines/api/arrow-fx-coroutines.api index 093b5fb9ee0..108050997f4 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/api/arrow-fx-coroutines.api +++ b/arrow-libs/fx/arrow-fx-coroutines/api/arrow-fx-coroutines.api @@ -168,18 +168,6 @@ public final class arrow/fx/coroutines/ParTraverse { public static final fun parSequenceScoped (Ljava/lang/Iterable;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun parSequenceScoped (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun parSequenceScoped$default (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public static final fun parSequenceValidated (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static final fun parSequenceValidated (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun parSequenceValidated$default (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public static final fun parSequenceValidatedN (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;ILkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static final fun parSequenceValidatedN (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;ILkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun parSequenceValidatedN$default (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;ILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public static final fun parSequenceValidatedNScoped (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;ILkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static final fun parSequenceValidatedNScoped (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;ILkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun parSequenceValidatedNScoped$default (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;ILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public static final fun parSequenceValidatedScoped (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static final fun parSequenceValidatedScoped (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun parSequenceValidatedScoped$default (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static final fun parTraverse (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun parTraverse (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun parTraverse$default (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; @@ -198,12 +186,6 @@ public final class arrow/fx/coroutines/ParTraverse { public static final fun parTraverseResultN (Ljava/lang/Iterable;ILkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun parTraverseResultN (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;ILkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun parTraverseResultN$default (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;ILkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public static final fun parTraverseValidated (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static final fun parTraverseValidated (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun parTraverseValidated$default (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public static final fun parTraverseValidatedN (Ljava/lang/Iterable;Larrow/typeclasses/Semigroup;ILkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static final fun parTraverseValidatedN (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;ILkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun parTraverseValidatedN$default (Ljava/lang/Iterable;Lkotlin/coroutines/CoroutineContext;Larrow/typeclasses/Semigroup;ILkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; } public final class arrow/fx/coroutines/ParZipKt { diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseResult.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseResult.kt index 6c0b129865a..75d47a64080 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseResult.kt +++ b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseResult.kt @@ -3,7 +3,7 @@ package arrow.fx.coroutines -import arrow.core.sequence +import arrow.core.continuations.result import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async @@ -131,6 +131,8 @@ public suspend fun Iterable.parTraverseResult( ctx: CoroutineContext = EmptyCoroutineContext, f: suspend CoroutineScope.(A) -> Result ): Result> = - coroutineScope { - map { async(ctx) { f.invoke(this, it) } }.awaitAll().sequence() + result { + coroutineScope { + map { async(ctx) { f.invoke(this, it).bind() } }.awaitAll() + } } diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseValidated.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseValidated.kt deleted file mode 100644 index da530594ed9..00000000000 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/ParTraverseValidated.kt +++ /dev/null @@ -1,210 +0,0 @@ -@file:JvmMultifileClass -@file:JvmName("ParTraverse") - -package arrow.fx.coroutines - -import arrow.core.Validated -import arrow.core.sequence -import arrow.typeclasses.Semigroup -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.sync.Semaphore -import kotlinx.coroutines.sync.withPermit -import kotlin.coroutines.ContinuationInterceptor -import kotlin.coroutines.CoroutineContext -import kotlin.coroutines.EmptyCoroutineContext -import kotlin.jvm.JvmMultifileClass -import kotlin.jvm.JvmName - -/** - * Traverses this [Iterable] and runs [f] in [n] parallel operations on [CoroutineContext]. - * If one or more of the tasks returns [Validated.Invalid] then all the [Validated.Invalid] results will be combined using [semigroup]. - * - * Cancelling this operation cancels all running tasks. - */ -@JvmName("parSequenceValidatedNScoped") -public suspend fun Iterable Validated>.parSequenceValidatedN(semigroup: Semigroup, n: Int): Validated> = - parTraverseValidatedN(Dispatchers.Default, semigroup, n) { it() } - -public suspend fun Iterable Validated>.parSequenceValidatedN(semigroup: Semigroup, n: Int): Validated> = - parTraverseValidatedN(Dispatchers.Default, semigroup, n) { it() } - -/** - * Traverses this [Iterable] and runs [f] in [n] parallel operations on [CoroutineContext]. - * If one or more of the tasks returns [Validated.Invalid] then all the [Validated.Invalid] results will be combined using [semigroup]. - * - * Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [ctx] argument. - * If the combined context does not have any dispatcher nor any other [ContinuationInterceptor], then [Dispatchers.Default] is used. - * **WARNING** If the combined context has a single threaded [ContinuationInterceptor], this function will not run in parallel. - * - * Cancelling this operation cancels all running tasks. - */ -@JvmName("parSequenceValidatedNScoped") -public suspend fun Iterable Validated>.parSequenceValidatedN( - ctx: CoroutineContext = EmptyCoroutineContext, - semigroup: Semigroup, - n: Int -): Validated> = - parTraverseValidatedN(ctx, semigroup, n) { it() } - -public suspend fun Iterable Validated>.parSequenceValidatedN( - ctx: CoroutineContext = EmptyCoroutineContext, - semigroup: Semigroup, - n: Int -): Validated> = - parTraverseValidatedN(ctx, semigroup, n) { it() } - -/** - * Traverses this [Iterable] and runs [f] in [n] parallel operations on [Dispatchers.Default]. - * If one or more of the [f] returns [Validated.Invalid] then all the [Validated.Invalid] results will be combined using [semigroup]. - * - * Cancelling this operation cancels all running tasks. - */ -public suspend fun Iterable.parTraverseValidatedN( - semigroup: Semigroup, - n: Int, - f: suspend CoroutineScope.(A) -> Validated -): Validated> = - parTraverseValidatedN(Dispatchers.Default, semigroup, n, f) - -/** - * Traverses this [Iterable] and runs [f] in [n] parallel operations on [CoroutineContext]. - * If one or more of the [f] returns [Validated.Invalid] then all the [Validated.Invalid] results will be combined using [semigroup]. - * - * Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [ctx] argument. - * If the combined context does not have any dispatcher nor any other [ContinuationInterceptor], then [Dispatchers.Default] is used. - * **WARNING** If the combined context has a single threaded [ContinuationInterceptor], this function will not run in parallel. - * - * Cancelling this operation cancels all running tasks. - */ -public suspend fun Iterable.parTraverseValidatedN( - ctx: CoroutineContext = EmptyCoroutineContext, - semigroup: Semigroup, - n: Int, - f: suspend CoroutineScope.(A) -> Validated -): Validated> { - val semaphore = Semaphore(n) - return parTraverseValidated(ctx, semigroup) { a -> - semaphore.withPermit { f(a) } - } -} - -/** - * Sequences all tasks in parallel on [Dispatchers.Default] and returns the result. - * If one or more of the tasks returns [Validated.Invalid] then all the [Validated.Invalid] results will be combined using [semigroup]. - * - * Cancelling this operation cancels all running tasks. - */ -@JvmName("parSequenceValidatedScoped") -public suspend fun Iterable Validated>.parSequenceValidated(semigroup: Semigroup): Validated> = - parTraverseValidated(Dispatchers.Default, semigroup) { it() } - -public suspend fun Iterable Validated>.parSequenceValidated(semigroup: Semigroup): Validated> = - parTraverseValidated(Dispatchers.Default, semigroup) { it() } - -/** - * Sequences all tasks in parallel on [ctx] and returns the result. - * If one or more of the tasks returns [Validated.Invalid] then all the [Validated.Invalid] results will be combined using [semigroup]. - * - * Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [ctx] argument. - * If the combined context does not have any dispatcher nor any other [ContinuationInterceptor], then [Dispatchers.Default] is used. - * **WARNING** If the combined context has a single threaded [ContinuationInterceptor], this function will not run in parallel. - * - * Cancelling this operation cancels all running tasks. - * - * ```kotlin - * import arrow.core.* - * import arrow.typeclasses.Semigroup - * import arrow.fx.coroutines.* - * import kotlinx.coroutines.Dispatchers - * - * typealias Task = suspend () -> ValidatedNel - * - * suspend fun main(): Unit { - * //sampleStart - * fun getTask(id: Int): Task = - * suspend { Validated.catchNel { println("Working on task $id on ${Thread.currentThread().name}") } } - * - * val res = listOf(1, 2, 3) - * .map(::getTask) - * .parSequenceValidated(Dispatchers.IO, Semigroup.nonEmptyList()) - * //sampleEnd - * println(res) - * } - * ``` - * - */ -@JvmName("parSequenceValidatedScoped") -public suspend fun Iterable Validated>.parSequenceValidated( - ctx: CoroutineContext = EmptyCoroutineContext, - semigroup: Semigroup -): Validated> = - parTraverseValidated(ctx, semigroup) { it() } - -public suspend fun Iterable Validated>.parSequenceValidated( - ctx: CoroutineContext = EmptyCoroutineContext, - semigroup: Semigroup -): Validated> = - parTraverseValidated(ctx, semigroup) { it() } - -/** - * Traverses this [Iterable] and runs all mappers [f] on [Dispatchers.Default]. - * If one or more of the [f] returns [Validated.Invalid] then all the [Validated.Invalid] results will be combined using [semigroup]. - * - * Cancelling this operation cancels all running tasks. - */ -public suspend fun Iterable.parTraverseValidated( - semigroup: Semigroup, - f: suspend CoroutineScope.(A) -> Validated -): Validated> = - parTraverseValidated(Dispatchers.Default, semigroup, f) - -/** - * Traverses this [Iterable] and runs all mappers [f] on [CoroutineContext]. - * If one or more of the [f] returns [Validated.Invalid] then all the [Validated.Invalid] results will be combined using [semigroup]. - * - * Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [ctx] argument. - * If the combined context does not have any dispatcher nor any other [ContinuationInterceptor], then [Dispatchers.Default] is used. - * **WARNING** If the combined context has a single threaded [ContinuationInterceptor], this function will not run in parallel. - * - * Cancelling this operation cancels all running tasks. - * - * ```kotlin - * import arrow.core.* - * import arrow.typeclasses.Semigroup - * import arrow.fx.coroutines.* - * import kotlinx.coroutines.Dispatchers - * - * object Error - * data class User(val id: Int, val createdOn: String) - * - * suspend fun main(): Unit { - * //sampleStart - * suspend fun getUserById(id: Int): ValidatedNel = - * if(id % 2 == 0) Error.invalidNel() - * else User(id, Thread.currentThread().name).validNel() - * - * val res = listOf(1, 3, 5) - * .parTraverseValidated(Dispatchers.IO, Semigroup.nonEmptyList()) { getUserById(it) } - * - * val res2 = listOf(1, 2, 3, 4, 5) - * .parTraverseValidated(Dispatchers.IO, Semigroup.nonEmptyList()) { getUserById(it) } - * //sampleEnd - * println(res) - * println(res2) - * } - * ``` - * - */ -public suspend fun Iterable.parTraverseValidated( - ctx: CoroutineContext = EmptyCoroutineContext, - semigroup: Semigroup, - f: suspend CoroutineScope.(A) -> Validated -): Validated> = - coroutineScope { - map { async(ctx) { f.invoke(this, it) } }.awaitAll() - .sequence(semigroup) - } diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseEitherTest.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseEitherTest.kt index f6c67ed496f..925a21a5246 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseEitherTest.kt +++ b/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseEitherTest.kt @@ -3,9 +3,10 @@ package arrow.fx.coroutines import arrow.atomic.Atomic import arrow.atomic.update import arrow.core.Either +import arrow.core.continuations.either import arrow.core.left import arrow.core.right -import arrow.core.sequence +import io.kotest.matchers.collections.shouldContain import io.kotest.matchers.should import io.kotest.matchers.shouldBe import io.kotest.property.Arb @@ -61,8 +62,8 @@ class ParTraverseEitherTest : ArrowFxSpec( val containsError = l.any(Either::isLeft) val res = l.parTraverseEither { it } - if (containsError) l.contains>(res) shouldBe true - else res shouldBe l.sequence() + if (containsError) l.shouldContain(res) + else res shouldBe either { l.map { it.bind() } } } } diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseResultTest.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseResultTest.kt index 6bab1da436c..bf178ba8ddc 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseResultTest.kt +++ b/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseResultTest.kt @@ -3,8 +3,9 @@ package arrow.fx.coroutines import arrow.atomic.Atomic import arrow.atomic.update import arrow.core.Either -import arrow.core.sequence +import arrow.core.continuations.result import arrow.core.test.generators.result +import io.kotest.matchers.collections.shouldContain import io.kotest.matchers.result.shouldBeFailureOfType import io.kotest.matchers.shouldBe import io.kotest.matchers.types.shouldBeTypeOf @@ -59,7 +60,8 @@ class ParTraverseResultTest : ArrowFxSpec( "parTraverseResult identity is identity" { checkAll(Arb.list(Arb.result(Arb.int()))) { l -> val res = l.parTraverseResult { it } - res shouldBe l.sequence() + if (l.any { it.isFailure }) l.shouldContain(res) + else res shouldBe result { l.map { it.bind() } } } } diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedTest.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedTest.kt deleted file mode 100644 index 133e1ffa30d..00000000000 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedTest.kt +++ /dev/null @@ -1,89 +0,0 @@ -package arrow.fx.coroutines - -import arrow.atomic.Atomic -import arrow.atomic.update -import arrow.core.Either -import arrow.core.NonEmptyList -import arrow.core.Validated -import arrow.core.invalidNel -import arrow.core.sequence -import arrow.core.validNel -import arrow.typeclasses.Semigroup -import io.kotest.matchers.should -import io.kotest.matchers.shouldBe -import io.kotest.property.Arb -import io.kotest.property.arbitrary.int -import io.kotest.property.arbitrary.string -import kotlinx.coroutines.CompletableDeferred - -class ParTraverseValidatedTest : ArrowFxSpec( - spec = { - "parTraverseValidated can traverse effect full computations" { - val ref = Atomic(0) - (0 until 100).parTraverseValidated(Semigroup.nonEmptyList()) { - ref.update { it + 1 }.validNel() - } - ref.value shouldBe 100 - } - - "parTraverseValidated runs in parallel" { - val promiseA = CompletableDeferred() - val promiseB = CompletableDeferred() - val promiseC = CompletableDeferred() - - listOf( - suspend { - promiseA.await() - promiseC.complete(Unit).validNel() - }, - suspend { - promiseB.await() - promiseA.complete(Unit).validNel() - }, - suspend { - promiseB.complete(Unit) - promiseC.await().validNel() - } - ).parTraverseValidated(Semigroup.nonEmptyList()) { it() } - } - - "parTraverseValidated results in the correct left" { - checkAll( - Arb.int(min = 10, max = 20), - Arb.int(min = 1, max = 9), - Arb.string() - ) { n, killOn, e -> - (0 until n).parTraverseValidated(Semigroup.nonEmptyList()) { i -> - if (i == killOn) e.invalidNel() else Unit.validNel() - } shouldBe e.invalidNel() - } - } - - "parTraverseValidated identity is identity" { - checkAll(Arb.list(Arb.validatedNel(Arb.int(), Arb.int()))) { l -> - val res: Validated, List> = l.parTraverseValidated(Semigroup.nonEmptyList()) { it } - res shouldBe l.sequence(Semigroup.nonEmptyList()) - } - } - - "parTraverseValidated results in the correct error" { - checkAll( - Arb.int(min = 10, max = 20), - Arb.int(min = 1, max = 9), - Arb.throwable() - ) { n, killOn, e -> - Either.catch { - (0 until n).parTraverseValidated(Semigroup.nonEmptyList()) { i -> - if (i == killOn) throw e else Unit.validNel() - } - } should leftException(e) - } - } - - "parTraverseValidated stack-safe" { - val count = 20_000 - val l = (0 until count).parTraverseValidated(Semigroup.nonEmptyList()) { it.validNel() } - l shouldBe (0 until count).toList().validNel() - } - } -) diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedJvmTest.kt b/arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedJvmTest.kt deleted file mode 100644 index eabcac3060b..00000000000 --- a/arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/arrow/fx/coroutines/ParTraverseValidatedJvmTest.kt +++ /dev/null @@ -1,26 +0,0 @@ -package arrow.fx.coroutines - -import arrow.core.orNull -import arrow.core.validNel -import arrow.typeclasses.Semigroup -import io.kotest.assertions.assertSoftly -import io.kotest.assertions.fail -import io.kotest.matchers.string.shouldStartWith -import io.kotest.property.Arb -import io.kotest.property.arbitrary.int - -class ParTraverseValidatedJvmTest : ArrowFxSpec(spec = { - "parTraverseValidated finishes on single thread " { // 100 is same default length as Arb.list - checkAll(Arb.int(min = Int.MIN_VALUE, max = 100)) { i -> - val res = resourceScope { - val ctx = singleThreadContext("single") - (0 until i).parTraverseValidated(ctx, Semigroup.nonEmptyList()) { Thread.currentThread().name.validNel() } - } - assertSoftly { - res.orNull()?.forEach { - it shouldStartWith "single" - } ?: fail("Expected Right but found $res") - } - } - } -}) diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/examples/example-partraversevalidated-01.kt b/arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/examples/example-partraversevalidated-01.kt deleted file mode 100644 index dba6a9a37b4..00000000000 --- a/arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/examples/example-partraversevalidated-01.kt +++ /dev/null @@ -1,21 +0,0 @@ -// This file was automatically generated from ParTraverseValidated.kt by Knit tool. Do not edit. -package arrow.fx.coroutines.examples.examplePartraversevalidated01 - -import arrow.core.* -import arrow.typeclasses.Semigroup -import arrow.fx.coroutines.* -import kotlinx.coroutines.Dispatchers - -typealias Task = suspend () -> ValidatedNel - -suspend fun main(): Unit { - //sampleStart - fun getTask(id: Int): Task = - suspend { Validated.catchNel { println("Working on task $id on ${Thread.currentThread().name}") } } - - val res = listOf(1, 2, 3) - .map(::getTask) - .parSequenceValidated(Dispatchers.IO, Semigroup.nonEmptyList()) - //sampleEnd - println(res) -} diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/examples/example-partraversevalidated-02.kt b/arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/examples/example-partraversevalidated-02.kt deleted file mode 100644 index 50ec6bb74c4..00000000000 --- a/arrow-libs/fx/arrow-fx-coroutines/src/jvmTest/kotlin/examples/example-partraversevalidated-02.kt +++ /dev/null @@ -1,26 +0,0 @@ -// This file was automatically generated from ParTraverseValidated.kt by Knit tool. Do not edit. -package arrow.fx.coroutines.examples.examplePartraversevalidated02 - -import arrow.core.* -import arrow.typeclasses.Semigroup -import arrow.fx.coroutines.* -import kotlinx.coroutines.Dispatchers - -object Error -data class User(val id: Int, val createdOn: String) - -suspend fun main(): Unit { - //sampleStart - suspend fun getUserById(id: Int): ValidatedNel = - if(id % 2 == 0) Error.invalidNel() - else User(id, Thread.currentThread().name).validNel() - - val res = listOf(1, 3, 5) - .parTraverseValidated(Dispatchers.IO, Semigroup.nonEmptyList()) { getUserById(it) } - - val res2 = listOf(1, 2, 3, 4, 5) - .parTraverseValidated(Dispatchers.IO, Semigroup.nonEmptyList()) { getUserById(it) } - //sampleEnd - println(res) - println(res2) -} diff --git a/arrow-libs/optics/arrow-optics/api/arrow-optics.api b/arrow-libs/optics/arrow-optics/api/arrow-optics.api index 970a6993266..e69f61deb4d 100644 --- a/arrow-libs/optics/arrow-optics/api/arrow-optics.api +++ b/arrow-libs/optics/arrow-optics/api/arrow-optics.api @@ -252,8 +252,6 @@ public final class arrow/optics/PEvery$DefaultImpls { public abstract interface class arrow/optics/PIso : arrow/optics/Fold, arrow/optics/Getter, arrow/optics/PEvery, arrow/optics/PLens, arrow/optics/POptional, arrow/optics/PPrism, arrow/optics/PSetter, arrow/optics/PTraversal { public static final field Companion Larrow/optics/PIso$Companion; public abstract fun compose (Larrow/optics/PIso;)Larrow/optics/PIso; - public static fun eitherToPValidated ()Larrow/optics/PIso; - 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 get (Ljava/lang/Object;)Ljava/lang/Object; @@ -278,13 +276,9 @@ public abstract interface class arrow/optics/PIso : arrow/optics/Fold, arrow/opt public abstract fun set (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public abstract fun split (Larrow/optics/PIso;)Larrow/optics/PIso; public static fun stringToList ()Larrow/optics/PIso; - public static fun validatedToEither ()Larrow/optics/PIso; - public static fun validatedToPEither ()Larrow/optics/PIso; } public final class arrow/optics/PIso$Companion { - public final fun eitherToPValidated ()Larrow/optics/PIso; - public final fun eitherToValidated ()Larrow/optics/PIso; public final fun id ()Larrow/optics/PIso; public final fun invoke (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/optics/PIso; public final fun listToOptionNel ()Larrow/optics/PIso; @@ -297,8 +291,6 @@ public final class arrow/optics/PIso$Companion { public final fun optionToPEither ()Larrow/optics/PIso; public final fun optionToPNullable ()Larrow/optics/PIso; public final fun stringToList ()Larrow/optics/PIso; - public final fun validatedToEither ()Larrow/optics/PIso; - public final fun validatedToPEither ()Larrow/optics/PIso; } public final class arrow/optics/PIso$DefaultImpls { 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 446d625743b..86fbd888422 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 @@ -68,8 +68,8 @@ public interface Fold { val fold = ::fold as (Monoid, S) -> Any? val res = fold(object : Monoid { override fun empty(): Any = EMPTY_VALUE - override fun Any?.combine(b: Any?): Any? = - if (this === EMPTY_VALUE) b else this + override fun append(a: Any?, b: Any?): Any? = + if (a === EMPTY_VALUE) b else a }, source) return EMPTY_VALUE.unbox(res) } @@ -82,8 +82,8 @@ public interface Fold { val fold = ::fold as (Monoid, S) -> Any? val res = fold(object : Monoid { override fun empty(): Any = EMPTY_VALUE - override fun Any?.combine(b: Any?): Any? = - if (b !== EMPTY_VALUE) b else this + override fun append(a: Any?, b: Any?): Any? = + if (b !== EMPTY_VALUE) b else a }, source) return EMPTY_VALUE.unbox(res) } @@ -113,8 +113,8 @@ public interface Fold { public fun findOrNull(source: S, predicate: (focus: A) -> Boolean): A? { val res = foldMap(object : Monoid { override fun empty(): Any = EMPTY_VALUE - override fun Any?.combine(b: Any?): Any? = - if (this === EMPTY_VALUE) b else this + override fun append(a: Any?, b: Any?): Any? = + if (a === EMPTY_VALUE) b else a }, source) { focus -> if (predicate(focus)) focus else EMPTY_VALUE } return EMPTY_VALUE.unbox(res) } @@ -127,8 +127,8 @@ public interface Fold { public fun exists(source: S, predicate: (focus: A) -> Boolean): Boolean { val res = foldMap(object : Monoid { override fun empty(): Any = EMPTY_VALUE - override fun Any?.combine(b: Any?): Any? = - if (this === EMPTY_VALUE) b else this + override fun append(a: Any?, b: Any?): Any? = + if (a === EMPTY_VALUE) b else a }, source) { focus -> if (predicate(focus)) focus else EMPTY_VALUE } return res !== EMPTY_VALUE } 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 007831bcd90..e7d64b2eb63 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 @@ -6,9 +6,6 @@ import arrow.core.None import arrow.core.Option import arrow.core.Either.Right import arrow.core.Some -import arrow.core.Validated -import arrow.core.Validated.Invalid -import arrow.core.Validated.Valid import arrow.core.compose import arrow.core.identity import arrow.typeclasses.Monoid @@ -168,23 +165,6 @@ public interface PIso : PPrism, PLens, Gette public fun listToOptionNel(): Iso, Option>> = listToPOptionNel() - /** - * [PIso] that defines the equality between [Either] and [Validated] - */ - @JvmStatic - public fun eitherToPValidated(): PIso, Either, Validated, Validated> = - PIso( - get = { it.fold(::Invalid, ::Valid) }, - reverseGet = Validated::toEither - ) - - /** - * [Iso] that defines the equality between [Either] and [Validated] - */ - @JvmStatic - public fun eitherToValidated(): Iso, Validated> = - eitherToPValidated() - /** * [Iso] that defines the equality between a Unit value [Map] and a [Set] with its keys */ @@ -248,22 +228,5 @@ public interface PIso : PPrism, PLens, Gette @JvmStatic public fun stringToList(): Iso> = stringToList - - /** - * [PIso] that defines equality between [Validated] and [Either] - */ - @JvmStatic - public fun validatedToPEither(): PIso, Validated, Either, Either> = - PIso( - get = Validated::toEither, - reverseGet = Validated.Companion::fromEither - ) - - /** - * [Iso] that defines equality between [Validated] and [Either] - */ - @JvmStatic - public fun validatedToEither(): Iso, Either> = - validatedToPEither() } } diff --git a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/predef.kt b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/predef.kt index 419f0ad2401..bde68db7922 100644 --- a/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/predef.kt +++ b/arrow-libs/optics/arrow-optics/src/commonMain/kotlin/arrow/optics/predef.kt @@ -11,7 +11,7 @@ internal object EMPTY_VALUE { private object BooleanOr : Monoid { override fun empty(): Boolean = false - override fun Boolean.combine(b: Boolean): Boolean = this || b + override fun append(a: Boolean, b: Boolean): Boolean = a || b } internal fun Monoid.Companion.booleanOr(): Monoid = diff --git a/arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/std/EitherTest.kt b/arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/std/EitherTest.kt deleted file mode 100644 index e434dd4f2f9..00000000000 --- a/arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/std/EitherTest.kt +++ /dev/null @@ -1,25 +0,0 @@ -package arrow.optics.std - -import arrow.core.test.UnitSpec -import arrow.core.test.generators.either -import arrow.core.test.generators.functionAToB -import arrow.core.test.generators.validated -import arrow.optics.Iso -import arrow.optics.test.laws.IsoLaws -import io.kotest.property.Arb -import io.kotest.property.arbitrary.int -import io.kotest.property.arbitrary.string - -class EitherTest : UnitSpec() { - - init { - testLaws( - IsoLaws.laws( - iso = Iso.eitherToValidated(), - aGen = Arb.either(Arb.string(), Arb.int()), - bGen = Arb.validated(Arb.string(), Arb.int()), - funcGen = Arb.functionAToB(Arb.validated(Arb.string(), Arb.int())), - ) - ) - } -} diff --git a/arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/std/ValidatedTest.kt b/arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/std/ValidatedTest.kt deleted file mode 100644 index fe5b0d1d89f..00000000000 --- a/arrow-libs/optics/arrow-optics/src/commonTest/kotlin/arrow/optics/std/ValidatedTest.kt +++ /dev/null @@ -1,27 +0,0 @@ -package arrow.optics.std - -import arrow.core.test.UnitSpec -import arrow.core.test.generators.either -import arrow.core.test.generators.functionAToB -import arrow.core.test.generators.validated -import arrow.optics.Iso -import arrow.optics.test.laws.IsoLaws -import io.kotest.property.Arb -import io.kotest.property.arbitrary.int -import io.kotest.property.arbitrary.string - -class ValidatedTest : UnitSpec() { - - init { - - testLaws( - "Iso validated to either - ", - IsoLaws.laws( - iso = Iso.validatedToEither(), - aGen = Arb.validated(Arb.string(), Arb.int()), - bGen = Arb.either(Arb.string(), Arb.int()), - funcGen = Arb.functionAToB(Arb.either(Arb.string(), Arb.int())), - ) - ) - } -} diff --git a/arrow-site/docs/_code/fx-home-code.md b/arrow-site/docs/_code/fx-home-code.md index f4cbb2f9f02..75ad8627875 100644 --- a/arrow-site/docs/_code/fx-home-code.md +++ b/arrow-site/docs/_code/fx-home-code.md @@ -2,7 +2,7 @@ library: fx ---