Kotlin高阶函数合成
我试图找出如何将一个函数定义为Kotlin中其他两个函数的组合,但我正在努力。这是我的密码:Kotlin高阶函数合成,kotlin,Kotlin,我试图找出如何将一个函数定义为Kotlin中其他两个函数的组合,但我正在努力。这是我的密码: fun compose(a: (Int, Int) -> Int, b: (Int, Int) -> Int): Int { return a.invoke() + b.invoke() } compose函数的思想是,它将接受两个函数作为输入(两个函数都接受两个Int并返回一个Int),然后返回两个传递函数的结果之和。问题是我必须调用传递的函数来计算它们的和(显然是lol),但我
fun compose(a: (Int, Int) -> Int, b: (Int, Int) -> Int): Int {
return a.invoke() + b.invoke()
}
compose函数的思想是,它将接受两个函数作为输入(两个函数都接受两个Int并返回一个Int),然后返回两个传递函数的结果之和。问题是我必须调用传递的函数来计算它们的和(显然是lol),但我不知道我希望在compose方法中调用的值(它们是传递给函数的值)
我完全错过了什么吗?我知道这在Haskell这样的语言中是可能的,在Kotlin中是可能的还是不可能的?单向: 您必须将这两个整数作为附加参数传递给
compose
,如下所示:
fun compose(
c: Int, d: Int, a: (Int, Int) -> Int, b: (Int, Int) -> Int
) = a(c, d) + b(c, d)
f(2, 4)
// 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
lambda是一个更高层次的抽象,它为您提供了使行为可变的机会,您仍然需要向它们提供数据
更抽象的方法:
您可以进一步抽象,并让compose
返回一个lambda,该lambda组合了其他两个lambda的结果(称之为compose2
):
f
本身就是一个lambda,可以这样称呼:
fun compose(
c: Int, d: Int, a: (Int, Int) -> Int, b: (Int, Int) -> Int
) = a(c, d) + b(c, d)
f(2, 4)
// 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
因此,compose2
只返回一个lambda,它将两个传递的lambda的结果相加。实际调用是在compose2
之外完成的
更抽象的方法:
在合成函数中,使用简单的加法作为合成操作。您甚至可以通过传递第三个lambdaab
来生成此操作变量,它告诉您的函数如何组合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))
}
结果也是一个lambda,它接受两个Int并返回一个Int。您需要一个新函数
(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) }
就是这样。另一个有价值的方法是使用中缀扩展函数。对于参数类型为
Int
的情况,可以如下所示:
fun compose(
c: Int, d: Int, a: (Int, Int) -> Int, b: (Int, Int) -> Int
) = a(c, d) + b(c, d)
f(2, 4)
// 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
编写
a
和b
通常意味着将a
应用于b
应用于某个参数的结果,但这并不是您真正想要的。是的。名字compose
意味着一些特定的操作:函数的组合f(x)
和g(x)
是g(f(x))
,而不是一个函数和……或者如果你把infix
改为操作符,你可以写first+second