Понимание параметра arity метода Proc.curry в Ruby - PullRequest
0 голосов
/ 04 декабря 2018

В документации метода Ruby Proc.curry по адресу https://ruby -doc.org / core-2.5.3 / Proc.html # method-i-curry говорится:

curry -> a_proc

curry (arity) -> a_proc

Возвращает процесс с карри.Если задан необязательный аргумент arity, он определяет количество аргументов.Карри Proc получает некоторые аргументы.Если задано достаточное количество аргументов, он передает предоставленные аргументы исходному процессу и возвращает результат.В противном случае возвращает другой каррированный процесс, который принимает остальные аргументы.

Я знаю, arity означает количество аргументов функции.Однако мне не совсем понятно, как это работает здесь.Может кто-нибудь помочь объяснить, пожалуйста?Я прочитал примеры на документе, но все еще в замешательстве.

1 Ответ

0 голосов
/ 05 декабря 2018

Возможно, поможет лучший пример.Давайте начнем с простого процесса:

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
...