Julia中是否存在支持自定义与内置函数的通用柯里化方法?
Julia中实现函数柯里化的惯用方式
在Haskell中,函数默认支持自动柯里化,示例如下:
times a b = a * b -- 直接传两个参数调用 times 2 3 -- 结果是6 -- 部分应用(自动柯里化) (times 2) 3 -- 同样得到6
在Julia中,部分内置函数原生支持这种部分应用的特性:
<(8, 7) # 结果是false <(7)(8) # 结果相同 7 |> <(8) # 结果相同
但自定义函数默认不具备该能力:
times(a, b) = a * b times(2, 3) # 结果是6 3 |> times(2) # 报错:MethodError: no method matching times(::Int64)
手动定义单参数版本可以实现柯里化,但Julia提供了更通用的方式,适配自定义和内置函数,以下是几种惯用方法:
1. 使用内置的Fix1和Fix2
Base.Fix1和Base.Fix2是Julia原生提供的工具,分别用于固定函数的第一个和第二个参数,返回一个可接受剩余参数的新函数:
Fix1(f, x):等价于y -> f(x, y)Fix2(f, y):等价于x -> f(x, y)
示例代码:
using Base: Fix1, Fix2 # 自定义函数 times(a, b) = a * b # 固定第一个参数 times2 = Fix1(times, 2) times2(3) # 输出6 3 |> times2 # 输出6 # 固定第二个参数 times_3 = Fix2(times, 3) times_3(2) # 输出6 # 多参数函数可嵌套使用 add3(a, b, c) = a + b + c add1_2 = Fix1(Fix1(add3, 1), 2) add1_2(3) # 输出6
2. 匿名函数快速实现柯里化
对于自定义函数,直接用匿名函数嵌套的方式,能快速生成柯里化版本,写法简洁直观:
# 双参数柯里化 times(a) = b -> a * b times(2)(3) # 输出6 3 |> times(2) # 输出6 # 多参数嵌套柯里化 add3(a) = b -> c -> a + b + c add3(1)(2)(3) # 输出6
3. 自定义宏实现自动柯里化
可以编写宏来自动为函数添加柯里化能力,无需手动修改函数定义:
macro curry(f) quote function $(esc(f))(args...) if length(args) < methods($(esc(f)))[1].nargs - 1 return x -> $(esc(f))(args..., x) else return $(esc(f))(args...) end end end end # 为自定义函数启用自动柯里化 @curry times(a, b) = a * b times(2)(3) # 输出6
注:这个宏的实现适配了常规的函数参数数量判断,可根据需求进一步扩展完善。
4. 管道+匿名函数的即时部分应用
在不需要提前定义柯里化函数的场景下,直接结合管道操作符和匿名函数,也能实现临时的部分应用:
times(a, b) = a * b 3 |> x -> times(2, x) # 输出6
内容的提问来源于stack exchange,提问作者P Varga
相关产品推荐
相关产品推荐

