Как создать лямбду из лямбды с параметром, не делая .call в Ruby? - PullRequest
4 голосов
/ 05 января 2012

Я хочу создать новую лямбду, не принимая аргументов от лямбды, принимающей ее.

Скажем, у меня есть

irb(main):001:0> f1 = lambda { |p| p }
=> #<Proc:0x00000001045190@(irb):1 (lambda)>
irb(main):002:0> f1.call(2)
=> 2

и теперь я

irb(main):003:0> f2 = lambda { f1.call(2) }
=> #<Proc:0x00000000f620e8@(irb):3 (lambda)>
irb(main):004:0> f2.call
=> 2

, ноЯ не хочу создавать лямбду вокруг первого, но хочу «подставить» параметр для него или чего-то еще.

Может быть, если у нас есть call, есть какая-то магия, которая делает то же самое, что и вызов,но возвращает лямбду, за исключением фактического вызова кода:

f2 = f1.some_magic(2)
f2.call
=> 2

PS Извините, если этот вопрос глуп, мне иногда сложно понять этот функциональный материал.

PPS Found эта тема на ruby-forum.com, и, кажется, я хочу сделать то же самое без лишних вызовов.

Ответы [ 2 ]

3 голосов
/ 05 января 2012

Вы ищете карри?:

f1 = lambda { |p| p }
p f1.curry[2] #=> 2

Карри доступен в Ruby 1.9

3 голосов
/ 05 января 2012

Вы можете создать функцию, которая связывает аргументы с процедурой. Это работает с Ruby> = 1.8:

def bind_args(l, *bound_args)
  lambda { |*unbound_args|
    l[*(bound_args + unbound_args)]
  }
end

Используется:

f1 = lambda { |p| p }   
f2 = bind_args(f1, 2)
p f2.call
# 2

Если вы хотите связать некоторые, но не все аргументы, вы можете сделать это тоже:

f1 = lambda { |p, q| [p, q] }
f2 = bind_args(f1, 2)
p f2.call(3)
# [2, 3]

За исключением того, что curry совершает вызов, а не новую лямбду, если заданы полные аргументы связываемой лямбды, это почти то, что делает curry. Я не назвал это curry, чтобы избежать путаницы с методом этого имени, встроенным в Ruby 1.9.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...