// !LANGUAGE: +ContextReceivers // TARGET_BACKEND: JVM_IR // WITH_STDLIB interface Semigroup { infix fun T.combine(other: T): T } interface Monoid : Semigroup { val unit: T } object IntMonoid : Monoid { override fun Int.combine(other: Int): Int = this + other override val unit: Int = 0 } object StringMonoid : Monoid { override fun String.combine(other: String): String = this + other override val unit: String = "" } context(Monoid) fun List.sum(): T = fold(unit) { acc, e -> acc.combine(e) } fun box(): String { with(IntMonoid) { listOf(1, 2, 3).sum() } return with(StringMonoid) { listOf("O", "K").sum() } }