From 4f113bcfebdd1a5eaaf9b96a2f23f75f454ad5e7 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Thu, 23 Jun 2022 09:36:40 +0200 Subject: [PATCH 01/14] catch for EffectScope --- .../kotlin/arrow/core/continuations/EffectScope.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt index 5a1f7d23d6d..887d09e768e 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt @@ -240,3 +240,17 @@ public suspend fun EffectScope.ensureNotNull(value: B?, shift: ( contract { returns() implies (value != null) } return value ?: shift(shift()) } + +/** + * Catch any possible `shift`ed outcome from [action], and transform it with [handler]. + * This reads like a `catch` block, but for `EffectScope`. + * + * The [handler] may `shift` into a different `ErrorScope`, which is useful to + * simulate re-throwing of exceptions. + */ +public suspend fun EffectScope.catch( + action: suspend EffectScope.() -> A, + handler: suspend EffectScope.(R) -> A +): A = effect(action).fold( + recover = { handler(it) }, transform = { x -> x } + ) From 822c89ba6e9aa08456af5e2b4866260b8487b06c Mon Sep 17 00:00:00 2001 From: serras Date: Thu, 23 Jun 2022 07:41:49 +0000 Subject: [PATCH 02/14] Update API files --- arrow-libs/core/arrow-core/api/arrow-core.api | 1 + 1 file changed, 1 insertion(+) diff --git a/arrow-libs/core/arrow-core/api/arrow-core.api b/arrow-libs/core/arrow-core/api/arrow-core.api index 3f18274171f..289ebe216da 100644 --- a/arrow-libs/core/arrow-core/api/arrow-core.api +++ b/arrow-libs/core/arrow-core/api/arrow-core.api @@ -2694,6 +2694,7 @@ public final class arrow/core/continuations/EffectScope$DefaultImpls { } public final class arrow/core/continuations/EffectScopeKt { + public static final fun catch (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun ensureNotNull (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } From 8c31fe33fa115db1b24c83365c7ef944b1c3f748 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 1 Jul 2022 11:07:04 +0200 Subject: [PATCH 03/14] Suggestions by @i-walker + add catch for EagerEffectScope --- .../arrow/core/continuations/EagerEffectScope.kt | 14 ++++++++++++++ .../kotlin/arrow/core/continuations/EffectScope.kt | 8 ++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt index a0be9e206bf..348d6e60122 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt @@ -214,3 +214,17 @@ public suspend fun EagerEffectScope.ensureNotNull(value: B?, shi contract { returns() implies (value != null) } return value ?: shift(shift()) } + +/** + * Catch any possible `shift`ed outcome from [action], and transform it with [handler]. + * This reads like a `catch` block, but for `EagerEffectScope`. + * + * The [handler] may `shift` into a different `EagerErrorScope`, which is useful to + * simulate re-throwing of exceptions. + */ +public fun EagerEffectScope.catch( + f: suspend EagerEffectScope.() -> A, + recover: EagerEffectScope.(R) -> A +): A = eagerEffect(f).fold( + recover = { recover(it) }, transform = { x -> x } +) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt index 887d09e768e..cbf7dabb322 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt @@ -249,8 +249,8 @@ public suspend fun EffectScope.ensureNotNull(value: B?, shift: ( * simulate re-throwing of exceptions. */ public suspend fun EffectScope.catch( - action: suspend EffectScope.() -> A, - handler: suspend EffectScope.(R) -> A -): A = effect(action).fold( - recover = { handler(it) }, transform = { x -> x } + f: suspend EffectScope.() -> A, + recover: suspend EffectScope.(R) -> A +): A = effect(f).fold( + recover = { recover(it) }, transform = { x -> x } ) From e9b86d2f8656264cb3f83c6632cbdf310e60d43c Mon Sep 17 00:00:00 2001 From: serras Date: Fri, 1 Jul 2022 09:11:22 +0000 Subject: [PATCH 04/14] Update API files --- arrow-libs/core/arrow-core/api/arrow-core.api | 1 + 1 file changed, 1 insertion(+) diff --git a/arrow-libs/core/arrow-core/api/arrow-core.api b/arrow-libs/core/arrow-core/api/arrow-core.api index 289ebe216da..022be242fa9 100644 --- a/arrow-libs/core/arrow-core/api/arrow-core.api +++ b/arrow-libs/core/arrow-core/api/arrow-core.api @@ -2636,6 +2636,7 @@ public final class arrow/core/continuations/EagerEffectScope$DefaultImpls { } public final class arrow/core/continuations/EagerEffectScopeKt { + public static final fun catch (Larrow/core/continuations/EagerEffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public static final fun ensureNotNull (Larrow/core/continuations/EagerEffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } From f18db85636faa85631c0ed08b1215dd264617abc Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Wed, 6 Jul 2022 11:09:18 +0200 Subject: [PATCH 05/14] Suggestions by @nomisRev to improve inference --- .../core/continuations/EagerEffectScope.kt | 50 ++++++++++++++----- .../arrow/core/continuations/EffectScope.kt | 50 ++++++++++++++----- .../arrow/core/continuations/EffectSpec.kt | 31 ++++++++++-- 3 files changed, 101 insertions(+), 30 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt index 348d6e60122..f1dc17a352e 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt @@ -10,6 +10,8 @@ import arrow.core.identity import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract import kotlin.coroutines.RestrictsSuspension +import kotlin.experimental.ExperimentalTypeInference +import kotlin.jvm.JvmInline /** Context of the [EagerEffect] DSL. */ @RestrictsSuspension @@ -186,8 +188,43 @@ public interface EagerEffectScope { */ public suspend fun ensure(condition: Boolean, shift: () -> R): Unit = if (condition) Unit else shift(shift()) + + /** + * Initializes an "attempt block", which encloses an action for which + * you want to catch any possible `shift`ed outcome. This should be used + * in combination with `catch`. + * + * ``` + * attempt { ... } catch { ... } + * ``` + * + * The [effect] may `shift` into a different `ErrorScope`, giving + * the change to a later `recover` to change the shifted value. + * This is useful to simulate re-throwing of exceptions. + */ + @OptIn(ExperimentalTypeInference::class) + public suspend fun attempt( + @BuilderInference + f: suspend EagerEffectScope.() -> A, + ): AttemptEager = AttemptEager(f) + + /** + * Finishes an "attempt block" by providing the way in which to [recover] + * from a `shift`ed outcome. This function should be used in combination + * with `attempt`. + * + * ``` + * attempt { ... } catch { ... } + * ``` + */ + public infix fun AttemptEager.catch( + recover: EagerEffectScope.(E) -> A, + ): A = eagerEffect(f).fold({ recover(it) }, ::identity) } +@JvmInline +public value class AttemptEager(public val f: suspend EagerEffectScope.() -> A) + /** * Ensure that [value] is not `null`. if it's non-null it will be smart-casted and returned if it's * `false` it will `shift` with the provided value [R]. Monadic version of [kotlin.requireNotNull]. @@ -215,16 +252,3 @@ public suspend fun EagerEffectScope.ensureNotNull(value: B?, shi return value ?: shift(shift()) } -/** - * Catch any possible `shift`ed outcome from [action], and transform it with [handler]. - * This reads like a `catch` block, but for `EagerEffectScope`. - * - * The [handler] may `shift` into a different `EagerErrorScope`, which is useful to - * simulate re-throwing of exceptions. - */ -public fun EagerEffectScope.catch( - f: suspend EagerEffectScope.() -> A, - recover: EagerEffectScope.(R) -> A -): A = eagerEffect(f).fold( - recover = { recover(it) }, transform = { x -> x } -) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt index cbf7dabb322..225856a7141 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt @@ -9,6 +9,8 @@ import arrow.core.Validated import arrow.core.identity import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract +import kotlin.experimental.ExperimentalTypeInference +import kotlin.jvm.JvmInline /** Context of the [Effect] DSL. */ public interface EffectScope { @@ -212,8 +214,43 @@ public interface EffectScope { */ public suspend fun ensure(condition: Boolean, shift: () -> R): Unit = if (condition) Unit else shift(shift()) + + /** + * Initializes an "attempt block", which encloses an action for which + * you want to catch any possible `shift`ed outcome. This should be used + * in combination with `catch`. + * + * ``` + * attempt { ... } catch { ... } + * ``` + * + * The [effect] may `shift` into a different `ErrorScope`, giving + * the change to a later `recover` to change the shifted value. + * This is useful to simulate re-throwing of exceptions. + */ + @OptIn(ExperimentalTypeInference::class) + public suspend fun attempt( + @BuilderInference + f: suspend EffectScope.() -> A, + ): Attempt = Attempt(f) + + /** + * Finishes an "attempt block" by providing the way in which to [recover] + * from a `shift`ed outcome. This function should be used in combination + * with `attempt`. + * + * ``` + * attempt { ... } catch { ... } + * ``` + */ + public suspend infix fun Attempt.catch( + recover: EffectScope.(E) -> A, + ): A = effect(f).fold({ recover(it) }, ::identity) } +@JvmInline +public value class Attempt(public val f: suspend EffectScope.() -> A) + /** * Ensure that [value] is not `null`. if it's non-null it will be smart-casted and returned if it's * `false` it will `shift` with the provided value [R]. Monadic version of [kotlin.requireNotNull]. @@ -241,16 +278,3 @@ public suspend fun EffectScope.ensureNotNull(value: B?, shift: ( return value ?: shift(shift()) } -/** - * Catch any possible `shift`ed outcome from [action], and transform it with [handler]. - * This reads like a `catch` block, but for `EffectScope`. - * - * The [handler] may `shift` into a different `ErrorScope`, which is useful to - * simulate re-throwing of exceptions. - */ -public suspend fun EffectScope.catch( - f: suspend EffectScope.() -> A, - recover: suspend EffectScope.(R) -> A -): A = effect(f).fold( - recover = { recover(it) }, transform = { x -> x } - ) diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt index f5566949003..901840fae07 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt @@ -8,10 +8,7 @@ import io.kotest.assertions.fail 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.int -import io.kotest.property.arbitrary.orNull -import io.kotest.property.arbitrary.string +import io.kotest.property.arbitrary.* import io.kotest.property.checkAll import kotlin.coroutines.Continuation import kotlin.coroutines.CoroutineContext @@ -108,6 +105,32 @@ class EffectSpec : } } + "attempt - catch" { + checkAll(Arb.int(), Arb.long()) { i, l -> + effect { + attempt { + shift(l) + } catch { ll -> + ll shouldBe l + i + } + }.runCont() shouldBe i + } + } + + "attempt - no catch" { + checkAll(Arb.int(), Arb.long()) { i, l -> + effect { + attempt { + i + } catch { ll -> + ll shouldBe l + i + 1 + } + }.runCont() shouldBe i + } + } + "eagerEffect can be consumed within an Effect computation" { checkAll(Arb.int(), Arb.int()) { a, b -> val eager: EagerEffect = From 533f0fc634852d7e7f998dc0e922f039ac492bb8 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Wed, 6 Jul 2022 11:35:29 +0200 Subject: [PATCH 06/14] Remove the intermediate `Attempt` class --- .../kotlin/arrow/core/continuations/EagerEffectScope.kt | 9 +++------ .../kotlin/arrow/core/continuations/EffectScope.kt | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt index f1dc17a352e..d15cff13e0e 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt @@ -206,7 +206,7 @@ public interface EagerEffectScope { public suspend fun attempt( @BuilderInference f: suspend EagerEffectScope.() -> A, - ): AttemptEager = AttemptEager(f) + ): suspend EagerEffectScope.() -> A = f /** * Finishes an "attempt block" by providing the way in which to [recover] @@ -217,14 +217,11 @@ public interface EagerEffectScope { * attempt { ... } catch { ... } * ``` */ - public infix fun AttemptEager.catch( + public infix fun (suspend EagerEffectScope.() -> A).catch( recover: EagerEffectScope.(E) -> A, - ): A = eagerEffect(f).fold({ recover(it) }, ::identity) + ): A = eagerEffect(this).fold({ recover(it) }, ::identity) } -@JvmInline -public value class AttemptEager(public val f: suspend EagerEffectScope.() -> A) - /** * Ensure that [value] is not `null`. if it's non-null it will be smart-casted and returned if it's * `false` it will `shift` with the provided value [R]. Monadic version of [kotlin.requireNotNull]. diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt index 225856a7141..b7dd56242a1 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt @@ -232,7 +232,7 @@ public interface EffectScope { public suspend fun attempt( @BuilderInference f: suspend EffectScope.() -> A, - ): Attempt = Attempt(f) + ): suspend EffectScope.() -> A = f /** * Finishes an "attempt block" by providing the way in which to [recover] @@ -243,14 +243,11 @@ public interface EffectScope { * attempt { ... } catch { ... } * ``` */ - public suspend infix fun Attempt.catch( + public suspend infix fun (suspend EffectScope.() -> A).catch( recover: EffectScope.(E) -> A, - ): A = effect(f).fold({ recover(it) }, ::identity) + ): A = effect(this).fold({ recover(it) }, ::identity) } -@JvmInline -public value class Attempt(public val f: suspend EffectScope.() -> A) - /** * Ensure that [value] is not `null`. if it's non-null it will be smart-casted and returned if it's * `false` it will `shift` with the provided value [R]. Monadic version of [kotlin.requireNotNull]. From 4958b48466e24df8cf10120a59d87a13f730beaf Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Wed, 6 Jul 2022 15:32:10 +0200 Subject: [PATCH 07/14] API dump --- arrow-libs/core/arrow-core/api/arrow-core.api | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/arrow-libs/core/arrow-core/api/arrow-core.api b/arrow-libs/core/arrow-core/api/arrow-core.api index 022be242fa9..487f076aa3e 100644 --- a/arrow-libs/core/arrow-core/api/arrow-core.api +++ b/arrow-libs/core/arrow-core/api/arrow-core.api @@ -2617,26 +2617,29 @@ public final class arrow/core/continuations/EagerEffectKt { } public abstract interface class arrow/core/continuations/EagerEffectScope { + public abstract fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun bind (Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun bind (Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun bind (Larrow/core/continuations/EagerEffect;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 catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public abstract fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun shift (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class arrow/core/continuations/EagerEffectScope$DefaultImpls { + public static fun attempt (Larrow/core/continuations/EagerEffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EagerEffectScope;Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EagerEffectScope;Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EagerEffectScope;Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EagerEffectScope;Larrow/core/continuations/EagerEffect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EagerEffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun catch (Larrow/core/continuations/EagerEffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public static fun ensure (Larrow/core/continuations/EagerEffectScope;ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class arrow/core/continuations/EagerEffectScopeKt { - public static final fun catch (Larrow/core/continuations/EagerEffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public static final fun ensureNotNull (Larrow/core/continuations/EagerEffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } @@ -2674,28 +2677,31 @@ public final class arrow/core/continuations/EffectKt { } public abstract interface class arrow/core/continuations/EffectScope { + public abstract fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun bind (Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun bind (Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun bind (Larrow/core/continuations/EagerEffect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun bind (Larrow/core/continuations/Effect;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 catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun shift (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class arrow/core/continuations/EffectScope$DefaultImpls { + public static fun attempt (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EffectScope;Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EffectScope;Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EffectScope;Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EffectScope;Larrow/core/continuations/EagerEffect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EffectScope;Larrow/core/continuations/Effect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun catch (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun ensure (Larrow/core/continuations/EffectScope;ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class arrow/core/continuations/EffectScopeKt { - public static final fun catch (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun ensureNotNull (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } @@ -2707,12 +2713,14 @@ public final class arrow/core/continuations/FoldContinuation : kotlin/coroutines public final class arrow/core/continuations/IorEagerEffectScope : arrow/core/continuations/EagerEffectScope, arrow/typeclasses/Semigroup { public fun (Larrow/typeclasses/Semigroup;Larrow/core/continuations/EagerEffectScope;)V + public fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun bind (Larrow/core/Ior;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/continuations/EagerEffect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public fun combine (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun maybeCombine (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @@ -2722,6 +2730,7 @@ public final class arrow/core/continuations/IorEagerEffectScope : arrow/core/con public final class arrow/core/continuations/IorEffectScope : arrow/core/continuations/EffectScope, arrow/typeclasses/Semigroup { public fun (Larrow/typeclasses/Semigroup;Larrow/core/continuations/EffectScope;)V + public fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun bind (Larrow/core/Ior;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2729,6 +2738,7 @@ public final class arrow/core/continuations/IorEffectScope : arrow/core/continua public fun bind (Larrow/core/continuations/EagerEffect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/continuations/Effect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun combine (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun maybeCombine (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @@ -2737,6 +2747,8 @@ public final class arrow/core/continuations/IorEffectScope : arrow/core/continua } public final class arrow/core/continuations/NullableEagerEffectScope : arrow/core/continuations/EagerEffectScope { + public fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun attempt-impl (Larrow/core/continuations/EagerEffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2750,6 +2762,8 @@ public final class arrow/core/continuations/NullableEagerEffectScope : arrow/cor public static final fun bind-impl (Larrow/core/continuations/EagerEffectScope;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/EagerEffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final synthetic fun box-impl (Larrow/core/continuations/EagerEffectScope;)Larrow/core/continuations/NullableEagerEffectScope; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; + public static fun catch-impl (Larrow/core/continuations/EagerEffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public static fun constructor-impl (Larrow/core/continuations/EagerEffectScope;)Larrow/core/continuations/EagerEffectScope; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun ensure-impl (Larrow/core/continuations/EagerEffectScope;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2768,6 +2782,8 @@ public final class arrow/core/continuations/NullableEagerEffectScope : arrow/cor } public final class arrow/core/continuations/NullableEffectScope : arrow/core/continuations/EffectScope { + public fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun attempt-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2783,6 +2799,8 @@ public final class arrow/core/continuations/NullableEffectScope : arrow/core/con public static final fun bind-impl (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final synthetic fun box-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/NullableEffectScope; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun catch-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun constructor-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/EffectScope; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun ensure-impl (Larrow/core/continuations/EffectScope;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2806,6 +2824,8 @@ public final class arrow/core/continuations/NullableKt { } public final class arrow/core/continuations/OptionEagerEffectScope : arrow/core/continuations/EagerEffectScope { + public fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun attempt-impl (Larrow/core/continuations/EagerEffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2818,6 +2838,8 @@ public final class arrow/core/continuations/OptionEagerEffectScope : arrow/core/ public static fun bind-impl (Larrow/core/continuations/EagerEffectScope;Larrow/core/continuations/EagerEffect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/EagerEffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final synthetic fun box-impl (Larrow/core/continuations/EagerEffectScope;)Larrow/core/continuations/OptionEagerEffectScope; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; + public static fun catch-impl (Larrow/core/continuations/EagerEffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public static fun constructor-impl (Larrow/core/continuations/EagerEffectScope;)Larrow/core/continuations/EagerEffectScope; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun ensure-impl (Larrow/core/continuations/EagerEffectScope;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2836,6 +2858,8 @@ public final class arrow/core/continuations/OptionEagerEffectScope : arrow/core/ } public final class arrow/core/continuations/OptionEffectScope : arrow/core/continuations/EffectScope { + public fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun attempt-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2850,6 +2874,8 @@ public final class arrow/core/continuations/OptionEffectScope : arrow/core/conti public static fun bind-impl (Larrow/core/continuations/EffectScope;Larrow/core/continuations/Effect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final synthetic fun box-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/OptionEffectScope; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun catch-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun constructor-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/EffectScope; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun ensure-impl (Larrow/core/continuations/EffectScope;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2875,6 +2901,8 @@ public final class arrow/core/continuations/OptionKt { } public final class arrow/core/continuations/ResultEagerEffectScope : arrow/core/continuations/EagerEffectScope { + public fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun attempt-impl (Larrow/core/continuations/EagerEffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2887,6 +2915,8 @@ public final class arrow/core/continuations/ResultEagerEffectScope : arrow/core/ public static final fun bind-impl (Larrow/core/continuations/EagerEffectScope;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/EagerEffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final synthetic fun box-impl (Larrow/core/continuations/EagerEffectScope;)Larrow/core/continuations/ResultEagerEffectScope; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; + public static fun catch-impl (Larrow/core/continuations/EagerEffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public static fun constructor-impl (Larrow/core/continuations/EagerEffectScope;)Larrow/core/continuations/EagerEffectScope; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun ensure-impl (Larrow/core/continuations/EagerEffectScope;ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2904,6 +2934,8 @@ public final class arrow/core/continuations/ResultEagerEffectScope : arrow/core/ } public final class arrow/core/continuations/ResultEffectScope : arrow/core/continuations/EffectScope { + public fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun attempt-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Either;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Option;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Validated;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2918,6 +2950,8 @@ public final class arrow/core/continuations/ResultEffectScope : arrow/core/conti public static final fun bind-impl (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final synthetic fun box-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/ResultEffectScope; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun catch-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun constructor-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/EffectScope; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun ensure-impl (Larrow/core/continuations/EffectScope;ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; From c19e720b5203a7969e2b0fa4fa58ebc66e531b40 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Thu, 7 Jul 2022 17:04:36 +0200 Subject: [PATCH 08/14] Better docs based on @i-walker's suggestions --- .../core/continuations/EagerEffectScope.kt | 37 ++++++++++++++----- .../arrow/core/continuations/EffectScope.kt | 36 +++++++++++++----- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt index d15cff13e0e..1c4235d5ce4 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt @@ -190,16 +190,15 @@ public interface EagerEffectScope { if (condition) Unit else shift(shift()) /** - * Initializes an "attempt block", which encloses an action for which - * you want to catch any possible `shift`ed outcome. This should be used - * in combination with `catch`. + * Encloses an action for which you want to catch any `shift`. + * [attempt] is used in combination with [catch]. * * ``` * attempt { ... } catch { ... } * ``` * - * The [effect] may `shift` into a different `ErrorScope`, giving - * the change to a later `recover` to change the shifted value. + * The [f] may `shift` into a different `EagerEffectScope`, giving + * the chance for a later [catch] to change the shifted value. * This is useful to simulate re-throwing of exceptions. */ @OptIn(ExperimentalTypeInference::class) @@ -208,14 +207,32 @@ public interface EagerEffectScope { f: suspend EagerEffectScope.() -> A, ): suspend EagerEffectScope.() -> A = f + /** - * Finishes an "attempt block" by providing the way in which to [recover] - * from a `shift`ed outcome. This function should be used in combination - * with `attempt`. + * When the [EagerEffect] has shifted with [R] it will [recover] + * the shifted value to [A], and when it ran the computation to + * completion it will return the value [A]. + * [catch] is used in combination with [attempt]. * + * ```kotlin + * import arrow.core.Either + * import arrow.core.None + * import arrow.core.Option + * import arrow.core.Validated + * import arrow.core.continuations.eagerEffect + * import io.kotest.assertions.fail + * import io.kotest.matchers.shouldBe + * + * fun main() { + * eagerEffect { + * val x = Either.Right(1).bind() + * val y = Validated.Valid(2).bind() + * val z = + * attempt { None.bind { "Option was empty" } } catch { 0 } + * x + y + z + * }.fold({ fail("Shift can never be the result") }, { it shouldBe 3 }) * ``` - * attempt { ... } catch { ... } - * ``` + * */ public infix fun (suspend EagerEffectScope.() -> A).catch( recover: EagerEffectScope.(E) -> A, diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt index b7dd56242a1..50aa14025f9 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt @@ -216,16 +216,15 @@ public interface EffectScope { if (condition) Unit else shift(shift()) /** - * Initializes an "attempt block", which encloses an action for which - * you want to catch any possible `shift`ed outcome. This should be used - * in combination with `catch`. + * Encloses an action for which you want to catch any `shift`. + * [attempt] is used in combination with [catch]. * * ``` * attempt { ... } catch { ... } * ``` * - * The [effect] may `shift` into a different `ErrorScope`, giving - * the change to a later `recover` to change the shifted value. + * The [f] may `shift` into a different `EffectScope`, giving + * the chance for a later [catch] to change the shifted value. * This is useful to simulate re-throwing of exceptions. */ @OptIn(ExperimentalTypeInference::class) @@ -235,13 +234,30 @@ public interface EffectScope { ): suspend EffectScope.() -> A = f /** - * Finishes an "attempt block" by providing the way in which to [recover] - * from a `shift`ed outcome. This function should be used in combination - * with `attempt`. + * When the [Effect] has shifted with [R] it will [recover] + * the shifted value to [A], and when it ran the computation to + * completion it will return the value [A]. + * [catch] is used in combination with [attempt]. * + * ```kotlin + * import arrow.core.Either + * import arrow.core.None + * import arrow.core.Option + * import arrow.core.Validated + * import arrow.core.continuations.effect + * import io.kotest.assertions.fail + * import io.kotest.matchers.shouldBe + * + * fun main() { + * effect { + * val x = Either.Right(1).bind() + * val y = Validated.Valid(2).bind() + * val z = + * attempt { None.bind { "Option was empty" } } catch { 0 } + * x + y + z + * }.fold({ fail("Shift can never be the result") }, { it shouldBe 3 }) * ``` - * attempt { ... } catch { ... } - * ``` + * */ public suspend infix fun (suspend EffectScope.() -> A).catch( recover: EffectScope.(E) -> A, From b77ce5091f25aecbd96a32bad8fe8b3e13dd165b Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 8 Jul 2022 19:41:23 +0200 Subject: [PATCH 09/14] Add missing files + apply suggestions --- .../core/continuations/EagerEffectScope.kt | 4 ++-- .../arrow/core/continuations/EffectScope.kt | 4 ++-- .../arrow/core/continuations/EffectSpec.kt | 6 +++++- .../examples/example-eager-effect-scope-08.kt | 19 ++++++++++------- .../examples/example-eager-effect-scope-09.kt | 16 ++++++++++++++ .../examples/example-effect-scope-09.kt | 21 +++++++++++-------- .../examples/example-effect-scope-10.kt | 16 ++++++++++++++ 7 files changed, 64 insertions(+), 22 deletions(-) create mode 100644 arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-09.kt create mode 100644 arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-10.kt diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt index 1c4235d5ce4..4ab6cb68d2b 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt @@ -232,7 +232,7 @@ public interface EagerEffectScope { * x + y + z * }.fold({ fail("Shift can never be the result") }, { it shouldBe 3 }) * ``` - * + * */ public infix fun (suspend EagerEffectScope.() -> A).catch( recover: EagerEffectScope.(E) -> A, @@ -258,7 +258,7 @@ public interface EagerEffectScope { * }.toEither() shouldBe (int?.right() ?: failure.left()) * } * ``` - * + * */ @OptIn(ExperimentalContracts::class) public suspend fun EagerEffectScope.ensureNotNull(value: B?, shift: () -> R): B { diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt index 50aa14025f9..22824d7a90f 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt @@ -257,7 +257,7 @@ public interface EffectScope { * x + y + z * }.fold({ fail("Shift can never be the result") }, { it shouldBe 3 }) * ``` - * + * */ public suspend infix fun (suspend EffectScope.() -> A).catch( recover: EffectScope.(E) -> A, @@ -283,7 +283,7 @@ public interface EffectScope { * }.toEither() shouldBe (int?.right() ?: failure.left()) * } * ``` - * + * */ @OptIn(ExperimentalContracts::class) public suspend fun EffectScope.ensureNotNull(value: B?, shift: () -> R): B { diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt index 901840fae07..82e0b4b019e 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt @@ -8,7 +8,11 @@ import io.kotest.assertions.fail import io.kotest.core.spec.style.StringSpec import io.kotest.matchers.shouldBe import io.kotest.property.Arb -import io.kotest.property.arbitrary.* +import io.kotest.property.arbitrary.boolean +import io.kotest.property.arbitrary.int +import io.kotest.property.arbitrary.long +import io.kotest.property.arbitrary.orNull +import io.kotest.property.arbitrary.string import io.kotest.property.checkAll import kotlin.coroutines.Continuation import kotlin.coroutines.CoroutineContext diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-08.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-08.kt index 4f62bcbc504..980cfc54314 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-08.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-08.kt @@ -1,16 +1,19 @@ // This file was automatically generated from EagerEffectScope.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEagerEffectScope08 +import arrow.core.Either +import arrow.core.None +import arrow.core.Option +import arrow.core.Validated import arrow.core.continuations.eagerEffect -import arrow.core.continuations.ensureNotNull -import arrow.core.left -import arrow.core.right +import io.kotest.assertions.fail import io.kotest.matchers.shouldBe fun main() { - val failure = "failed" - val int: Int? = null eagerEffect { - ensureNotNull(int) { failure } - }.toEither() shouldBe (int?.right() ?: failure.left()) -} + val x = Either.Right(1).bind() + val y = Validated.Valid(2).bind() + val z = + attempt { None.bind { "Option was empty" } } catch { 0 } + x + y + z + }.fold({ fail("Shift can never be the result") }, { it shouldBe 3 }) diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-09.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-09.kt new file mode 100644 index 00000000000..9bd00d04b02 --- /dev/null +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-09.kt @@ -0,0 +1,16 @@ +// This file was automatically generated from EagerEffectScope.kt by Knit tool. Do not edit. +package arrow.core.examples.exampleEagerEffectScope09 + +import arrow.core.continuations.eagerEffect +import arrow.core.continuations.ensureNotNull +import arrow.core.left +import arrow.core.right +import io.kotest.matchers.shouldBe + +fun main() { + val failure = "failed" + val int: Int? = null + eagerEffect { + ensureNotNull(int) { failure } + }.toEither() shouldBe (int?.right() ?: failure.left()) +} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-09.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-09.kt index dc5178b8589..e2011e04963 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-09.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-09.kt @@ -1,16 +1,19 @@ // This file was automatically generated from EffectScope.kt by Knit tool. Do not edit. package arrow.core.examples.exampleEffectScope09 +import arrow.core.Either +import arrow.core.None +import arrow.core.Option +import arrow.core.Validated import arrow.core.continuations.effect -import arrow.core.continuations.ensureNotNull -import arrow.core.left -import arrow.core.right +import io.kotest.assertions.fail import io.kotest.matchers.shouldBe -suspend fun main() { - val failure = "failed" - val int: Int? = null +fun main() { effect { - ensureNotNull(int) { failure } - }.toEither() shouldBe (int?.right() ?: failure.left()) -} + val x = Either.Right(1).bind() + val y = Validated.Valid(2).bind() + val z = + attempt { None.bind { "Option was empty" } } catch { 0 } + x + y + z + }.fold({ fail("Shift can never be the result") }, { it shouldBe 3 }) diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-10.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-10.kt new file mode 100644 index 00000000000..0d0dc84b89e --- /dev/null +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-10.kt @@ -0,0 +1,16 @@ +// This file was automatically generated from EffectScope.kt by Knit tool. Do not edit. +package arrow.core.examples.exampleEffectScope10 + +import arrow.core.continuations.effect +import arrow.core.continuations.ensureNotNull +import arrow.core.left +import arrow.core.right +import io.kotest.matchers.shouldBe + +suspend fun main() { + val failure = "failed" + val int: Int? = null + effect { + ensureNotNull(int) { failure } + }.toEither() shouldBe (int?.right() ?: failure.left()) +} From c08c23612a1f3f302804c5eaaaac50f8d5e8c153 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 8 Jul 2022 20:25:25 +0200 Subject: [PATCH 10/14] Fix Knit examples --- .../kotlin/arrow/core/continuations/EagerEffectScope.kt | 1 + .../commonMain/kotlin/arrow/core/continuations/EffectScope.kt | 3 ++- .../jvmTest/kotlin/examples/example-eager-effect-scope-08.kt | 1 + .../src/jvmTest/kotlin/examples/example-effect-scope-09.kt | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt index 4ab6cb68d2b..2eedc8bf645 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt @@ -231,6 +231,7 @@ public interface EagerEffectScope { * attempt { None.bind { "Option was empty" } } catch { 0 } * x + y + z * }.fold({ fail("Shift can never be the result") }, { it shouldBe 3 }) + * } * ``` * */ diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt index 22824d7a90f..1a0a44706cc 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt @@ -248,7 +248,7 @@ public interface EffectScope { * import io.kotest.assertions.fail * import io.kotest.matchers.shouldBe * - * fun main() { + * suspend fun main() { * effect { * val x = Either.Right(1).bind() * val y = Validated.Valid(2).bind() @@ -256,6 +256,7 @@ public interface EffectScope { * attempt { None.bind { "Option was empty" } } catch { 0 } * x + y + z * }.fold({ fail("Shift can never be the result") }, { it shouldBe 3 }) + * } * ``` * */ diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-08.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-08.kt index 980cfc54314..a68c64d66ca 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-08.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-eager-effect-scope-08.kt @@ -17,3 +17,4 @@ fun main() { attempt { None.bind { "Option was empty" } } catch { 0 } x + y + z }.fold({ fail("Shift can never be the result") }, { it shouldBe 3 }) +} diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-09.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-09.kt index e2011e04963..4b4ffa3eb7b 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-09.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-scope-09.kt @@ -9,7 +9,7 @@ import arrow.core.continuations.effect import io.kotest.assertions.fail import io.kotest.matchers.shouldBe -fun main() { +suspend fun main() { effect { val x = Either.Right(1).bind() val y = Validated.Valid(2).bind() @@ -17,3 +17,4 @@ fun main() { attempt { None.bind { "Option was empty" } } catch { 0 } x + y + z }.fold({ fail("Shift can never be the result") }, { it shouldBe 3 }) +} From 1e1f63eea5861f7a3a1c1408544d4a935ba85b48 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Mon, 18 Jul 2022 20:50:35 +0200 Subject: [PATCH 11/14] Introduce forgotten suspend in catch for EffectScope --- arrow-libs/core/arrow-core/api/arrow-core.api | 18 +++++++++--------- .../arrow/core/continuations/EffectScope.kt | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arrow-libs/core/arrow-core/api/arrow-core.api b/arrow-libs/core/arrow-core/api/arrow-core.api index cb8eada36c9..fc33b4f3d0d 100644 --- a/arrow-libs/core/arrow-core/api/arrow-core.api +++ b/arrow-libs/core/arrow-core/api/arrow-core.api @@ -2699,7 +2699,7 @@ public abstract interface class arrow/core/continuations/EffectScope { public abstract fun bind (Larrow/core/continuations/EagerEffect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun bind (Larrow/core/continuations/Effect;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 catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public abstract fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun shift (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } @@ -2712,7 +2712,7 @@ public final class arrow/core/continuations/EffectScope$DefaultImpls { public static fun bind (Larrow/core/continuations/EffectScope;Larrow/core/continuations/EagerEffect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EffectScope;Larrow/core/continuations/Effect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static fun catch (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun catch (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun ensure (Larrow/core/continuations/EffectScope;ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } @@ -2755,7 +2755,7 @@ public final class arrow/core/continuations/IorEffectScope : arrow/core/continua public fun bind (Larrow/core/continuations/EagerEffect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/continuations/Effect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun combine (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getLeftState ()Ljava/util/concurrent/atomic/AtomicReference; @@ -2818,8 +2818,8 @@ public final class arrow/core/continuations/NullableEffectScope : arrow/core/con public static final fun bind-impl (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final synthetic fun box-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/NullableEffectScope; - public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static fun catch-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun catch-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun constructor-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/EffectScope; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun ensure-impl (Larrow/core/continuations/EffectScope;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2893,8 +2893,8 @@ public final class arrow/core/continuations/OptionEffectScope : arrow/core/conti public static fun bind-impl (Larrow/core/continuations/EffectScope;Larrow/core/continuations/Effect;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final synthetic fun box-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/OptionEffectScope; - public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static fun catch-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun catch-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun constructor-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/EffectScope; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun ensure-impl (Larrow/core/continuations/EffectScope;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2969,8 +2969,8 @@ public final class arrow/core/continuations/ResultEffectScope : arrow/core/conti public static final fun bind-impl (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun bind-impl (Larrow/core/continuations/EffectScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final synthetic fun box-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/ResultEffectScope; - public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static fun catch-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun catch-impl (Larrow/core/continuations/EffectScope;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun constructor-impl (Larrow/core/continuations/EffectScope;)Larrow/core/continuations/EffectScope; public fun ensure (ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun ensure-impl (Larrow/core/continuations/EffectScope;ZLkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt index 1a0a44706cc..8a6a5b46466 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt @@ -261,7 +261,7 @@ public interface EffectScope { * */ public suspend infix fun (suspend EffectScope.() -> A).catch( - recover: EffectScope.(E) -> A, + recover: suspend EffectScope.(E) -> A, ): A = effect(this).fold({ recover(it) }, ::identity) } From 93564cf469414fae367ea5f0490da54980b4c2a6 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Tue, 19 Jul 2022 13:14:16 +0200 Subject: [PATCH 12/14] Update arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt Co-authored-by: Imran Malic Settuba <46971368+i-walker@users.noreply.github.com> --- .../kotlin/arrow/core/continuations/EagerEffectScope.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt index 2eedc8bf645..1147ffa2371 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt @@ -236,7 +236,7 @@ public interface EagerEffectScope { * */ public infix fun (suspend EagerEffectScope.() -> A).catch( - recover: EagerEffectScope.(E) -> A, + recover: suspend EagerEffectScope.(E) -> A, ): A = eagerEffect(this).fold({ recover(it) }, ::identity) } From f3907a491fc1c53bb4a46f1efd516b324241717c Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Tue, 19 Jul 2022 13:44:59 +0200 Subject: [PATCH 13/14] Remove suspend from EagerEffectScope.catch --- .../kotlin/arrow/core/continuations/EagerEffectScope.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt index 1147ffa2371..2eedc8bf645 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt @@ -236,7 +236,7 @@ public interface EagerEffectScope { * */ public infix fun (suspend EagerEffectScope.() -> A).catch( - recover: suspend EagerEffectScope.(E) -> A, + recover: EagerEffectScope.(E) -> A, ): A = eagerEffect(this).fold({ recover(it) }, ::identity) } From 81b07110e5ec3271b2b7329903e6fe2ad53e60b0 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Wed, 20 Jul 2022 16:18:13 +0200 Subject: [PATCH 14/14] Add attempt/catch test for EagerEffect --- .../core/continuations/EagerEffectSpec.kt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt index 040657f0991..7c32aeae4c4 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt @@ -10,6 +10,7 @@ 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.orNull import io.kotest.property.arbitrary.string import io.kotest.property.checkAll @@ -57,6 +58,32 @@ class EagerEffectSpec : StringSpec({ } } + "attempt - catch" { + checkAll(Arb.int(), Arb.long()) { i, l -> + eagerEffect { + attempt { + shift(l) + } catch { ll -> + ll shouldBe l + i + } + }.runCont() shouldBe i + } + } + + "attempt - no catch" { + checkAll(Arb.int(), Arb.long()) { i, l -> + eagerEffect { + attempt { + i + } catch { ll -> + ll shouldBe l + i + 1 + } + }.runCont() shouldBe i + } + } + "immediate values" { eagerEffect { 1 }.toEither().orNull() shouldBe 1 } "immediate short-circuit" { eagerEffect { shift("hello") }.runCont() shouldBe "hello" }