我试图弄清楚如何将一个函数声明地定义为Kotlin中另外两个函数的组合,但我正在努力。这是我的代码:
fun compose(a: (Int, Int) -> Int, b: (Int, Int) -> Int): Int {
return a.invoke() + b.invoke()
}
组合函数的思想是它将接受两个函数作为它的输入(两个函数都需要两个Ints并返回一个Int)并返回两个传递函数的结果之和。问题是我必须调用传递的函数来计算它们的总和(显然是lol)但我不知道我希望在compose方法中调用的值(它们是传递给函数的值)。
我在这里完全遗漏了什么吗?我知道这在Haskell这样的语言中是可能的,在Kotlin中是否可能?
答案 0 :(得分:1)
单向:
你必须将这两个Int作为compose
的附加参数传递给你:
fun compose(c: Int, d: Int,
a: (Int, Int) -> Int,
b: (Int, Int) -> Int) = a(c, d) + b(c, d)
Lambdas是一个进一步的抽象层次,它为您提供了使行为变量的机会,您仍然需要为它们提供数据。
更抽象的方法:
你可以进一步抽象,让compose
返回一个lambda,它结合了另外两个lambdas的结果(让我们称之为compose2
):
// return type is inferred to (Int, Int) -> Int
fun compose2(a: (Int, Int) -> Int, b: (Int, Int) -> Int) = {
c: Int, d: Int -> a(c, d) + b(c, d)
}
val f = compose2(/* pass lambdas */)
f
是一个lambda本身可以像这样调用:
f(2, 4)
因此,compose2
只会返回一个lambda,它会添加两个传递的lambdas的结果。实际调用在compose2
之外完成。
更抽象的方法:
在您的撰写功能中,您可以使用简单的添加作为合成操作。您甚至可以通过传递第三个lambda ab
来使该操作变量,该lambda a
告诉您的函数如何撰写b
和fun compose3(a: (Int, Int) -> Int,
b: (Int, Int) -> Int,
ab: (Int, Int) -> Int) = {
c: Int, d: Int -> ab(a(c, d), b(c, d))
}
:
rng <- range(time(dta))
g <- xts(, seq(rng[1], rng[2], by = 1))
na.locf(merge(dta, g))
结果又是一个lambda,它接受两个Ints并返回一个Int。
答案 1 :(得分:1)
您需要一个新函数(Int, Int) -> Int
,它是两个(Int, Int) -> Int
函数的总和。
因此,compose(...)
返回的是另一个(Int, Int) -> Int
类型的函数。
现在,我们有函数compose
的类型。它返回一个函数,而不是Int
值。
fun compose(a: (Int, Int) -> Int, b: (Int, Int) -> Int): (Int, Int) -> Int
它的身体怎么样?
它将返回一个函数。让我们只返回一个lambda表达式{ x: Int, y: Int -> a(x, y) + b(x, y) }
。
fun compose(a: (Int, Int) -> Int, b: (Int, Int) -> Int): (Int, Int) -> Int {
return { x: Int, y: Int -> a(x, y) + b(x, y)}
}
现在我们可以省略所有不必要的部分。
fun compose(a: (Int, Int) -> Int, b: (Int, Int) -> Int): (Int, Int) -> Int =
{ x, y -> a(x, y) + b(x, y) }
那就是它。
答案 2 :(得分:0)
另一种值得的方法是使用中缀扩展功能。对于参数类型为Int
的情况,可能是这样的:
// Extension function on lambda
private infix fun ((Int, Int) -> Int).plus(f: (Int, Int) -> Int) = {
p1: Int, p2: Int, p3: Int, p4: Int -> this(p1, p2) + f(p3, p4)
}
// Usage
val first: (Int, Int) -> Int = { a, b -> a + b }
val second: (Int, Int) -> Int = { a, b -> a - b }
// first two parameters (1 and 2) for the `first` lambda,
// second two parameters (4 and 3) for the `second` lambda
val sum = (first plus second)(1, 2, 4, 3) // result is 4