swift - 将常规 Swift 函数转换为 Curry 函数

标签 swift currying

我正在尝试将常规函数转换为柯里函数,但得到执行被中断

下面是我柯里化(Currying)一个函数并执行 unsafeBitCast 来调用具有一个参数的函数并稍后使用第二个参数调用它的代码。

func curry<T>(f: (T, T) -> T) -> T -> T -> T {
    return { a in
        typealias Function = (T) -> (T -> T)
        let fn = unsafeBitCast(f, Function.self)
        return curry(fn(a))
    }
}

func curry<T>(f: T -> T) -> T -> T {
    return { f($0) } // Throws Runtime Exception
}

func adder(x: Int, y: Int) -> Int {
    return x + y
}

let adderCurry = curry(adder)
let add1 = adderCurry(1)
add1(2)

有谁知道如何将具有两个或多个参数的常规函数​​转换为柯里化(Currying)函数

func add(x: Int)(y: Int) -> Int {
  return x + y
}

编辑:这个例子也不起作用

func curry<T>(f: (T, T) -> T) -> T -> T -> T {
    typealias Function = T -> T -> T
    return unsafeBitCast(f, Function.self)
}

func adder(x: Int, y: Int) -> Int {
    return x + y
}

let adderCurry = curry(adder)
let add1 = adderCurry(1)
add1(2)

最佳答案

您不需要对其进行类型转换,而是返回依次捕获每个参数的嵌套闭包:

func add(x: Int, y: Int) -> Int {
    return x + y
}

func curry<T1, T2, T3>(f: (T1, T2) -> T3) -> T1 -> T2 -> T3 {
    return {
        (t1: T1) -> T2 -> T3 in

        return {
            (t2: T2) -> T3 in

            return f(t1, t2)
        }
    }
}

let curriedAdd = curry(add)
let add3 = curriedAdd(3)
println(add3(5))
// 8

这更简洁:

func curry<T1, T2, T3>(f: (T1, T2) -> T3) -> T1 -> T2 -> T3 {
    return { t1 in { t2 in f(t1, t2) } }
}

我认为写一个 curry 机会很有趣;就是这样 - 如果有人知道如何制作其中一个来生成实际的函数,那就太棒了:

func curryRecipe(n: Int) -> String {
    let types = join(", ", map(1...n, { "T\($0)" }))
    let returnType = join(" -> ", map(1...n, { "T\($0)" }))
    let closures = join(" in ", map(1...n, { "{ t\($0)" }))
    let braces = join(" ", Array(count: n, repeatedValue: "}"))
    return "func curry<\(types), R>(f: (\(types)) -> R) -> \(returnType) -> R {\r" +
        "    return \(closures) in f(\(types.lowercaseString)) \(braces)\r}"
}

println(curryRecipe(15))

输出:

func curry<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R>(f: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) -> R) -> T1 -> T2 -> T3 -> T4 -> T5 -> T6 -> T7 -> T8 -> T9 -> T10 -> T11 -> T12 -> T13 -> T14 -> T15 -> R {
    return { t1 in { t2 in { t3 in { t4 in { t5 in { t6 in { t7 in { t8 in { t9 in { t10 in { t11 in { t12 in { t13 in { t14 in { t15 in f(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15) } } } } } } } } } } } } } } }
}

关于swift - 将常规 Swift 函数转换为 Curry 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26824338/

相关文章:

f# - 从 C# 调用部分应用的函数

javascript - 什么是 'Currying' ?

f# - "int -> int -> int"这在 F# 中是什么意思?

swift - 将 AnyObject 转换为特定类

Scala 实例 - 柯里化(Currying)问题

ios - 检查用户是否登录 Facebook 并更改 View Controller

ios - swift 结构体作为函数参数

r - 为什么重复调用 lapply 后闭包中的变量值会丢失?

ios - 如果使用自动释放池来控制对 Realm 的引用,在离开池之前调用 realm.invalidate 是一种好习惯吗

iOS 操作扩展,从 Safari 共享 PDF 失败