Kotlin 折叠错误 "None of the following functions can be called with the arguments supplied"
Kotlin fold error "None of the following functions can be called with the arguments supplied"
这个折叠函数出现错误;
fun <T> addAll(num: List<T>) : T = num.fold(0, {x,y -> x+y})
说:
None 可以使用提供的参数调用以下函数。
但是如果我这样做:
fun addAll(num: List<Int>) : Int = num.fold(0, {x,y -> x+y})
它工作没有问题。
是否可以保持函数的通用性以便将其用于整数和双精度列表?
不幸的是,Kotlin 目前不允许对所有数字类型的运算符进行抽象(我相信这是为了能够在 JVM 运行时使用原始数字)。
所以你能得到的最好的是这样的:
fun <T> addAll(num: List<T>, zero: T, adder: (T, T) -> T) : T =
num.fold(zero, adder)
println(addAll(listOf(1,2,3), 0, Int::plus))
println(addAll(listOf(1.0,2.0,3.0), 0.0, Double::plus))
虽然不幸的是您不能使用单个泛型函数来做到这一点,但您可以简单地使用 sum
,它是为许多 Iterable
类型定义的,例如 Iterable<Int>
和 [=14] =]:
val doublesSum = listOf(1.0, 2.0).sum()
val intsSum = listOf(1, 2).sum()
这样至少可以解决当前的问题:)
另一种方法是使用函数式编程。
仅当您熟悉 FP 并且需要非常非常通用的解决方案时才这样做。
这是一个使用 Arrow 库的示例:
import arrow.core.identity
import arrow.data.ListKW
import arrow.data.foldable
import arrow.data.k
import arrow.typeclasses.monoid
inline fun <reified T> addAll(num: List<T>): T =
ListKW.foldable().foldMap(monoid(), num.k(), ::identity)
fun main(args: Array<String>) {
println(addAll(listOf(1, 2, 3)))
println(addAll(listOf(1.0, 2.0, 3.0)))
println(addAll(listOf("one", "two", "three")))
}
这个折叠函数出现错误;
fun <T> addAll(num: List<T>) : T = num.fold(0, {x,y -> x+y})
说:
None 可以使用提供的参数调用以下函数。
但是如果我这样做:
fun addAll(num: List<Int>) : Int = num.fold(0, {x,y -> x+y})
它工作没有问题。 是否可以保持函数的通用性以便将其用于整数和双精度列表?
不幸的是,Kotlin 目前不允许对所有数字类型的运算符进行抽象(我相信这是为了能够在 JVM 运行时使用原始数字)。
所以你能得到的最好的是这样的:
fun <T> addAll(num: List<T>, zero: T, adder: (T, T) -> T) : T =
num.fold(zero, adder)
println(addAll(listOf(1,2,3), 0, Int::plus))
println(addAll(listOf(1.0,2.0,3.0), 0.0, Double::plus))
虽然不幸的是您不能使用单个泛型函数来做到这一点,但您可以简单地使用 sum
,它是为许多 Iterable
类型定义的,例如 Iterable<Int>
和 [=14] =]:
val doublesSum = listOf(1.0, 2.0).sum()
val intsSum = listOf(1, 2).sum()
这样至少可以解决当前的问题:)
另一种方法是使用函数式编程。 仅当您熟悉 FP 并且需要非常非常通用的解决方案时才这样做。
这是一个使用 Arrow 库的示例:
import arrow.core.identity
import arrow.data.ListKW
import arrow.data.foldable
import arrow.data.k
import arrow.typeclasses.monoid
inline fun <reified T> addAll(num: List<T>): T =
ListKW.foldable().foldMap(monoid(), num.k(), ::identity)
fun main(args: Array<String>) {
println(addAll(listOf(1, 2, 3)))
println(addAll(listOf(1.0, 2.0, 3.0)))
println(addAll(listOf("one", "two", "three")))
}