Ruby中的递归lambdas

Ruby中的递归lambdas,ruby,recursion,lambda,Ruby,Recursion,Lambda,我有以下代码,可以正确生成大小为num的所有可能的树: class Tree attr_accessor :left, :right def initialize left = nil, right = nil @left = left @right = right end # Don't ever specify any arguments, it will make me very angry. # Tilt your head 90 degrees

我有以下代码,可以正确生成大小为
num
的所有可能的树:

class Tree
  attr_accessor :left, :right

  def initialize left = nil, right = nil
    @left = left
    @right = right
  end

  # Don't ever specify any arguments, it will make me very angry.
  # Tilt your head 90 degrees to the side to see the tree when viewing.
  def print level = 0
    @right.pretty_print(level + 1) if @right
    puts ('  ' * level) + to_s
    @left.pretty_print(level + 1) if @left
  end

  def self.generate num
    trees = []
    generate_subtrees(num) { |tree| trees << tree } if num > 0
    trees
  end

  private

  def self.generate_subtrees num, &block
    if num == 0
      yield nil
    else
      (1..num).each do |root_position|
        generate_subtrees(root_position - 1) do |left|
          generate_subtrees(num - root_position) do |right|
            yield Tree.new nil, left, right
          end
        end
      end
    end
  end
end
类树
属性存取器:左、右
def初始化左=零,右=零
@左=左
@右=右
结束
#永远不要指定任何论点,这会让我非常生气。
#观察时,将头部向侧面倾斜90度,以查看树。
def打印级别=0
@对。如果@right,则打印精美(级别+1)
将(''*level)+置于
@左。如果@left,则打印精美(级别+1)
结束
def self.generate num
树=[]
生成_子树(num){|树|树0
树
结束
私有的
def self.generate_子树数和块(&block)
如果num==0
零收益
其他的
(1..num)。每个do |根位置|
生成子树(根位置-1)左|
生成|子树(num-root |位置)do | right|
产量树。新零,左,右
结束
结束
结束
结束
结束
结束
为了实现这一点,我正试图利用lambda递归将其“压缩”为一个方法。我目前的尝试(几次迭代)如下:

def self.generate num
  trees = []

  gen = ->(num, &block) do
    if num == 0
      yield nil                                       # L61
    else
      (1..num).each do |root_position|                # L63
        gen.call(root_position - 1) do |left|         # L64
          gen.call(num - root_position) do |right|
            block.call { Tree.new nil, left, right }
          end
        end
      end
    end
  end

  gen.call(num) { |tree| trees << tree }              # L73

  trees
end
def self.generate num
树=[]
gen=->(num和block)do
如果num==0
产量为零#161
其他的
(1..num).每个do |根位置|#L63
通用呼叫(根位置-1)do |左|#L64
gen.call(num-root_位置)do | right|
block.call{Tree.new nil,left,right}
结束
结束
结束
结束
结束

gen.call(num){| tree | trees在lambda内部,
yield
关键字不起作用。另一种方法是使用
和block
,方法与您在第64行和第65行中已经使用的方法相同:

gen = ->(num, &block) do
if num == 0
  block.call(nil)
else
  # ...
end

gen.call(num) { |tree| trees << tree } 
gen=->(num,&block)do
如果num==0
阻塞呼叫(无)
其他的
# ...
结束

gen.call(num){| tree | trees感谢编辑Dave!lambdas的拼写永远不会完全正确…您应该为tree类发布一些最小的代码,以便我们可以轻松测试此函数的新版本。@DavidGrayson我已按要求发布了更多的tree类(虽然不是全部,但如果最小化有任何错误,请告诉我)。我发誓我已经改变了那个(至少在某一点上,我可能做了,但有其他一些事情组合错了)。此外,这指出了第66行我应该使用括号而不是花括号。谢谢!
gen = ->(num, &block) do
if num == 0
  block.call(nil)
else
  # ...
end

gen.call(num) { |tree| trees << tree }