interface Monoid : Semigroup { abstract val unit: T abstract get } interface Semigroup { abstract infix fun T.combine(other: T): T } object IntMonoid : Monoid { override val unit: Int field = 0 override get private constructor() /* primary */ { super/*Any*/() /* () */ } override infix fun Int.combine(other: Int): Int { return .plus(other = other) } } object StringMonoid : Monoid { override val unit: String field = "" override get private constructor() /* primary */ { super/*Any*/() /* () */ } override infix fun String.combine(other: String): String { return .plus(other = other) } } fun box(): String { with(receiver = IntMonoid, block = local fun IntMonoid.(): Int { return listOf(elements = [1, 2, 3]).sum($context_receiver_0 = $this$with) } ) /*~> Unit */ return with(receiver = StringMonoid, block = local fun StringMonoid.(): String { return listOf(elements = ["O", "K"]).sum($context_receiver_0 = $this$with) } ) } fun List.sum($context_receiver_0: Monoid): T { return .fold(initial = $context_receiver_0.(), operation = local fun (acc: @ParameterName(name = "acc") T, e: T): T { return ($context_receiver_0, acc).combine(other = e) } ) }