首页 > 解决方案 > 在 Ruby 中传递任意数量的 lambda(或 procs)

问题描述

我正在研究 Ruby 中的功能模型并遇到了问题。我能够成功地将任何给定数量的参数传递给任意函数,如下所示:

add = ->(x, y) { return x + y }
mul = ->(x, y) { return x * y }

def call_binop(a, b, &func)
  return func.call(a, b)
end

res = call_binop(2, 3, &add)
print("#{res}\n")   #5

res = call_binop(3, 4, &mul)
print("#{res}\n")   #12

但是,我无法传递任意数量的函数:

dbl = ->(x) { return 2 * x }
sqr = ->(x) { return x * x }

def call_funccomp(a, &func1, &func2)
  return func2.call(func1.call(a))
end

res = call_funccomp(3, &dbl, &sqr)
print("#{res}\n")   #Expect 36 but compiler error

编译器错误是syntax error, unexpected ',', expecting ')'

我已经将 lambdas 和 procs 添加到一个数组中,然后执行了数组的元素,所以我知道我可以通过传递这样一个数组作为参数来解决这个问题,但对于简单的情况,这似乎是对某些东西的扭曲(我希望)在该语言中是合法的。Ruby 是否真的限制了参数列表中可以传递的数量或 lambda?它似乎有一个相当现代、灵活的功能模型(符号有点奇怪),其中事情可以通过call方法执行。

标签: rubyfunctional-programming

解决方案


Ruby 是否真的限制了参数列表中可以传递的数量或 lambda?

不,您可以传递任意数量的 procs / lambdas。您只是不能将它们作为块参数传递。

在 proc 前添加&触发器 Ruby 的proc 以阻止转换,即您的 proc 成为一个块参数。而 Ruby 最多只允许一个块参数

尝试调用call_funccomp(3, &dbl, &sqr)相当于传递两个块:

call_funccomp(3) { 2 * x } { x * x }

Ruby 不允许的东西。

解决方法是省略,即将 procs / lambdas 作为位置参数&传递:

dbl = ->(x) { 2 * x }
sqr = ->(x) { x * x }

def call_funccomp(a, func1, func2)
  func2.call(func1.call(a))
end

res = call_funccomp(3, dbl, sqr)
print("#{res}\n") 

还有Proc#>>一个结合了两个过程:

def call_funccomp(a, func1, func2)
  (func1 >> func2).call(a)
end

推荐阅读