Невозможно создать последовательность Ints в Kotlin через функцию succesor. Говорит "Ошибка вывода типа"
Я пытаюсь создать поток / последовательность натуральных чисел из числа 0 и функции-преемника S через функцию generateSequence.
Вот что у меня есть:
package core
fun sequenceOfNumbers(): Sequence<Int> {
return generateSequence(0){x -> S(x)}
}
class S: (Int) -> Int {
override operator fun invoke(x: Int) = x + 1
}
fun main(args: Array<String>) {
println(sequenceOfNumbers().take(10).toList())
}
Я знаю, что это может показаться не лучшим способом решения этой проблемы, поскольку уже есть операторы инкремента и что уже есть ярлык для генерации первых n натуральных чисел, но я хочу, чтобы S был классом или, по крайней мере, объектом для некоторые другие причины позже.
Когда я его компилирую, я получаю следующие сообщения:
Type inference failed: Cannot infer type parameter T in
fun <T : Any> generateSequence(
seed: T?,
nextFunction: (T) → T?
) : Sequence<T>
None of the following substitutions
(S?, (S) → S?)
(Int?, (Int) → Int?)
(Any?, (Any) → Any?)
can be applied to
(Int, (Int) → S)
а также
Слишком много аргументов для открытого конструктора S(), определенного в core.
Другие вещи, которые я пробовал, переписывает S как
class S: Function<Int> {
operator fun invoke(x: Int) = x + 1
}
или изменив функцию generateSequence на
fun sequenceOfNumbers(start: Int): Sequence<Int> {
return generateSequence(seed = start, nextFunction = (x: Int) -> S(x))
}
что тоже не сработало. Последняя функция получила сообщения компиляции "Неожиданная спецификация типа" и "Неожиданные токены (используйте ';' для разделения выражений в одной строке").
Любой способ решить это так, чтобы println
Функция выводит первые 10 натуральных чисел и все еще использует класс преемника?
1 ответ
Проблема в вашем коде, что вы на самом деле вызываете конструктор S
, скорее, чем invoke()
, Вы должны перейти на следующее, чтобы это работало:
return generateSequence(0){x -> S()(x)}
Конечно, будет лучше, если вы храните S
в локальной переменной и повторно использовать его в генераторе последовательности:
fun sequenceOfNumbers(): Sequence<Int> {
val s = S()
return generateSequence(0){x -> s(x)} //generateSequence(0, s::invoke)
}
Или даже лучше сделать S
синглтон:
fun sequenceOfNumbers(): Sequence<Int> {
return generateSequence(0) { x -> S(x)} //generateSequence(0, S::invoke)
}
object S: (Int) -> Int {
override operator fun invoke(x: Int) = x + 1
}
В итоге ваш код будет выглядеть так, как в вашем примере.