<@UAV6BQPP1> To add to what <@U0B8UEMV1> mentioned...
# arrow
r
@Allan Wang To add to what @pakoito mentioned type classes have the following anatomy: Type class: Interface declaration parametric to one type argument: Ex:
Comparator<A>
Data type: Target data type of the type you want to enhance or support with polymorphism: Ex:
Int
Instance: A decoupled proof that at compile time we can verify to establish that a given instance couples a behavior to a data type: Ex:
Comparator<Int>
If the compiler has the notion of this bridging instance is able to inject it implicitly where needed:
Copy code
fun <A> compare(a: A, b: A, with comparator: Comparator<A>): Int = a.compareTo(b)

compare(1, 2) // no need to provide `comparator` as an argument because the compiler is able to resolve it in the companion or subpackages of either `Comparator` or `Int` or in the users local name space if the instance is flagged as `internal` therefore non-exportable

compare("1", "2") // does not compile because no instance of type `Comparator<String>` is found.
The compiler here is able to find instances and inject them implicitly activating all the type class functions and extension over the surrounding scope. without type class all you can do is:
Copy code
fun compare(a: Int, b: Int,  comparator: Comparator<Int>): Int = with (comparator) { a.compareTo(b) }