无法通过后继函数在 Kotlin 中创建 Int 序列。说 "Type Inference failed"
Can't create sequence of Ints in Kotlin through succesor function. Says "Type Inference failed"
我正在尝试通过 generateSequence 函数从数字 0 和后继函数 S 创建一个 stream/sequence 自然数。
这是我得到的:
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 是 class 或至少以后出于其他原因反对。
当我编译它时,我收到以下消息:
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)
和
Too many arguments for public constructor S() defined in 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))
}
这也没有用。最后一个函数得到编译消息 "Unexpected type specification" 和 "Unexpected tokens (use ';' to separate expressions on the same line".
有什么方法可以解决这个问题,让println
函数打印出前10个自然数,并且仍然使用后继class?
您的代码中的问题是您实际调用了 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
}
因此最终您的代码将类似于您的示例。
我正在尝试通过 generateSequence 函数从数字 0 和后继函数 S 创建一个 stream/sequence 自然数。
这是我得到的:
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 是 class 或至少以后出于其他原因反对。
当我编译它时,我收到以下消息:
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)
和
Too many arguments for public constructor S() defined in 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))
}
这也没有用。最后一个函数得到编译消息 "Unexpected type specification" 和 "Unexpected tokens (use ';' to separate expressions on the same line".
有什么方法可以解决这个问题,让println
函数打印出前10个自然数,并且仍然使用后继class?
您的代码中的问题是您实际调用了 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
}
因此最终您的代码将类似于您的示例。