I was looking at this and thinking about how to avoid implicits, but it seems like if that’s an important design parameter, typeclasses can/should just be done in the existing type system with an adapter-like pattern. I don’t like it, but having *some* way to do it is better than nothing. Sticking with @alex_delattre’s proposed syntax, here’s what it would look like:

```
interface Monoid<A> {
fun zero(): A
fun add(a1: A, a2: A): A
}
val stringMonoid = object : Monoid<String> {
override fun zero() = ""
override fun add(a1: String, a2: String) = a1 + a2
}
fun<A> multiply(a: A, n: Int, M: Monoid<A>) {
var result: A = M.zero()
for (i in 1 to n) {
result = M.add(result, a)
}
return result
}
```

That seems like more-or-less the least common denominator of what JetBrains is willing to give us and the functionality people want (and it’s already possible).

One language feature that *would* make this pattern nicer (and maybe not break everything) is currying. Obviously we can mock currying with HOFs, but there’s non-negligible friction in doing things that way. With currying we could just do something like:

```
fun<A> multiply(M: Monoid<A>)(a: A, n: Int) {
// ...
}
fun<A, B> funUsingTwoMonoids(aMonoid: Monoid<A>, bMonoid: Monoid<B>) {
val aMult = multiply(aMonoid)
val bMult = multiply(bMonoid)
// do something, multiply some stuff
}
```