Можно ли использовать функции высокого порядка с необязательными аргументами

Я собрал фиктивную проблему, чтобы проиллюстрировать мою мысль: скажем, что у нас есть следующая удобная функция для отображения информации об определенном алгоритме сортировки:

fun sort(name: String, array: Array<Int>, sortingAlgorithm: (Array<Int>) -> Array<Int>) { println(name) sortingAlgorithm(array).forEach { print(" $it ") } println() } 

Вы бы использовали его так:

 sort("Selection Sort - Θ(n^2)", arrayOf(2, 3, 1), ::selectionSort) 

И это работает, потому что подпись selectionSort проста: fun selectionSort(array: Array<Int>): Array<Int> {

Но скажу, что у меня есть другой алгоритм сортировки со следующей подписью

 fun quickSort(array: Array<Int>, start: Int = 0, end: Int = array.size - 1): Array<Int> { 

Последние два аргумента являются необязательными, поэтому теоретически вы можете вызвать quickSort же, как вы вызываете selectionSort . То есть, он уважает подпись (Array<Int>) -> Array<Int> Right?

К сожалению, когда я пытаюсь вызвать sort("Quick Sort", arrayOf(2, 3, 1), ::quickSort) я получаю:

тип missmatch

Я думаю, что компилятор недостаточно умен, чтобы понять, что эти два аргумента являются необязательными. Как избежать этой проблемы, кроме перегрузки метода sort чтобы принять функцию высокого порядка с подписью?

Нельзя избежать этой проблемы, поскольку это противоречило бы двум угловым камням системы типа Котлин:

  • 1) Каждое выражение имеет тип (сильная типизация)
  • 2) Сторона приемника не влияет на тип выражения (локальный вывод)

Например, если бы вы могли это сделать, следующее не сработало бы, это простой рефакторинг вашего примера:

 val algorithm = ::quickSort sort("Quick Sort", arrayOf(2, 3, 1), algorithm) 

В любом случае, для Kotlin разработчики тратят время на решение проблемы sort("Quick Sort", { quickSort(unsorted) }) .