raulraja
05/21/2018, 11:32 AM// type class
interface Monoid<A> {
fun A.combine(b: A): A
val empty: A
}
// instance
extension object IntMonoid : Monoid<Int> {
fun Int.combine(b: Int): Int = this + b
val empty: Int = 0
}
// polimorphic function or class that depends on `Monoid`
fun <A> add(a: A, b: A, with Monoid<A>): A = a.combine(b)
add(1, 1) // compiles
add("a", "b") // does not compile: No `Monoid<String>` instance defined in scope
add
may desugar to:
fun <A> add(a: A, b: A, $ev: Monoid<A>): A = $ev.run { a.combine(b) }