commonMain.effekt.handler.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kontinuity-jvm Show documentation
Show all versions of kontinuity-jvm Show documentation
Provides fully-fledged multishot delimitied continuations in Kotlin with Coroutines
The newest version!
package effekt
import Prompt
import Reader
import abortS0
import abortWith0
import abortWithFast
import ask
import pushReader
import reset
import takeSubCont
import takeSubContOnce
import takeSubContWithFinal
import kotlin.jvm.JvmInline
public interface Handler {
public fun prompt(): HandlerPrompt
}
public interface StatefulHandler : Handler {
public val reader: Reader
}
public suspend fun StatefulHandler.get(): S = reader.ask()
public suspend inline fun Handler.use(crossinline body: suspend (Cont) -> E): A =
prompt().prompt.takeSubCont { sk ->
body(Cont(sk))
}
public suspend inline fun Handler.useOnce(crossinline body: suspend (Cont) -> E): A =
prompt().prompt.takeSubContOnce { sk ->
body(Cont(sk))
}
public suspend inline fun Handler.useWithFinal(crossinline body: suspend (Pair, Cont>) -> E): A =
prompt().prompt.takeSubContWithFinal { sk ->
body(Cont(sk.first) to Cont(sk.second))
}
public fun Handler.discard(body: suspend () -> E): Nothing = prompt().prompt.abortS0(body)
public fun Handler.discardWith(value: Result): Nothing = prompt().prompt.abortWith0(value)
public suspend fun Handler.discardWithFast(value: Result): Nothing = prompt().prompt.abortWithFast(deleteDelimiter = true, value)
public suspend fun handle(
handler: ((() -> HandlerPrompt) -> H), body: suspend H.() -> E
): E = handle { handler { this }.body() }
public suspend fun handle(body: suspend HandlerPrompt.() -> E): E = with(HandlerPrompt()) {
handle { body() }
}
public suspend fun Handler.handle(body: suspend () -> E): E = prompt().prompt.reset(body)
public suspend fun , S> handleStateful(
handler: ((() -> StatefulPrompt) -> H), value: S, fork: S.() -> S,
body: suspend H.() -> E
): E {
val p = StatefulPrompt()
val h = handler { p }
return h.handleStateful(value, fork) { h.body() }
}
public suspend fun handleStateful(
value: S, fork: S.() -> S, body: suspend StatefulPrompt.() -> E
): E = with(StatefulPrompt()) {
handleStateful(value, fork) { body() }
}
public suspend fun StatefulHandler.handleStateful(
value: S, fork: S.() -> S,
body: suspend () -> E
): E = reader.pushReader(value, fork) {
prompt().prompt.reset(body)
}
@JvmInline
public value class HandlerPrompt private constructor(@PublishedApi internal val prompt: Prompt) : Handler {
public constructor() : this(Prompt())
override fun prompt(): HandlerPrompt = this
}
public class StatefulPrompt(
private val prompt: HandlerPrompt = HandlerPrompt(), override val reader: Reader = Reader()
) : StatefulHandler, Handler by prompt
@JvmInline
public value class Cont @PublishedApi internal constructor(internal val subCont: SubCont) {
public suspend fun resumeWith(value: Result, shouldClear: Boolean = false): R =
subCont.pushSubContWith(value, isDelimiting = true, shouldClear)
public suspend operator fun invoke(value: T, shouldClear: Boolean = false): R =
resumeWith(Result.success(value), shouldClear)
public suspend fun resumeWithException(exception: Throwable, shouldClear: Boolean = false): R =
resumeWith(Result.failure(exception), shouldClear)
public fun copy(): Cont = Cont(subCont.copy())
public fun clear() { subCont.clear() }
}