理解 Ruby 中 Proc.curry 方法的 arity 参数

4
在Ruby的文档中,Proc.curry方法的说明如下:https://ruby-doc.org/core-2.5.3/Proc.html#method-i-curry

curry -> a_proc

curry(arity) -> a_proc

返回一个柯里化的proc。如果给定了可选的arity参数,则确定参数的数量。一个柯里化的proc接收一些参数。如果提供了足够数量的参数,则将这些参数传递给原始的proc并返回结果。否则,返回另一个接收其余参数的柯里化的proc。

我知道arity表示函数的参数数量。然而,在这里它是如何工作的我不太清楚。有人可以帮忙解释一下吗?我已经阅读了文档上的示例,但仍然感到困惑。
1个回答

4
也许通过一个更好的例子来说明会更有帮助。我们从一个简单的过程开始:

也许通过一个更好的例子来说明会更有帮助。我们从一个简单的过程开始:

p = proc { |a, b, c| "a=#{a.inspect}, b=#{b.inspect}, c=#{c.inspect}" }
p[1,2,3]
# "a=1, b=2, c=3" 

如果我们调用 curry 而没有传递 arity 参数,那么很显然会发生什么:

p.curry          # evaluates to a proc
p.curry[1]       # and a different proc
p.curry[1][2]    # another different proc
p.curry[1][2][3] # "a=1, b=2, c=3" 
p.curry[1,2]     # yet another proc, hooray for procs!
p.curry[1,2][3]  # "a=1, b=2, c=3"
p.curry[1,2,3]   # "a=1, b=2, c=3"

所以,p.curry 通过为参数提供值来给我们提供一系列 Proc,直到我们有足够的值来评估原始的 Proc。现在我们开始添加 arity 值:

p.curry(1)          # some proc
p.curry(1)[]        # some other proc,
p.curry(1)[1]       # "a=1, b=nil, c=nil" 
p.curry(1)[1, 2]    # "a=1, b=2, c=nil" 
p.curry(1)[1, 2, 3] # "a=1, b=2, c=3"

p.curry(2)          # a proc
p.curry(2)[]        # another proc
p.curry(2)[1]       # oh look, a proc, a lovely surprise
p.curry(2)[1][2]    # "a=1, b=2, c=nil" 
p.curry(2)[1, 2]    # "a=1, b=2, c=nil" 
p.curry(2)[1, 2, 3] # "a=1, b=2, c=3" 

arity参数设置了柯里化过程中有效的元数;不要关注实际的元数 - p.curry.arity, p.curry(1).arity, ... - 因为它总是-1(即可变元数)。结果是p.curry(1)有点像

proc { |a| p[a] }.curry # "change" p's arity to 1 then curry

p.curry(2)有点像:

proc { |a, b| p[a, b] }.curry # "change" p's arity to 2 then curry

等等,要记住,仅仅因为一个(非lambda)过程的arity是n,并不意味着您必须使用n个参数调用它。过程的arity更像是一种建议。

当然,如果您尝试对lambda进行这种花招,那么一切都会出问题,因为lambda非常关心它们的arity:

λ = ->(a, b, c) {  "a=#{a.inspect}, b=#{b.inspect}, c=#{c.inspect}" }

λ[1]             # ArgumentError (wrong number of arguments (given 1, expected 3))
λ.curry[1]       # a lambda-proc
λ.curry[1][2][3] # "a=1, b=2, c=3" 
λ.curry[1][2, 3] # "a=1, b=2, c=3" 

λ.curry(1)       # ArgumentError (wrong number of arguments (given 1, expected 3))
λ.curry(2)       # ArgumentError (wrong number of arguments (given 2, expected 3))
λ.curry(3)       # a lambda-proc that's just like λ.curry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接