Сравнение шаблонов на кортежах в Котлине

У меня есть следующий фрагмент кода

fun changeSelection(item: FileOrFolder, selected: Boolean) {
    selection = when(item) {
        is Folder -> {
            when(selected) {
                true -> selection + item
                false -> selection - item
            }
        }
        is File -> {
            when(selected) {
                true -> selection + item
                false -> selection - item
            }
        }
        else -> throw Exception("unreachable")
    }
}

который выглядит как-то загроможденным для меня, когда я привык к этому в scala

def changeSelection(item: FileOrFolder, selected: Boolean) {
    (item, selected) match {
        case (item: Folder, true) => selection + item
        case (item: Folder, false) => selection - item
        case (item: File, true) => selection + item
        case (item: File, false) => selection - item
    }
}

Есть ли способ добиться чего-то подобного в Котлин?

Ответ 1

Ну, для Scala ради вы можете написать:

fun changeSelection(item: FileOrFolder, selected: Boolean) {
    selection = when {
        item is Folder &&  selected -> selection + item
        item is Folder && !selected -> selection - item
        item is File   &&  selected -> selection + item
        item is File   && !selected -> selection - item
        else -> throw Exception()
    }
}

Более прямой вариант:

fun changeSelection(item: FileOrFolder, selected: Boolean) {
    selection = if(selected)
        when(item) {
            is Folder -> selection + item
            is File   -> selection + item
            else -> throw Exception()
        }
    else
        when(item) {
            is Folder -> selection - item
            is File   -> selection - item
            else -> throw Exception()
        }
}

Но я определенно предпочитаю:

operator fun Selection.plus(f: FileOrFolder) = ...
operator fun Selection.minus(f: FileOrFolder) = ...

fun changeSelection(item: FileOrFolder, selected: Boolean) {
    if(selected)
        selection += item
    else 
        selection -= item
}