Возможно, поможет лучший пример.Давайте начнем с простого процесса:
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
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
устанавливает эффективную арность каррированного процесса;не беспокойтесь, глядя на real arity - p.curry.arity
, p.curry(1).arity
, ... - так как это всегда будет -1
(т.е. variadic).В результате 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
и т. Д.Имейте в виду, что только потому, что (не лямбда) процесс имеет arity n
, не означает, что вы должны вызывать его с n
аргументами.Арктичность прока - это скорее предложение, чем что-либо еще.
Конечно, если вы попробуете эту чиканье с лямбдой, тогда все пойдет не так, потому что лямбды очень заботятся об их арности:
λ = ->(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