在https://ruby-doc.org/core-2.5.3/Proc.html#method-i-curry的Ruby Proc.curry
方法的文档中,它说:
curry-> a_proc
curry(arity)-> a_proc
返回一个咖喱的过程。如果给出了可选的arity参数,则它确定参数的数量。咖喱过程接收一些参数。如果提供了足够数量的参数,它将提供的参数传递给原始proc并返回结果。否则,返回另一个使用其余参数的咖喱过程。
我知道arity
表示函数的参数数量。但是,我不太清楚它在这里如何工作。有人可以帮忙解释一下吗?我已经阅读了文档中的示例,但仍然感到困惑。
答案 0 :(得分:1)
也许通过一个更好的例子可能会有所帮助。让我们从一个简单的过程开始:
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
参数设置了咖喱过程的有效属性;不要担心 real 实物-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具有Ar n
并不意味着您必须使用n
自变量来调用它。 proc的友善比其他任何东西更像是一个建议。
当然,如果您尝试用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