@@ -5,9 +5,8 @@ import arrow.core.Either.Left
5
5
import arrow.core.Either.Right
6
6
import arrow.higherkind
7
7
import arrow.typeclasses.Show
8
+ import arrow.typeclasses.suspended.BindSyntax
8
9
import kotlin.coroutines.Continuation
9
- import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
10
- import kotlin.coroutines.intrinsics.startCoroutineUninterceptedOrReturn
11
10
import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
12
11
13
12
/* *
@@ -651,6 +650,7 @@ import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
651
650
* import arrow.core.extensions.fx
652
651
* import arrow.core.Either
653
652
*
653
+ * suspend fun main() {
654
654
* val value =
655
655
* //sampleStart
656
656
* Either.fx<Int, Int> {
@@ -660,7 +660,6 @@ import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
660
660
* a + b + c
661
661
* }
662
662
* //sampleEnd
663
- * fun main() {
664
663
* println(value)
665
664
* }
666
665
* ```
@@ -901,6 +900,21 @@ sealed class Either<out A, out B> : EitherOf<A, B> {
901
900
} catch (t: Throwable ) {
902
901
fe(t.nonFatalOrThrow()).left()
903
902
}
903
+
904
+ fun <E , A > fx2 (c : suspend EagerBind <EitherPartialOf <E >>.() -> A ): Either <E , A > {
905
+ val continuation: EitherContinuation <E , A > = EitherContinuation ()
906
+ return continuation.startCoroutineUninterceptedAndReturn {
907
+ Right (c())
908
+ } as Either <E , A >
909
+ }
910
+
911
+ suspend fun <E , A > fx (c : suspend BindSyntax <EitherPartialOf <E >>.() -> A ): Either <E , A > =
912
+ suspendCoroutineUninterceptedOrReturn sc@{ cont ->
913
+ val continuation = EitherSContinuation (cont as Continuation <EitherOf <E , A >>)
914
+ continuation.startCoroutineUninterceptedOrReturn {
915
+ Right (c())
916
+ }
917
+ }
904
918
}
905
919
}
906
920
@@ -1102,29 +1116,20 @@ fun <A, B> EitherOf<A, B>.handleErrorWith(f: (A) -> EitherOf<A, B>): Either<A, B
1102
1116
}
1103
1117
}
1104
1118
1105
- suspend fun <E , A > Either.Companion.fx (c : suspend EitherContinuation <E , A >.() -> A ): Either <E , A > =
1106
- suspendCoroutineUninterceptedOrReturn sc@{ cont ->
1107
- val continuation = EitherContinuation (cont as Continuation <EitherOf <E , A >>)
1108
- val wrapReturn: suspend EitherContinuation <E , A >.() -> Either <E , A > = { c().right() }
1109
-
1110
- // Returns either `Either<A, B>` or `COROUTINE_SUSPENDED`
1111
- val x: Any? = try {
1112
- wrapReturn.startCoroutineUninterceptedOrReturn(continuation, continuation)
1113
- } catch (e: Throwable ) {
1114
- if (e is SuspendMonadContinuation .ShortCircuit ) Left (e.e as E )
1115
- else throw e
1116
- }
1117
-
1118
- return @sc if (x == COROUTINE_SUSPENDED ) continuation.getResult()
1119
- else x as Either <E , A >
1120
- }
1121
-
1122
- class EitherContinuation <E , A >(
1119
+ internal class EitherSContinuation <E , A >(
1123
1120
parent : Continuation <EitherOf <E , A >>
1124
1121
) : SuspendMonadContinuation<EitherPartialOf<E>, A>(parent) {
1122
+ override fun ShortCircuit.recover (): Kind <EitherPartialOf <E >, A> =
1123
+ Left (value as E )
1124
+
1125
1125
override suspend fun <A > Kind <EitherPartialOf <E >, A>.bind (): A =
1126
1126
fix().fold({ e -> throw ShortCircuit (e) }, ::identity)
1127
+ }
1127
1128
1129
+ internal class EitherContinuation <E , A > : MonadContinuation <EitherPartialOf <E >, A >() {
1128
1130
override fun ShortCircuit.recover (): Kind <EitherPartialOf <E >, A> =
1129
- Left (e as E )
1131
+ Left (value as E )
1132
+
1133
+ override suspend fun <A > Kind <EitherPartialOf <E >, A>.bind (): A =
1134
+ fix().fold({ e -> throw ShortCircuit (e) }, ::identity)
1130
1135
}
0 commit comments