我想做一个函数,返回一个咖喱函数,如下所示
func addTwoNumbers(a: Int)(b: Int) -> Int {
return a + b
}
addTwoNumbers(4)(b: 6) // Result: 10
var add4 = addTwoNumbers(4)
add4(b: 10) // returns 14 这类函数的返回类型是什么,我如何使用使用变量参数的函数生成这样的函数。
func generateCurry(.../*Variadic parameters*/) -> .../*curry function type*/ {
return ...//curry function
}我想要一个通用的解决方案,而不是仅以Int作为参数,在generateCurry函数的参数中
let curried = curry(func(a, b, c) {
print(a + b + c)
})
curried(1)(2)(3) //prints 6发布于 2014-08-19 03:16:06
通过闭包,您可以很容易地做到这一点:
/// Takes a binary function and returns a curried version
func curry<A,B,C>(f: (A, B) -> C) -> A -> B -> C {
return { a in { b in f(a, b) } }
}
curry(+)(5)(6) // => 11
let add: Int -> Int -> Int = curry(+)
add(5)(6) // => 11如果能够对包含3、4或更多参数的函数执行相同的操作,但不重复实现,那就太好了。这样一个函数的签名可能会启动如下内容:
/// Take a function accepting N arguments and return a curried version
func curry<T>(args: T...) -> /* ? */返回类型是什么?它将根据对函数的输入进行更改。这在Swift目前是不可能的,如果没有某种宏观系统,我认为这是不可能的。但是,即使使用宏,我也不认为编译器会满意,除非它在编译时知道列表的长度。
话虽如此,使用接受3、4、5或更多参数的版本手动重载运行函数确实是一种直截了当的做法:
func curry<A,B,C,D>(f: (A, B, C) -> D) -> A -> B -> C -> D {
return { a in { b in { c in f(a,b,c) } } }
}
func curry<A,B,C,D,E>(f: (A, B, C, D) -> E) -> A -> B -> C -> D -> E {
return { a in { b in { c in { d in f(a,b,c,d) } } } }
}
// etc.发布于 2014-06-08 14:45:19
我不确定这是否真的会像Python这样的语言中的方式一样成为可能。
我看到有一个通用解决方案的核心问题是要接受的闭包/函数的强类型。
您可以相当容易地创建一个用于特定或通用函数签名的curry函数,但就一般用途咖喱而言,我看不到它的工作方式。问题不仅仅在于论点的类型(如评论中提到的那样),还包括它们的数量。
我编写了一个简单的例子,说明如何实现curry函数。它可以工作,但我不认为有一个明智的方式,有一个真正的通用的,你可以在更松散的类型的语言。
func add(a1: Int, a2: Int) -> Int {
return a1 + a2
}
func curry(argument: Int, block: (Int, Int) -> Int) -> Int -> Int{
func curried(arg: Int) -> Int {
return block(argument, arg)
}
return curried
}
curry(5, add)(6)发布于 2017-01-24 09:10:26
如果您想要快速获得任意数量的参数的curry函数,就可以生成它,如这个要旨所示。
代码在SWIFT2.2中,并为SWIFT2.2生成代码(目前)。它使用简单的基于模板的方法(一种可能的替代方法是构建AST,然后进行代码生成):
func genCurry(n: Int, indent: Indent = .fourSpaces, accessLevel: AccessLevel = .Default, verbose: Bool = false) -> String {
// ...
// The bulky park is skipped for clarity.
return accessLevel.asPrefix + "func curry<\(genericParams)>(f: \(fSig)) -> \(curriedSig(n)) {\n"
+ indent.single + "return \(closure)\n"
+ "}\n"
}https://stackoverflow.com/questions/24107191
复制相似问题