-
Notifications
You must be signed in to change notification settings - Fork 451
/
Copy pathior.kt
98 lines (84 loc) · 3.22 KB
/
ior.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package arrow.core.continuations
import arrow.core.EmptyValue
import arrow.core.Ior
import arrow.core.identity
import arrow.typeclasses.Semigroup
@Deprecated(iorDSLDeprecation, ReplaceWith("ior", "arrow.core.raise.ior"))
@Suppress("ClassName")
public object ior {
@Deprecated(iorDSLDeprecation, ReplaceWith("ior(semigroup, f)", "arrow.core.raise.ior"))
public inline fun <E, A> eager(
semigroup: Semigroup<E>,
crossinline f: suspend IorEagerEffectScope<E>.() -> A
): Ior<E, A> =
eagerEffect<E, Ior<E, A>> {
val effect = IorEagerEffectScope(semigroup, this)
@Suppress("ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL")
val res = f(effect)
val leftState = effect.leftState.get()
if (leftState === EmptyValue) Ior.Right(res) else Ior.Both(EmptyValue.unbox(leftState), res)
}.fold({ Ior.Left(it) }, ::identity)
@Deprecated(iorDSLDeprecation, ReplaceWith("ior(semigroup, f)", "arrow.core.raise.ior"))
public suspend inline operator fun <E, A> invoke(
semigroup: Semigroup<E>,
crossinline f: suspend IorEffectScope<E>.() -> A
): Ior<E, A> =
effect<E, Ior<E, A>> {
val effect = IorEffectScope(semigroup, this)
val res = f(effect)
val leftState = effect.leftState.get()
if (leftState === EmptyValue) Ior.Right(res) else Ior.Both(EmptyValue.unbox(leftState), res)
}.fold({ Ior.Left(it) }, ::identity)
}
@Deprecated(
"IorEffectScope<E> is replaced with arrow.core.raise.IorRaise<E>",
ReplaceWith("IorRaise<E>", "arrow.core.raise.IorRaise")
)
public class IorEffectScope<E>(semigroup: Semigroup<E>, private val effect: EffectScope<E>) :
EffectScope<E>, Semigroup<E> by semigroup {
@PublishedApi
internal var leftState: AtomicRef<Any?> = AtomicRef(EmptyValue)
private fun combine(other: E): E =
leftState.updateAndGet { state ->
if (state === EmptyValue) other else EmptyValue.unbox<E>(state).combine(other)
} as
E
public suspend fun <B> Ior<E, B>.bind(): B =
when (this) {
is Ior.Left -> shift(value)
is Ior.Right -> value
is Ior.Both -> {
combine(leftValue)
rightValue
}
}
override suspend fun <B> shift(r: E): B = effect.shift(combine(r))
}
@Deprecated(
"IorEagerEffectScope<E> is replaced with arrow.core.raise.IorRaise<E>",
ReplaceWith("IorRaise<E>", "arrow.core.raise.IorRaise")
)
public class IorEagerEffectScope<E>(semigroup: Semigroup<E>, private val effect: EagerEffectScope<E>) :
EagerEffectScope<E>, Semigroup<E> by semigroup {
@PublishedApi
internal var leftState: AtomicRef<Any?> = AtomicRef(EmptyValue)
private fun combine(other: E): E =
leftState.updateAndGet { state ->
if (state === EmptyValue) other else EmptyValue.unbox<E>(state).combine(other)
} as
E
public suspend fun <B> Ior<E, B>.bind(): B =
when (this) {
is Ior.Left -> shift(value)
is Ior.Right -> value
is Ior.Both -> {
combine(leftValue)
rightValue
}
}
@Suppress("ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL")
override suspend fun <B> shift(r: E): B = effect.shift(combine(r))
}
private const val iorDSLDeprecation =
"The ior DSL has been moved to arrow.core.raise.ior.\n" +
"Replace import arrow.core.computations.ior with arrow.core.raise.ior"