@@ -2,6 +2,8 @@ package effekt
2
2
3
3
import Prompt
4
4
import abortS0
5
+ import ask
6
+ import context
5
7
import pushPrompt
6
8
import reset
7
9
import shift0
@@ -11,13 +13,24 @@ import kotlin.jvm.JvmInline
11
13
12
14
public interface Handler <E > {
13
15
public fun prompt (): HandlerPrompt <E >
16
+ public suspend fun <T > Reader<T>.get (): T = ask()
17
+ public suspend fun <T > Reader<T>.set (value : T ): Unit = useWithContext { k, _ ->
18
+ k(Unit , context(value))
19
+ }
14
20
}
15
21
22
+ public interface StatefulHandler <E , S > : Handler <E >, Reader <S >
23
+
24
+ public suspend fun <A , E , S > StatefulHandler <E , S >.useStateful (body : suspend (suspend (A , S ) -> E , S ) -> E ): A =
25
+ useWithContext { k, ctx ->
26
+ body({ a, s -> k(a, context(s)) }, ctx[this ]!! .value)
27
+ }
28
+
16
29
public suspend fun <A , E > Handler<E>.use (body : suspend (Cont <A , E >) -> E ): A = prompt().prompt.shift0(body)
17
30
public fun <E > Handler<E>.discard (body : suspend () -> E ): Nothing = prompt().prompt.abortS0(body)
18
- public suspend fun <A , E > Handler<E>.useStateful (body : suspend (suspend (A , CoroutineContext ) -> E ) -> E ): A =
31
+ public suspend fun <A , E > Handler<E>.useWithContext (body : suspend (suspend (A , CoroutineContext ) -> E , CoroutineContext ) -> E ): A =
19
32
prompt().prompt.takeSubCont { sk ->
20
- body { a, ctx -> sk.pushSubContWith(Result .success(a), isDelimiting = true , extraContext = ctx) }
33
+ body( { a, ctx -> sk.pushSubContWith(Result .success(a), isDelimiting = true , extraContext = ctx) }, sk.extraContext)
21
34
}
22
35
23
36
public suspend fun <E , H > handle (
@@ -28,18 +41,32 @@ public suspend fun <E> handle(body: suspend HandlerPrompt<E>.() -> E): E = with(
28
41
handle { body() }
29
42
}
30
43
31
- public suspend fun <E > HandlerPrompt <E>.handle (body : suspend () -> E ): E = prompt.reset(body)
44
+ public suspend fun <E > Handler <E>.handle (body : suspend () -> E ): E = prompt(). prompt.reset(body)
32
45
33
- public suspend fun <E , H > handleStateful (
46
+ public suspend fun <E , H > handleWithContext (
34
47
handler : ((() -> HandlerPrompt <E >) -> H ), extraContext : CoroutineContext , body : suspend H .() -> E
35
- ): E = handleStateful (extraContext) { handler { this }.body() }
48
+ ): E = handleWithContext (extraContext) { handler { this }.body() }
36
49
37
- public suspend fun <E > handleStateful (extraContext : CoroutineContext , body : suspend HandlerPrompt <E >.() -> E ): E =
38
- HandlerPrompt <E >().handleStateful(extraContext, body)
50
+ public suspend fun <E > handleWithContext (extraContext : CoroutineContext , body : suspend HandlerPrompt <E >.() -> E ): E =
51
+ with (HandlerPrompt <E >()) {
52
+ handleWithContext(extraContext) { body() }
53
+ }
54
+
55
+ public suspend fun <E > Handler<E>.handleWithContext (
56
+ extraContext : CoroutineContext , body : suspend () -> E
57
+ ): E = prompt().prompt.pushPrompt(extraContext, body = body)
58
+
59
+ public suspend fun <E , H : StatefulHandler <E , S >, S > handleStateful (
60
+ handler : ((() -> HandlerPrompt <E >) -> H ), value : S , body : suspend H .() -> E
61
+ ): E {
62
+ val p = HandlerPrompt <E >()
63
+ val h = handler { p }
64
+ return h.handleStateful(value) { h.body() }
65
+ }
39
66
40
- public suspend fun <E > HandlerPrompt<E >.handleStateful (
41
- extraContext : CoroutineContext , body : suspend HandlerPrompt < E >. () -> E
42
- ): E = prompt.pushPrompt(extraContext) { body() }
67
+ public suspend fun <E , S > StatefulHandler < E , S >.handleStateful (
68
+ value : S , body : suspend () -> E
69
+ ): E = handleWithContext(context(value), body)
43
70
44
71
@JvmInline
45
72
public value class HandlerPrompt <E > private constructor(internal val prompt : Prompt <E >) : Handler<E> {
0 commit comments