Skip to content

Instantly share code, notes, and snippets.

@nomisRev
Created April 20, 2022 06:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nomisRev/6c31a24e6d0dbf0106b10a9048162929 to your computer and use it in GitHub Desktop.
Save nomisRev/6c31a24e6d0dbf0106b10a9048162929 to your computer and use it in GitHub Desktop.
Context Receivers lambdas
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import kotlin.time.ExperimentalTime
import kotlin.time.measureTimedValue
interface Logging {
fun info(msg: String): Unit
companion object Default : Logging {
override fun info(msg: String) = println("INFO: $msg")
}
}
interface Tracing {
suspend fun <A> trace(span: String, f: suspend () -> A): A = f()
companion object Default : Tracing {
@OptIn(ExperimentalTime::class)
override suspend fun <A> trace(span: String, f: suspend () -> A): A {
println("TRACE: Starting operation $span")
val (result, duration) = measureTimedValue { f() }
println("TRACE: Operation $span took $duration")
return result
}
}
}
context(Tracing, Logging)
suspend fun program() = trace("program") {
info("Hello World Context Receivers!")
}
suspend fun main() {
with(Logging, Tracing) {
program()
}
}
@OptIn(ExperimentalContracts::class)
inline fun <A, B, R> with(a: A, b: B, block: context(A, B) (TypeWrapper<B>) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(a, b, TypeWrapper.IMPL)
}
sealed interface TypeWrapper<out A> {
object IMPL: TypeWrapper<Nothing>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment