我有一个函数,该函数带有两个参数并返回一个值。
例如
func sum(x: Int, y: Int) -> Int {
return x + y
}
下一步是使用currying
获取仅采用第一个参数的函数,并返回带有适当签名的闭包。
另外,我写了一个类型别名以使结果类型更清晰。
typealias EscapingClosure<A, B> = (A) -> B
func curry<A, B, C>(_ f: @escaping (A, B) -> C) -> EscapingClosure<A, (B) -> C> {
return { (a: A) -> ((_ b: B) -> C) in
return { (b: B) -> C in f(a, b) }
}
}
但是后来我想起了uncurry
函数,如果我将其应用于结果,它将返回默认的sum
函数签名。
因此,我尝试实现uncurry
的变体,以及得到的结果:
func uncarry<A, B, C>(_ f: @escaping EscapingClosure<A, (B) -> C>) -> (A, B) -> C {
return { (a: A, b: B) -> C in
return f(a)(b)
}
}
但这是一个问题-我无法将此uncurry
函数与sum
函数一起使用,因为uncurry
仅需要 @转义参数,其中curryied函数返回无转义的变体。
这是一个Swift编译器错误:
Cannot convert value of type '((A) -> Void) -> ()' to expected argument type '(_) -> (_) -> _'
有人知道有什么方法可以在Swift中创建uncurry
函数,该方法适用于已获得的函数结果。
答案 0 :(得分:1)
您的uncurry
函数可以做到这一点,即无咖喱的咖喱函数:
let currableSum = curry(sum)
let uncurriedSum = uncurry(currableSum)
let add100 = currableSum(100)
print(add100(23)) // => 123
print(uncurriedSum(2, 2)) // => 4
问题是您误用了取消申请。一旦部分或完全应用了curried函数(或其他任何函数),便没有任何机制可以返回以获得产生结果的原始函数。
uncurry(add100) // ❌ can't "unapply" a partially applied function
想象一下是不是这种情况。每个整数,字符串和其他值都必须记住导致它的函数的历史记录。我无法想到一个用例。首先,这将需要动态类型化(或在诸如Swift之类的静态语言中进行强制编译时强制转换),因为您无法预测会产生给定结果的任意函数的签名。
答案 1 :(得分:0)
正如@Alexander所写,我可以轻松地使用uncurry
函数获取sum()
的查询结果。
当传递curried函数的结果值时,我只是犯了一个错误。