3

在https://ruby-doc.org/core-2.5.3/Proc.html#method-i-curry的 RubyProc.curry方法文档中,它说:

咖喱-> a_proc

咖喱(arity)-> a_proc

返回一个咖喱​​过程。如果给出了可选的arity 参数,它会确定参数的数量。一个 curried proc 接收一些参数。如果提供了足够数量的参数,它会将提供的参数传递给原始 proc 并返回结果。否则,返回另一个接受其余参数的 curried proc。

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

4

1 回答 1

3

也许通过一个更好的例子可能会有所帮助。让我们从一个简单的过程开始:

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给我们连续的Procs,直到我们有足够的值来评估原始 s 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参数是设置 curried proc 的有效参数;不要费心去看真正的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)proc 具有 arityn并不意味着您必须使用n参数调用它。proc的arity更像是一个建议而不是其他任何东西。

当然,如果您尝试使用 lambda 进行这种诡计,那么一切都会横向发展,因为 lambda 非常关心它们的数量:

λ = ->(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
于 2018-12-05T04:24:10.007 回答