You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中单参柯里化函数可接收双参函数的编译异常问题

Swift中柯里化函数的类型匹配问题

问题重现

这段代码看起来明显不符合类型要求,但居然能编译通过:

func curry<A, B>(_ f: @escaping (A) -> B) -> (A) -> B {
    print("is called")
    return f
}

func sum(a: Int, b: Int) -> Int {
    a + b
}

curry(sum)

编译器自动把f推断成了((Int, Int)) -> Int类型——这不是bug,是Swift的特性:多参数函数会被自动转换为接受对应元组的函数。

如何避免这种类型不匹配的传参

  • 显式指定泛型参数:调用时明确给出泛型类型,让编译器严格校验:
    curry<Int, Int>(sum) // 直接编译报错,因为sum不符合(Int)->Int的类型
    
  • 修改curry函数签名:如果你的目标是柯里化多参数函数,直接针对多参数场景写签名,比如双参数的柯里化:
    func curry<A, B, C>(_ f: @escaping (A, B) -> C) -> (A) -> (B) -> C {
        return { a in { b in f(a, b) } }
    }
    
    // 调用后得到真正的柯里化函数
    let curriedSum = curry(sum)
    let result = curriedSum(1)(2) // 输出3
    
  • 用类型约束限制输入:如果要确保传入的是严格单参数函数,可通过泛型约束排除元组(Swift没有直接的元组约束,可借助其他协议或条件):
    // 示例:用Sendable约束(根据你的场景调整)
    func curry<A, B>(_ f: @escaping (A) -> B) -> (A) -> B where A: Sendable {
        print("is called")
        return f
    }
    // 此时传入sum会编译报错,因为元组(Int, Int)默认不遵循Sendable(需手动扩展或调整约束)
    

补充说明

原代码里的curry是实现通用可变参数柯里化过程中的一步,所以用了这个命名,但当前函数只是单参数函数的包装,没有处理多参数柯里化逻辑,这才让编译器有机会把多参数函数转成元组函数。

内容的提问来源于stack exchange,提问作者Roman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 19:42:28