А зачем нужны тайпклассы, когда есть интерфейсы?
Чтобы навешивать конкретные операторы на существующие классы. К примеру, под один интерфейс с общим набором экстеншнов вы просто так не подведёте, к примеру, List и Observable из Rx. Кроме того, Arrow со своими kinds частично решает, насколько я знаю, ещё и отсутствие в языке селф-типов. Кому-то, к примеру, очень претит тот факт, что setOf(1, 2, 3).map { it * 2 }
возвращает в котлине List<Int>
.
Хочу отметить, что я не агитирую за то, что в котлине это необходимо, просто отмечаю, чем это может быть полезно, и почему этого могут хотеть другие.