ios - Swift中的非咖喱函数
问题描述
我有一个函数,它接受两个参数并返回一个值。
例如
func sum(x: Int, y: Int) -> Int {
return x + y
}
下一步是使用 acurrying
获取一个函数,该函数接受唯一的第一个参数并返回一个带有适当签名的闭包。另外,我写了一个类型别名以使结果类型更加清晰。
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) }
}
}
但是后来我想起了函数,如果我将它应用于 curryied 结果,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
函数进行currying,因为uncurry
只需要@escaping参数,其中curryied 函数返回一个非转义变体。
这是一个 Swift 编译器错误:
Cannot convert value of type '((A) -> Void) -> ()' to expected argument type '(_) -> (_) -> _'
有谁知道有什么方法可以uncurry
在 Swift 中创建适用于 curryied 函数结果的函数。
解决方案
您的uncurry
函数可以做到这一点,非咖喱函数:
let currableSum = curry(sum)
let uncurriedSum = uncurry(currableSum)
let add100 = currableSum(100)
print(add100(23)) // => 123
print(uncurriedSum(2, 2)) // => 4
问题是你误认为 uncurrying 是 unapplying。一旦您部分或完全应用了一个柯里化函数(或任何函数,就此而言),就没有机制可以返回,以获取产生结果的原始函数。
uncurry(add100) // ❌ can't "unapply" a partially applied function
想象一下,如果是这样的话。每个整数、字符串和其他值都必须记住是什么函数导致它的历史。我想不出一个单一的用例。一方面,它需要动态类型(或在 Swift 等静态语言中强制编译时强制转换),因为您无法预测产生给定结果的任意函数的签名。
推荐阅读
- python - Python + Selenium:我无法从 div 获取打印文本
- c# - 标签助手不填充表单值
- javascript - 页面加载后无法在 select2 下拉列表中设置多个值
- react-native - 如何将 useState 的值传递给 BackHandler.addEventListener
- r - 在 R 中安装 tensorflow 时出错:/Users/emmeran/.virtualenvs/r-reticulate/bin/pip:没有这样的文件或目录
- python - CNN特征提取时间
- global-variables - 在 Julia 中跨模块共享全局变量
- matlab - 在matlab中,我在一个类的方法中得到了不同的值
- python - Z3python XOR 和?
- javascript - 为什么html2canvas的顶部有一个空白?