Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin高阶函数合成_Kotlin - Fatal编程技术网

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),但我

我试图找出如何将一个函数定义为Kotlin中其他两个函数的组合,但我正在努力。这是我的密码:

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
之外完成的

更抽象的方法:

在合成函数中,使用简单的加法作为合成操作。您甚至可以通过传递第三个lambda
ab
来生成此操作变量,它告诉您的函数如何组合
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